func (backend *dockerBackend) BuildRecipe(stagingGuid string, request cc_messages.StagingRequestFromCC) (*models.TaskDefinition, string, string, error) { logger := backend.logger.Session("build-recipe", lager.Data{"app-id": request.AppId, "staging-guid": stagingGuid}) logger.Info("staging-request") var lifecycleData cc_messages.DockerStagingData err := json.Unmarshal(*request.LifecycleData, &lifecycleData) if err != nil { return &models.TaskDefinition{}, "", "", err } err = backend.validateRequest(request, lifecycleData) if err != nil { return &models.TaskDefinition{}, "", "", err } compilerURL, err := backend.compilerDownloadURL() if err != nil { return &models.TaskDefinition{}, "", "", err } cachedDependencies := []*models.CachedDependency{ &models.CachedDependency{ From: compilerURL.String(), To: path.Dir(DockerBuilderExecutablePath), CacheKey: "docker-lifecycle", }, } runActionArguments := []string{ "-outputMetadataJSONFilename", DockerBuilderOutputPath, "-dockerRef", lifecycleData.DockerImageUrl, } if len(backend.config.InsecureDockerRegistries) > 0 { insecureDockerRegistries := strings.Join(backend.config.InsecureDockerRegistries, ",") runActionArguments = append(runActionArguments, "-insecureDockerRegistries", insecureDockerRegistries) } fileDescriptorLimit := uint64(request.FileDescriptors) runAs := "vcap" actions := []models.ActionInterface{} if cacheDockerImage(request.Environment) { runAs = "root" additionalEgressRules, additionalArgs, err := cachingEgressRulesAndArgs( logger, backend.config.DockerRegistryAddress, backend.config.ConsulCluster, lifecycleData, ) if err != nil { return &models.TaskDefinition{}, "", "", err } runActionArguments = append(runActionArguments, additionalArgs...) request.EgressRules = append(request.EgressRules, additionalEgressRules...) actions = append( actions, models.EmitProgressFor( &models.RunAction{ Path: MountCgroupsPath, ResourceLimits: &models.ResourceLimits{ Nofile: &fileDescriptorLimit, }, User: runAs, }, "Preparing docker daemon...", "", "Failed to set up docker environment", ), ) } actions = append( actions, models.EmitProgressFor( &models.RunAction{ Path: DockerBuilderExecutablePath, Args: runActionArguments, Env: request.Environment, ResourceLimits: &models.ResourceLimits{ Nofile: &fileDescriptorLimit, }, User: runAs, }, "Staging...", "Staging Complete", "Staging Failed", ), ) annotationJson, _ := json.Marshal(cc_messages.StagingTaskAnnotation{ Lifecycle: DockerLifecycleName, CompletionCallback: request.CompletionCallback, }) taskDefinition := &models.TaskDefinition{ RootFs: models.PreloadedRootFS(backend.config.DockerStagingStack), ResultFile: DockerBuilderOutputPath, Privileged: true, MemoryMb: int32(request.MemoryMB), LogSource: TaskLogSource, LogGuid: request.LogGuid, EgressRules: request.EgressRules, DiskMb: int32(request.DiskMB), CompletionCallbackUrl: backend.config.CallbackURL(stagingGuid), Annotation: string(annotationJson), Action: models.WrapAction(models.Timeout(models.Serial(actions...), dockerTimeout(request, backend.logger))), CachedDependencies: cachedDependencies, LegacyDownloadUser: "******", TrustedSystemCertificatesPath: TrustedSystemCertificatesPath, } logger.Debug("staging-task-request") return taskDefinition, stagingGuid, backend.config.TaskDomain, nil }
func (backend *dockerBackend) BuildRecipe(stagingGuid string, request cc_messages.StagingRequestFromCC) (*models.TaskDefinition, string, string, error) { logger := backend.logger.Session("build-recipe", lager.Data{"app-id": request.AppId, "staging-guid": stagingGuid}) logger.Info("staging-request") var lifecycleData cc_messages.DockerStagingData err := json.Unmarshal(*request.LifecycleData, &lifecycleData) if err != nil { return &models.TaskDefinition{}, "", "", err } err = backend.validateRequest(request, lifecycleData) if err != nil { return &models.TaskDefinition{}, "", "", err } compilerURL, err := backend.compilerDownloadURL() if err != nil { return &models.TaskDefinition{}, "", "", err } cacheDockerImage := false for _, envVar := range request.Environment { if envVar.Name == "DIEGO_DOCKER_CACHE" && envVar.Value == "true" { cacheDockerImage = true break } } actions := []models.ActionInterface{} //Download builder actions = append( actions, models.EmitProgressFor( &models.DownloadAction{ From: compilerURL.String(), To: path.Dir(DockerBuilderExecutablePath), CacheKey: "docker-lifecycle", User: "******", }, "", "", "Failed to set up docker environment", ), ) runActionArguments := []string{"-outputMetadataJSONFilename", DockerBuilderOutputPath, "-dockerRef", lifecycleData.DockerImageUrl} runAs := "vcap" if cacheDockerImage { runAs = "root" host, port, err := net.SplitHostPort(backend.config.DockerRegistryAddress) if err != nil { logger.Debug("invalid docker registry address", lager.Data{"address": backend.config.DockerRegistryAddress, "error": err.Error()}) return &models.TaskDefinition{}, "", "", ErrInvalidDockerRegistryAddress } registryServices, err := getDockerRegistryServices(backend.config.ConsulCluster, backend.logger) if err != nil { return &models.TaskDefinition{}, "", "", err } registryRules := addDockerRegistryRules(request.EgressRules, registryServices) request.EgressRules = append(request.EgressRules, registryRules...) registryIPs := strings.Join(buildDockerRegistryAddresses(registryServices), ",") runActionArguments, err = addDockerCachingArguments(runActionArguments, registryIPs, backend.config.InsecureDockerRegistry, host, port, lifecycleData) if err != nil { return &models.TaskDefinition{}, "", "", err } } fileDescriptorLimit := uint64(request.FileDescriptors) // Run builder actions = append( actions, models.EmitProgressFor( &models.RunAction{ Path: DockerBuilderExecutablePath, Args: runActionArguments, Env: request.Environment, ResourceLimits: &models.ResourceLimits{ Nofile: &fileDescriptorLimit, }, User: runAs, }, "Staging...", "Staging Complete", "Staging Failed", ), ) annotationJson, _ := json.Marshal(cc_messages.StagingTaskAnnotation{ Lifecycle: DockerLifecycleName, }) taskDefinition := &models.TaskDefinition{ RootFs: models.PreloadedRootFS(backend.config.DockerStagingStack), ResultFile: DockerBuilderOutputPath, Privileged: true, MemoryMb: int32(request.MemoryMB), LogSource: TaskLogSource, LogGuid: request.LogGuid, EgressRules: request.EgressRules, DiskMb: int32(request.DiskMB), CompletionCallbackUrl: backend.config.CallbackURL(stagingGuid), Annotation: string(annotationJson), Action: models.WrapAction(models.Timeout(models.Serial(actions...), dockerTimeout(request, backend.logger))), } logger.Debug("staging-task-request") return taskDefinition, stagingGuid, backend.config.TaskDomain, nil }