func (m *UpdateServiceSnapshotByContainer) Process() error { _, imageName := m.info.GetName() cached, err := utils.IsImageCached(imageName) if err != nil { fmt.Println(err) return err } if !cached { //TODO: remove this image to save server disk err := utils.PullImage(imageName) if err != nil { return err } } var config container.Config config.Image = imageName config.Cmd = []string{snapshotProcess, m.info.CallbackID, m.info.Host, m.info.DataProto} var hostConfig container.HostConfig hostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf("%s:%s", m.info.DataURL, snapshotMountDir)) containerName := "scan-" + m.info.CallbackID err = utils.StartContainer(config, hostConfig, containerName) return err }
// SetConfigOptions is a place to add necessary container configuration // values that were not explicitly supplied by the user func setCreateConfigOptions(config, imageConfig *containertypes.Config) { // Overwrite or append the image's config from the CLI with the metadata from the image's // layer metadata where appropriate if len(config.Cmd) == 0 { config.Cmd = imageConfig.Cmd } if config.WorkingDir == "" { config.WorkingDir = imageConfig.WorkingDir } if len(config.Entrypoint) == 0 { config.Entrypoint = imageConfig.Entrypoint } if config.Volumes == nil { config.Volumes = imageConfig.Volumes } else { for k, v := range imageConfig.Volumes { //NOTE: the value of the map is an empty struct. // we also do not care about duplicates. // This Volumes map is really a Set. config.Volumes[k] = v } } // set up environment setEnvFromImageConfig(config, imageConfig) }
func TestUtilsContainer(t *testing.T) { //TODO: dockyard dev team should provide small testing containers. imageName := "google/nodejs" containerName := "" cached, err := utils.IsImageCached(imageName) if err == utils.ErrorsNoDockerClient { fmt.Println("Please start a docker daemon to continue the container operation test") return } assert.Nil(t, err, "Fail to load Image") if !cached { err := utils.PullImage(imageName) assert.Nil(t, err, "Fail to pull image") } tmpFile, err := ioutil.TempFile("/tmp", "dockyard-test-container-oper") assert.Nil(t, err, "System err, fail to create temp file") defer os.Remove(tmpFile.Name()) var config container.Config config.Image = imageName config.Cmd = []string{"touch", tmpFile.Name()} var hostConfig container.HostConfig hostConfig.Binds = append(hostConfig.Binds, "/tmp:/tmp") utils.StartContainer(config, hostConfig, containerName) //TODO: stop, remove the container process assert.Equal(t, true, utils.IsFileExist(tmpFile.Name()), "Fail to touch file by using StartContainer") }
// merge merges two Config, the image container configuration (defaults values), // and the user container configuration, either passed by the API or generated // by the cli. // It will mutate the specified user configuration (userConf) with the image // configuration where the user configuration is incomplete. func merge(userConf, imageConf *containertypes.Config) error { if userConf.User == "" { userConf.User = imageConf.User } if len(userConf.ExposedPorts) == 0 { userConf.ExposedPorts = imageConf.ExposedPorts } else if imageConf.ExposedPorts != nil { if userConf.ExposedPorts == nil { userConf.ExposedPorts = make(nat.PortSet) } for port := range imageConf.ExposedPorts { if _, exists := userConf.ExposedPorts[port]; !exists { userConf.ExposedPorts[port] = struct{}{} } } } if len(userConf.Env) == 0 { userConf.Env = imageConf.Env } else { for _, imageEnv := range imageConf.Env { found := false imageEnvKey := strings.Split(imageEnv, "=")[0] for _, userEnv := range userConf.Env { userEnvKey := strings.Split(userEnv, "=")[0] if imageEnvKey == userEnvKey { found = true break } } if !found { userConf.Env = append(userConf.Env, imageEnv) } } } if userConf.Labels == nil { userConf.Labels = map[string]string{} } if imageConf.Labels != nil { for l := range userConf.Labels { imageConf.Labels[l] = userConf.Labels[l] } userConf.Labels = imageConf.Labels } if userConf.Entrypoint.Len() == 0 { if userConf.Cmd.Len() == 0 { userConf.Cmd = imageConf.Cmd } if userConf.Entrypoint == nil { userConf.Entrypoint = imageConf.Entrypoint } } if userConf.WorkingDir == "" { userConf.WorkingDir = imageConf.WorkingDir } if len(userConf.Volumes) == 0 { userConf.Volumes = imageConf.Volumes } else { for k, v := range imageConf.Volumes { userConf.Volumes[k] = v } } return nil }
// merge merges two Config, the image container configuration (defaults values), // and the user container configuration, either passed by the API or generated // by the cli. // It will mutate the specified user configuration (userConf) with the image // configuration where the user configuration is incomplete. func merge(userConf, imageConf *containertypes.Config) error { if userConf.User == "" { userConf.User = imageConf.User } if len(userConf.ExposedPorts) == 0 { userConf.ExposedPorts = imageConf.ExposedPorts } else if imageConf.ExposedPorts != nil { if userConf.ExposedPorts == nil { userConf.ExposedPorts = make(nat.PortSet) } for port := range imageConf.ExposedPorts { if _, exists := userConf.ExposedPorts[port]; !exists { userConf.ExposedPorts[port] = struct{}{} } } } if len(userConf.Env) == 0 { userConf.Env = imageConf.Env } else { for _, imageEnv := range imageConf.Env { found := false imageEnvKey := strings.Split(imageEnv, "=")[0] for _, userEnv := range userConf.Env { userEnvKey := strings.Split(userEnv, "=")[0] if imageEnvKey == userEnvKey { found = true break } } if !found { userConf.Env = append(userConf.Env, imageEnv) } } } if userConf.Labels == nil { userConf.Labels = map[string]string{} } if imageConf.Labels != nil { for l := range userConf.Labels { imageConf.Labels[l] = userConf.Labels[l] } userConf.Labels = imageConf.Labels } if len(userConf.Entrypoint) == 0 { if len(userConf.Cmd) == 0 { userConf.Cmd = imageConf.Cmd userConf.ArgsEscaped = imageConf.ArgsEscaped } if userConf.Entrypoint == nil { userConf.Entrypoint = imageConf.Entrypoint } } if imageConf.Healthcheck != nil { if userConf.Healthcheck == nil { userConf.Healthcheck = imageConf.Healthcheck } else { if len(userConf.Healthcheck.Test) == 0 { userConf.Healthcheck.Test = imageConf.Healthcheck.Test } if userConf.Healthcheck.Interval == 0 { userConf.Healthcheck.Interval = imageConf.Healthcheck.Interval } if userConf.Healthcheck.Timeout == 0 { userConf.Healthcheck.Timeout = imageConf.Healthcheck.Timeout } if userConf.Healthcheck.Retries == 0 { userConf.Healthcheck.Retries = imageConf.Healthcheck.Retries } } } if userConf.WorkingDir == "" { userConf.WorkingDir = imageConf.WorkingDir } if len(userConf.Volumes) == 0 { userConf.Volumes = imageConf.Volumes } else { for k, v := range imageConf.Volumes { userConf.Volumes[k] = v } } if userConf.StopSignal == "" { userConf.StopSignal = imageConf.StopSignal } return nil }