1
0
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:
S.Çağlar Onur
2013-12-18 21:15:42 -05:00
parent 7a9b9ce505
commit d56f42939f
7 changed files with 170 additions and 31 deletions

1
.gitignore vendored
View File

@@ -21,6 +21,7 @@ examples/list
examples/list_keys
examples/list_snapshots
examples/reboot
examples/rename
examples/restore_snapshot
examples/shutdown
examples/start

View File

@@ -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"

View File

@@ -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

View File

@@ -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
View 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
View File

@@ -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
View File

@@ -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);