func parseKeyValueOpts(opts opts.ListOpts) ([]utils.KeyValuePair, error) {
	out := make([]utils.KeyValuePair, opts.Len())
	for i, o := range opts.GetAll() {
		k, v, err := utils.ParseKeyValueOpt(o)
		if err != nil {
			return nil, err
		}
		out[i] = utils.KeyValuePair{Key: k, Value: v}
	}
	return out, nil
}
func TestParseLxcConfOpt(t *testing.T) {
	opts := []string{"lxc.utsname=docker", "lxc.utsname = docker "}

	for _, o := range opts {
		k, v, err := utils.ParseKeyValueOpt(o)
		if err != nil {
			t.FailNow()
		}
		if k != "lxc.utsname" {
			t.Fail()
		}
		if v != "docker" {
			t.Fail()
		}
	}
}
func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error) {
	SetDevDir("/dev")

	devices := &DeviceSet{
		root:                 root,
		MetaData:             MetaData{Devices: make(map[string]*DevInfo)},
		dataLoopbackSize:     DefaultDataLoopbackSize,
		metaDataLoopbackSize: DefaultMetaDataLoopbackSize,
		baseFsSize:           DefaultBaseFsSize,
		filesystem:           "ext4",
		doBlkDiscard:         true,
	}

	foundBlkDiscard := false
	for _, option := range options {
		key, val, err := utils.ParseKeyValueOpt(option)
		if err != nil {
			return nil, err
		}
		key = strings.ToLower(key)
		switch key {
		case "dm.basesize":
			size, err := units.FromHumanSize(val)
			if err != nil {
				return nil, err
			}
			devices.baseFsSize = uint64(size)
		case "dm.loopdatasize":
			size, err := units.FromHumanSize(val)
			if err != nil {
				return nil, err
			}
			devices.dataLoopbackSize = size
		case "dm.loopmetadatasize":
			size, err := units.FromHumanSize(val)
			if err != nil {
				return nil, err
			}
			devices.metaDataLoopbackSize = size
		case "dm.fs":
			if val != "ext4" && val != "xfs" {
				return nil, fmt.Errorf("Unsupported filesystem %s\n", val)
			}
			devices.filesystem = val
		case "dm.mkfsarg":
			devices.mkfsArgs = append(devices.mkfsArgs, val)
		case "dm.mountopt":
			devices.mountOptions = joinMountOptions(devices.mountOptions, val)
		case "dm.metadatadev":
			devices.metadataDevice = val
		case "dm.datadev":
			devices.dataDevice = val
		case "dm.blkdiscard":
			foundBlkDiscard = true
			devices.doBlkDiscard, err = strconv.ParseBool(val)
			if err != nil {
				return nil, err
			}
		default:
			return nil, fmt.Errorf("Unknown option %s\n", key)
		}
	}

	// By default, don't do blk discard hack on raw devices, its rarely useful and is expensive
	if !foundBlkDiscard && devices.dataDevice != "" {
		devices.doBlkDiscard = false
	}

	if err := devices.initDevmapper(doInit); err != nil {
		return nil, err
	}

	return devices, nil
}
Exemple #4
0
// createContainer populates and configures the container type with the
// data provided by the execdriver.Command
func createContainer(c *execdriver.Command) *libcontainer.Container {
	container := getDefaultTemplate()

	container.Hostname = getEnv("HOSTNAME", c.Env)
	container.Tty = c.Tty
	container.User = c.User
	container.WorkingDir = c.WorkingDir
	container.Env = c.Env
	container.Context["mount_label"] = c.Context["mount_label"]
	container.Context["process_label"] = c.Context["process_label"]

	loopbackNetwork := libcontainer.Network{
		Mtu:     c.Network.Mtu,
		Address: fmt.Sprintf("%s/%d", "127.0.0.1", 0),
		Gateway: "localhost",
		Type:    "loopback",
		Context: libcontainer.Context{},
	}

	container.Networks = []*libcontainer.Network{
		&loopbackNetwork,
	}

	if c.Network.Interface != nil {
		vethNetwork := libcontainer.Network{
			Mtu:     c.Network.Mtu,
			Address: fmt.Sprintf("%s/%d", c.Network.Interface.IPAddress, c.Network.Interface.IPPrefixLen),
			Gateway: c.Network.Interface.Gateway,
			Type:    "veth",
			Context: libcontainer.Context{
				"prefix": "veth",
				"bridge": c.Network.Interface.Bridge,
			},
		}
		container.Networks = append(container.Networks, &vethNetwork)
	}

	container.Cgroups.Name = c.ID
	if c.Privileged {
		container.CapabilitiesMask = nil
		container.Cgroups.DeviceAccess = true
		container.Context["apparmor_profile"] = "unconfined"
	}
	if c.Resources != nil {
		container.Cgroups.CpuShares = c.Resources.CpuShares
		container.Cgroups.Memory = c.Resources.Memory
		container.Cgroups.MemorySwap = c.Resources.MemorySwap
	}

	if opts, ok := c.Config["unit"]; ok {
		props := [][2]string{}
		for _, opt := range opts {
			key, value, err := utils.ParseKeyValueOpt(opt)
			if err == nil {
				props = append(props, [2]string{key, value})
			} else {
				props = append(props, [2]string{opt, ""})
			}
		}
		container.Cgroups.UnitProperties = props
	}

	// check to see if we are running in ramdisk to disable pivot root
	container.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""

	for _, m := range c.Mounts {
		container.Mounts = append(container.Mounts, libcontainer.Mount{m.Source, m.Destination, m.Writable, m.Private})
	}

	return container
}