// TestContainerCreateEmptyImageCache() attempts a ContainerCreate() with an empty image // cache func TestContainerCreateEmptyImageCache(t *testing.T) { mockContainerProxy := NewMockContainerProxy() // Create our personality Container backend cb := &Container{ containerProxy: mockContainerProxy, } // mock a container create config var config types.ContainerCreateConfig config.HostConfig = &container.HostConfig{} config.Config = &container.Config{} config.NetworkingConfig = &dnetwork.NetworkingConfig{} config.Config.Image = "busybox" _, err := cb.ContainerCreate(config) assert.Contains(t, err.Error(), "No such image", "Error (%s) should have 'No such image' for an empty image cache", err.Error()) }
// TestContainerAddVolumes() assumes container handle create succeeded and cycles through all // possible input/outputs for committing the handle and calls vicbackends.ContainerCreate() func TestCommitHandle(t *testing.T) { mockContainerProxy := NewMockContainerProxy() // Create our personality Container backend cb := &Container{ containerProxy: mockContainerProxy, } AddMockImageToCache() // mock a container create config var config types.ContainerCreateConfig config.HostConfig = &container.HostConfig{} config.Config = &container.Config{} config.NetworkingConfig = &dnetwork.NetworkingConfig{} mockCommitHandleData := MockCommitData() // Iterate over create handler responses and see what the composite ContainerCreate() // returns. Since the handle is the first operation, we expect to receive a create handle // error. _, _, _, count := mockContainerProxy.GetMockDataCount() for i := 0; i < count; i++ { if i == SUCCESS { //skip success case continue } mockContainerProxy.SetMockDataResponse(0, 0, 0, i) config.Config.Image = mockCommitHandleData[i].createInputID _, err := cb.ContainerCreate(config) assert.Contains(t, err.Error(), mockCommitHandleData[i].createErrSubstr) } }
// validateCreateConfig() checks the parameters for ContainerCreate(). // It may "fix up" the config param passed into ConntainerCreate() if needed. func validateCreateConfig(config *types.ContainerCreateConfig) error { defer trace.End(trace.Begin("Container.validateCreateConfig")) // process cpucount here var cpuCount int64 = DefaultCPUs // support windows client if config.HostConfig.CPUCount > 0 { cpuCount = config.HostConfig.CPUCount } else { // we hijack --cpuset-cpus in the non-windows case if config.HostConfig.CpusetCpus != "" { cpus := strings.Split(config.HostConfig.CpusetCpus, ",") if c, err := strconv.Atoi(cpus[0]); err == nil { cpuCount = int64(c) } else { return fmt.Errorf("Error parsing CPU count: %s", err) } } } config.HostConfig.CPUCount = cpuCount // fix-up cpu/memory settings here if cpuCount < MinCPUs { config.HostConfig.CPUCount = MinCPUs } log.Infof("Container CPU count: %d", config.HostConfig.CPUCount) // convert from bytes to MiB for vsphere memoryMB := config.HostConfig.Memory / units.MiB if memoryMB == 0 { memoryMB = MemoryDefaultMB } else if memoryMB < MemoryMinMB { memoryMB = MemoryMinMB } // check that memory is aligned if remainder := memoryMB % MemoryAlignMB; remainder != 0 { log.Warnf("Default container VM memory must be %d aligned for hotadd, rounding up.", MemoryAlignMB) memoryMB += MemoryAlignMB - remainder } config.HostConfig.Memory = memoryMB log.Infof("Container memory: %d MB", config.HostConfig.Memory) if config.NetworkingConfig == nil { config.NetworkingConfig = &dnetwork.NetworkingConfig{} } if config.HostConfig == nil || config.Config == nil { return BadRequestError("invalid config") } // validate port bindings if config.HostConfig != nil { var ips []string if addrs, err := externalIPv4Addrs(); err != nil { log.Warnf("could not get address for external interface: %s", err) } else { ips = make([]string, len(addrs)) for i := range addrs { ips[i] = addrs[i].IP.String() } } for _, pbs := range config.HostConfig.PortBindings { for _, pb := range pbs { if pb.HostIP != "" && pb.HostIP != "0.0.0.0" { // check if specified host ip equals any of the addresses on the "client" interface found := false for _, i := range ips { if i == pb.HostIP { found = true break } } if !found { return InternalServerError("host IP for port bindings is only supported for 0.0.0.0 and the external interface IP address") } } start, end, _ := nat.ParsePortRangeToInt(pb.HostPort) if start != end { return InternalServerError("host port ranges are not supported for port bindings") } } } } // TODO(jzt): users other than root are not currently supported // We should check for USER in config.Config.Env once we support Dockerfiles. if config.Config.User != "" && config.Config.User != "root" { return InternalServerError("Failed to create container - users other than root are not currently supported") } // https://github.com/vmware/vic/issues/1378 if len(config.Config.Entrypoint) == 0 && len(config.Config.Cmd) == 0 { return derr.NewRequestNotFoundError(fmt.Errorf("No command specified")) } // Was a name provided - if not create a friendly name if config.Name == "" { //TODO: Assume we could have a name collison here : need to // provide validation / retry CDG June 9th 2016 config.Name = namesgenerator.GetRandomName(0) } return nil }