summaryrefslogtreecommitdiff
path: root/runtime/execdriver/lxc/init.go
diff options
context:
space:
mode:
authorunclejack <unclejack@users.noreply.github.com>2014-04-09 01:56:01 +0300
committerunclejack <unclejack@users.noreply.github.com>2014-04-09 01:56:01 +0300
commite128a606e39fa63c6b4fd6e53a1d88cf00aad868 (patch)
tree199ee7eb6678ffecd2ddad95fce794c795ad5183 /runtime/execdriver/lxc/init.go
parent143c9707a9fafc39e1d9747f528db97b2564f01e (diff)
parentdc9c28f51d669d6b09e81c2381f800f1a33bb659 (diff)
downloaddocker-release-0.10.tar.gz
Merge pull request #5079 from unclejack/bump_v0.10.0release-0.100.10.1-hotfixes
Bump version to v0.10.0
Diffstat (limited to 'runtime/execdriver/lxc/init.go')
-rw-r--r--runtime/execdriver/lxc/init.go175
1 files changed, 175 insertions, 0 deletions
diff --git a/runtime/execdriver/lxc/init.go b/runtime/execdriver/lxc/init.go
new file mode 100644
index 0000000000..c1933a5e43
--- /dev/null
+++ b/runtime/execdriver/lxc/init.go
@@ -0,0 +1,175 @@
+package lxc
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/dotcloud/docker/pkg/netlink"
+ "github.com/dotcloud/docker/pkg/user"
+ "github.com/dotcloud/docker/runtime/execdriver"
+ "github.com/syndtr/gocapability/capability"
+ "io/ioutil"
+ "net"
+ "os"
+ "strings"
+ "syscall"
+)
+
+// Clear environment pollution introduced by lxc-start
+func setupEnv(args *execdriver.InitArgs) error {
+ // Get env
+ var env []string
+ content, err := ioutil.ReadFile(".dockerenv")
+ if err != nil {
+ return fmt.Errorf("Unable to load environment variables: %v", err)
+ }
+ if err := json.Unmarshal(content, &env); err != nil {
+ return fmt.Errorf("Unable to unmarshal environment variables: %v", err)
+ }
+ // Propagate the plugin-specific container env variable
+ env = append(env, "container="+os.Getenv("container"))
+
+ args.Env = env
+
+ os.Clearenv()
+ for _, kv := range args.Env {
+ parts := strings.SplitN(kv, "=", 2)
+ if len(parts) == 1 {
+ parts = append(parts, "")
+ }
+ os.Setenv(parts[0], parts[1])
+ }
+
+ return nil
+}
+
+func setupHostname(args *execdriver.InitArgs) error {
+ hostname := getEnv(args, "HOSTNAME")
+ if hostname == "" {
+ return nil
+ }
+ return setHostname(hostname)
+}
+
+// Setup networking
+func setupNetworking(args *execdriver.InitArgs) error {
+ if args.Ip != "" {
+ // eth0
+ iface, err := net.InterfaceByName("eth0")
+ if err != nil {
+ return fmt.Errorf("Unable to set up networking: %v", err)
+ }
+ ip, ipNet, err := net.ParseCIDR(args.Ip)
+ if err != nil {
+ return fmt.Errorf("Unable to set up networking: %v", err)
+ }
+ if err := netlink.NetworkLinkAddIp(iface, ip, ipNet); err != nil {
+ return fmt.Errorf("Unable to set up networking: %v", err)
+ }
+ if err := netlink.NetworkSetMTU(iface, args.Mtu); err != nil {
+ return fmt.Errorf("Unable to set MTU: %v", err)
+ }
+ if err := netlink.NetworkLinkUp(iface); err != nil {
+ return fmt.Errorf("Unable to set up networking: %v", err)
+ }
+
+ // loopback
+ iface, err = net.InterfaceByName("lo")
+ if err != nil {
+ return fmt.Errorf("Unable to set up networking: %v", err)
+ }
+ if err := netlink.NetworkLinkUp(iface); err != nil {
+ return fmt.Errorf("Unable to set up networking: %v", err)
+ }
+ }
+ if args.Gateway != "" {
+ gw := net.ParseIP(args.Gateway)
+ if gw == nil {
+ return fmt.Errorf("Unable to set up networking, %s is not a valid gateway IP", args.Gateway)
+ }
+
+ if err := netlink.AddDefaultGw(gw); err != nil {
+ return fmt.Errorf("Unable to set up networking: %v", err)
+ }
+ }
+
+ return nil
+}
+
+// Setup working directory
+func setupWorkingDirectory(args *execdriver.InitArgs) error {
+ if args.WorkDir == "" {
+ return nil
+ }
+ if err := syscall.Chdir(args.WorkDir); err != nil {
+ return fmt.Errorf("Unable to change dir to %v: %v", args.WorkDir, err)
+ }
+ return nil
+}
+
+// Takes care of dropping privileges to the desired user
+func changeUser(args *execdriver.InitArgs) error {
+ uid, gid, suppGids, err := user.GetUserGroupSupplementary(
+ args.User,
+ syscall.Getuid(), syscall.Getgid(),
+ )
+ if err != nil {
+ return err
+ }
+
+ if err := syscall.Setgroups(suppGids); err != nil {
+ return fmt.Errorf("Setgroups failed: %v", err)
+ }
+ if err := syscall.Setgid(gid); err != nil {
+ return fmt.Errorf("Setgid failed: %v", err)
+ }
+ if err := syscall.Setuid(uid); err != nil {
+ return fmt.Errorf("Setuid failed: %v", err)
+ }
+
+ return nil
+}
+
+func setupCapabilities(args *execdriver.InitArgs) error {
+ if args.Privileged {
+ return nil
+ }
+
+ drop := []capability.Cap{
+ capability.CAP_SETPCAP,
+ capability.CAP_SYS_MODULE,
+ capability.CAP_SYS_RAWIO,
+ capability.CAP_SYS_PACCT,
+ capability.CAP_SYS_ADMIN,
+ capability.CAP_SYS_NICE,
+ capability.CAP_SYS_RESOURCE,
+ capability.CAP_SYS_TIME,
+ capability.CAP_SYS_TTY_CONFIG,
+ capability.CAP_AUDIT_WRITE,
+ capability.CAP_AUDIT_CONTROL,
+ capability.CAP_MAC_OVERRIDE,
+ capability.CAP_MAC_ADMIN,
+ capability.CAP_NET_ADMIN,
+ }
+
+ c, err := capability.NewPid(os.Getpid())
+ if err != nil {
+ return err
+ }
+
+ c.Unset(capability.CAPS|capability.BOUNDS, drop...)
+
+ if err := c.Apply(capability.CAPS | capability.BOUNDS); err != nil {
+ return err
+ }
+ return nil
+}
+
+func getEnv(args *execdriver.InitArgs, key string) string {
+ for _, kv := range args.Env {
+ parts := strings.SplitN(kv, "=", 2)
+ if parts[0] == key && len(parts) == 2 {
+ return parts[1]
+ }
+ }
+ return ""
+}