mirror of
https://github.com/lxc/go-lxc.git
synced 2026-02-05 06:46:38 +01:00
introduce Rename and split Attach functions into multiple functions
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,6 +21,7 @@ examples/list
|
||||
examples/list_keys
|
||||
examples/list_snapshots
|
||||
examples/reboot
|
||||
examples/rename
|
||||
examples/restore_snapshot
|
||||
examples/shutdown
|
||||
examples/start
|
||||
|
||||
11
const.go
11
const.go
@@ -40,13 +40,14 @@ const (
|
||||
errDaemonizeFailed = "setting daemonize flag for container %q failed"
|
||||
errDestroyFailed = "destroying the container %q failed"
|
||||
errDestroySnapshotFailed = "destroying the snapshot %q failed"
|
||||
errExecuteFailed = "executing the command in a temporary container %q failed"
|
||||
errFreezeFailed = "freezing the container %q failed"
|
||||
errIPAddress = "getting IP address on the interface %s of the container %q failed"
|
||||
errIPAddresses = "getting IP addresses of the container %q failed"
|
||||
errIPv4Addresses = "getting IPv4 addresses of the container %q failed"
|
||||
errIPv6Addresses = "getting IPv6 addresses of the container %q failed"
|
||||
errInsufficientNumberOfArguments = "insufficient number of arguments were supplied"
|
||||
errInterfaces = "getting interface names for the container %q failed"
|
||||
errIPAddresses = "getting IP addresses of the container %q failed"
|
||||
errIPAddress = "getting IP address on the interface %s of the container %q failed"
|
||||
errIPv4Addresses = "getting IPv4 addresses of the container %q failed"
|
||||
errIPv6Addresses = "getting IPv6 addresses of the container %q failed"
|
||||
errLoadConfigFailed = "loading config file for the container %q failed (path: %s)"
|
||||
errMemLimit = "your kernel does not support cgroup memory controller"
|
||||
errNewFailed = "allocating the container %q failed"
|
||||
@@ -54,6 +55,7 @@ const (
|
||||
errNotFrozen = "container %q is not frozen"
|
||||
errNotRunning = "container %q is not running"
|
||||
errRebootFailed = "rebooting the container %q failed"
|
||||
errRenameFailed = "renaming the container %q failed"
|
||||
errRestoreSnapshotFailed = "restoring the container %q failed"
|
||||
errSaveConfigFailed = "saving config file for the container %q failed (path: %s)"
|
||||
errSettingCgroupItemFailed = "setting cgroup item for the container %q failed (key: %s, value: %s)"
|
||||
@@ -63,7 +65,6 @@ const (
|
||||
errSettingSwapLimitFailed = "setting swap limit for the container %q failed"
|
||||
errShutdownFailed = "shutting down the container %q failed"
|
||||
errStartFailed = "starting the container %q failed"
|
||||
errExecuteFailed = "executing the command in a temporary container %q failed"
|
||||
errStopFailed = "stopping the container %q failed"
|
||||
errSwapLimit = "your kernel does not support cgroup swap controller"
|
||||
errUnfreezeFailed = "unfreezing the container %q failed"
|
||||
|
||||
71
container.go
71
container.go
@@ -468,6 +468,24 @@ func (lxc *Container) CloneToOverlayFS(name string) error {
|
||||
return lxc.Clone(name, CloneSnapshot, OverlayFS)
|
||||
}
|
||||
|
||||
// Rename renames the container
|
||||
func (lxc *Container) Rename(name string) error {
|
||||
if err := lxc.ensureDefinedButNotRunning(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lxc.mu.Lock()
|
||||
defer lxc.mu.Unlock()
|
||||
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
|
||||
if !bool(C.lxc_container_rename(lxc.container, cname)) {
|
||||
return fmt.Errorf(errRenameFailed, C.GoString(lxc.container.name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Wait waits for container to reach a given state or timeouts
|
||||
func (lxc *Container) Wait(state State, timeout int) bool {
|
||||
lxc.mu.Lock()
|
||||
@@ -836,9 +854,8 @@ func (lxc *Container) Console(ttynum, stdinfd, stdoutfd, stderrfd, escape int) e
|
||||
return nil
|
||||
}
|
||||
|
||||
// AttachRunShell runs a shell inside the container
|
||||
func (lxc *Container) AttachRunShell() error {
|
||||
// FIXME: support lxc_attach_options_t, currently we use LXC_ATTACH_OPTIONS_DEFAULT
|
||||
// AttachShell runs a shell inside the container
|
||||
func (lxc *Container) AttachShell() error {
|
||||
if err := lxc.ensureDefinedAndRunning(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -846,16 +863,29 @@ func (lxc *Container) AttachRunShell() error {
|
||||
lxc.mu.Lock()
|
||||
defer lxc.mu.Unlock()
|
||||
|
||||
ret := int(C.lxc_container_attach(lxc.container))
|
||||
if ret < 0 {
|
||||
if int(C.lxc_container_attach(lxc.container, false)) < 0 {
|
||||
return fmt.Errorf(errAttachFailed, C.GoString(lxc.container.name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AttachRunCommand runs the user specified command inside the container and waits it to exit
|
||||
func (lxc *Container) AttachRunCommand(args ...string) error {
|
||||
// FIXME: support lxc_attach_options_t, currently we use LXC_ATTACH_OPTIONS_DEFAULT
|
||||
// AttachShellWithClearEnvironment runs a shell inside the container and clears all environment variables before attaching
|
||||
func (lxc *Container) AttachShellWithClearEnvironment() error {
|
||||
if err := lxc.ensureDefinedAndRunning(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lxc.mu.Lock()
|
||||
defer lxc.mu.Unlock()
|
||||
|
||||
if int(C.lxc_container_attach(lxc.container, true)) < 0 {
|
||||
return fmt.Errorf(errAttachFailed, C.GoString(lxc.container.name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunCommand runs the user specified command inside the container and waits it to exit
|
||||
func (lxc *Container) RunCommand(args ...string) error {
|
||||
if args == nil {
|
||||
return fmt.Errorf(errInsufficientNumberOfArguments)
|
||||
}
|
||||
@@ -870,8 +900,29 @@ func (lxc *Container) AttachRunCommand(args ...string) error {
|
||||
cargs := makeNullTerminatedArgs(args)
|
||||
defer freeNullTerminatedArgs(cargs, len(args))
|
||||
|
||||
ret := int(C.lxc_container_attach_run_wait(lxc.container, cargs))
|
||||
if ret < 0 {
|
||||
if int(C.lxc_container_attach_run_wait(lxc.container, false, cargs)) < 0 {
|
||||
return fmt.Errorf(errAttachFailed, C.GoString(lxc.container.name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunCommandWithClearEnvironment runs the user specified command inside the container and waits it to exit. It also clears all environment variables before attaching.
|
||||
func (lxc *Container) RunCommandWithClearEnvironment(args ...string) error {
|
||||
if args == nil {
|
||||
return fmt.Errorf(errInsufficientNumberOfArguments)
|
||||
}
|
||||
|
||||
if err := lxc.ensureDefinedAndRunning(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lxc.mu.Lock()
|
||||
defer lxc.mu.Unlock()
|
||||
|
||||
cargs := makeNullTerminatedArgs(args)
|
||||
defer freeNullTerminatedArgs(cargs, len(args))
|
||||
|
||||
if int(C.lxc_container_attach_run_wait(lxc.container, true, cargs)) < 0 {
|
||||
return fmt.Errorf(errAttachFailed, C.GoString(lxc.container.name))
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -32,11 +32,13 @@ import (
|
||||
var (
|
||||
lxcpath string
|
||||
name string
|
||||
clear bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&lxcpath, "lxcpath", lxc.DefaultConfigPath(), "Use specified container path")
|
||||
flag.StringVar(&name, "name", "rubik", "Name of the original container")
|
||||
flag.BoolVar(&clear, "clear", false, "Attach with clear environment")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
@@ -47,13 +49,26 @@ func main() {
|
||||
}
|
||||
defer lxc.PutContainer(c)
|
||||
|
||||
log.Printf("AttachRunShell\n")
|
||||
if err := c.AttachRunShell(); err != nil {
|
||||
log.Fatalf("ERROR: %s\n", err.Error())
|
||||
}
|
||||
if clear {
|
||||
log.Printf("AttachShellWithClearEnvironment\n")
|
||||
if err := c.AttachShellWithClearEnvironment(); err != nil {
|
||||
log.Fatalf("ERROR: %s\n", err.Error())
|
||||
}
|
||||
|
||||
log.Printf("AttachRunCommand\n")
|
||||
if err := c.AttachRunCommand("uname", "-a"); err != nil {
|
||||
log.Fatalf("ERROR: %s\n", err.Error())
|
||||
log.Printf("RunCommandWithClearEnvironment\n")
|
||||
if err := c.RunCommandWithClearEnvironment("uname", "-a"); err != nil {
|
||||
log.Fatalf("ERROR: %s\n", err.Error())
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Printf("AttachShell\n")
|
||||
if err := c.AttachShell(); err != nil {
|
||||
log.Fatalf("ERROR: %s\n", err.Error())
|
||||
}
|
||||
|
||||
log.Printf("RunCommand\n")
|
||||
if err := c.RunCommand("uname", "-a"); err != nil {
|
||||
log.Fatalf("ERROR: %s\n", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
56
examples/rename.go
Normal file
56
examples/rename.go
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* rename.go
|
||||
*
|
||||
* Copyright © 2013, S.Çağlar Onur
|
||||
*
|
||||
* Authors:
|
||||
* S.Çağlar Onur <caglar@10ur.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/caglar10ur/lxc"
|
||||
)
|
||||
|
||||
var (
|
||||
lxcpath string
|
||||
newname string
|
||||
name string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&lxcpath, "lxcpath", lxc.DefaultConfigPath(), "Use specified container path")
|
||||
flag.StringVar(&newname, "newname", "kibur", "New name of the container")
|
||||
flag.StringVar(&name, "name", "rubik", "Name of the container")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func main() {
|
||||
c, err := lxc.NewContainer(name, lxcpath)
|
||||
if err != nil {
|
||||
log.Fatalf("ERROR: %s\n", err.Error())
|
||||
}
|
||||
defer lxc.PutContainer(c)
|
||||
|
||||
log.Printf("Renaming container to %s...\n", newname)
|
||||
if err := c.Rename(newname); err != nil {
|
||||
log.Printf("ERROR: %s\n", err.Error())
|
||||
}
|
||||
}
|
||||
28
lxc.c
28
lxc.c
@@ -172,10 +172,15 @@ char** lxc_container_get_ips(struct lxc_container *c, const char *interface, con
|
||||
return c->get_ips(c, interface, family, scope);
|
||||
}
|
||||
|
||||
int lxc_container_attach(struct lxc_container *c) {
|
||||
int lxc_container_attach(struct lxc_container *c, bool clear_env) {
|
||||
int ret;
|
||||
pid_t pid;
|
||||
lxc_attach_options_t default_options = LXC_ATTACH_OPTIONS_DEFAULT;
|
||||
lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
|
||||
|
||||
attach_options.env_policy = LXC_ATTACH_KEEP_ENV;
|
||||
if (clear_env) {
|
||||
attach_options.env_policy = LXC_ATTACH_CLEAR_ENV;
|
||||
}
|
||||
|
||||
/*
|
||||
remount_sys_proc
|
||||
@@ -199,9 +204,9 @@ int lxc_container_attach(struct lxc_container *c) {
|
||||
|
||||
default_options.extra_env_vars = extra_env;
|
||||
default_options.extra_keep_env = extra_keep;
|
||||
*/
|
||||
*/
|
||||
|
||||
ret = c->attach(c, lxc_attach_run_shell, NULL, &default_options, &pid);
|
||||
ret = c->attach(c, lxc_attach_run_shell, NULL, &attach_options, &pid);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
@@ -215,11 +220,16 @@ int lxc_container_attach(struct lxc_container *c) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lxc_container_attach_run_wait(struct lxc_container *c, const char * const argv[]) {
|
||||
int lxc_container_attach_run_wait(struct lxc_container *c, bool clear_env, const char * const argv[]) {
|
||||
int ret;
|
||||
lxc_attach_options_t default_options = LXC_ATTACH_OPTIONS_DEFAULT;
|
||||
lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
|
||||
|
||||
ret = c->attach_run_wait(c, &default_options, argv[0], argv);
|
||||
attach_options.env_policy = LXC_ATTACH_KEEP_ENV;
|
||||
if (clear_env) {
|
||||
attach_options.env_policy = LXC_ATTACH_CLEAR_ENV;
|
||||
}
|
||||
|
||||
ret = c->attach_run_wait(c, &attach_options, argv[0], argv);
|
||||
if (WIFEXITED(ret) && WEXITSTATUS(ret) == 255)
|
||||
return -1;
|
||||
return ret;
|
||||
@@ -252,3 +262,7 @@ bool lxc_container_add_device_node(struct lxc_container *c, const char *src_path
|
||||
bool lxc_container_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path) {
|
||||
return c->remove_device_node(c, src_path, dest_path);
|
||||
}
|
||||
|
||||
bool lxc_container_rename(struct lxc_container *c, const char *newname) {
|
||||
return c->rename(c, newname);
|
||||
}
|
||||
|
||||
5
lxc.h
5
lxc.h
@@ -17,6 +17,7 @@ extern bool lxc_container_load_config(struct lxc_container *c, const char *alt_f
|
||||
extern bool lxc_container_may_control(struct lxc_container *c);
|
||||
extern bool lxc_container_reboot(struct lxc_container *c);
|
||||
extern bool lxc_container_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path);
|
||||
extern bool lxc_container_rename(struct lxc_container *c, const char *newname);
|
||||
extern bool lxc_container_running(struct lxc_container *c);
|
||||
extern bool lxc_container_save_config(struct lxc_container *c, const char *alt_file);
|
||||
extern bool lxc_container_set_cgroup_item(struct lxc_container *c, const char *key, const char *value);
|
||||
@@ -39,8 +40,8 @@ extern char** lxc_container_get_ips(struct lxc_container *c, const char *interfa
|
||||
extern char* lxc_container_get_keys(struct lxc_container *c, const char *key);
|
||||
extern const char* lxc_container_get_config_path(struct lxc_container *c);
|
||||
extern const char* lxc_container_state(struct lxc_container *c);
|
||||
extern int lxc_container_attach_run_wait(struct lxc_container *c, const char * const argv[]);
|
||||
extern int lxc_container_attach(struct lxc_container *c);
|
||||
extern int lxc_container_attach_run_wait(struct lxc_container *c, bool clear_env, const char * const argv[]);
|
||||
extern int lxc_container_attach(struct lxc_container *c, bool clear_env);
|
||||
extern int lxc_container_console_getfd(struct lxc_container *c, int ttynum);
|
||||
extern int lxc_container_snapshot_list(struct lxc_container *c, struct lxc_snapshot **ret);
|
||||
extern int lxc_container_snapshot(struct lxc_container *c);
|
||||
|
||||
Reference in New Issue
Block a user