Exemplo n.º 1
0
func (dr *dropletRunner) BuildDroplet(taskName, dropletName, buildpackUrl string, environment map[string]string, memoryMB, cpuWeight, diskMB int) error {
	builderConfig := buildpack_app_lifecycle.NewLifecycleBuilderConfig([]string{buildpackUrl}, true, false)

	action := models.WrapAction(&models.SerialAction{
		Actions: []*models.Action{
			models.WrapAction(&models.DownloadAction{
				From: "http://file-server.service.cf.internal:8080/v1/static/cell-helpers/cell-helpers.tgz",
				To:   "/tmp",
				User: "******",
			}),
			models.WrapAction(&models.DownloadAction{
				From: "http://file-server.service.cf.internal:8080/v1/static/buildpack_app_lifecycle/buildpack_app_lifecycle.tgz",
				To:   "/tmp",
				User: "******",
			}),
			dr.blobStore.DownloadAppBitsAction(dropletName),
			dr.blobStore.DeleteAppBitsAction(dropletName),
			models.WrapAction(&models.RunAction{
				Path: "/bin/chmod",
				Dir:  "/tmp/app",
				Args: []string{"-R", "a+X", "."},
				User: "******",
			}),
			models.WrapAction(&models.RunAction{
				Path: "/tmp/builder",
				Dir:  "/",
				Args: builderConfig.Args(),
				User: "******",
			}),
			dr.blobStore.UploadDropletAction(dropletName),
			dr.blobStore.UploadDropletMetadataAction(dropletName),
		},
	})

	environment["CF_STACK"] = DropletStack
	environment["MEMORY_LIMIT"] = fmt.Sprintf("%dM", memoryMB)

	proxyConf, err := dr.proxyConfReader.ProxyConf()
	if err != nil {
		return err
	}
	environment["http_proxy"] = proxyConf.HTTPProxy
	environment["https_proxy"] = proxyConf.HTTPSProxy
	environment["no_proxy"] = proxyConf.NoProxy

	createTaskParams := task_runner.NewCreateTaskParams(
		action,
		taskName,
		DropletRootFS,
		"lattice",
		"BUILD",
		environment,
		[]*models.SecurityGroupRule{},
		memoryMB,
		cpuWeight,
		diskMB,
	)

	return dr.taskRunner.CreateTask(createTaskParams)
}
Exemplo n.º 2
0
func (b *BlobStore) DownloadAppBitsAction(dropletName string) *models.Action {
	return models.WrapAction(&models.SerialAction{
		Actions: []*models.Action{
			models.WrapAction(&models.RunAction{
				Path: "/tmp/s3tool",
				Dir:  "/",
				Args: []string{
					"get",
					b.blobTarget.AccessKey,
					b.blobTarget.SecretKey,
					b.Bucket,
					b.blobTarget.Region,
					"/" + dropletName + "/bits.zip",
					"/tmp/bits.zip",
				},
				User: "******",
			}),
			models.WrapAction(&models.RunAction{
				Path: "/bin/mkdir",
				Args: []string{"/tmp/app"},
				User: "******",
			}),
			models.WrapAction(&models.RunAction{
				Path: "/usr/bin/unzip",
				Dir:  "/tmp/app",
				Args: []string{"-q", "/tmp/bits.zip"},
				User: "******",
			}),
		},
	})
}
Exemplo n.º 3
0
func NewValidDesiredLRP(guid string) *models.DesiredLRP {
	myRouterJSON := json.RawMessage(`{"foo":"bar"}`)
	modTag := models.NewModificationTag("epoch", 0)
	desiredLRP := &models.DesiredLRP{
		ProcessGuid:          guid,
		Domain:               "some-domain",
		RootFs:               "some:rootfs",
		Instances:            1,
		EnvironmentVariables: []*models.EnvironmentVariable{{Name: "FOO", Value: "bar"}},
		CachedDependencies: []*models.CachedDependency{
			{Name: "app bits", From: "blobstore.com/bits/app-bits", To: "/usr/local/app", CacheKey: "cache-key", LogSource: "log-source"},
			{Name: "app bits with checksum", From: "blobstore.com/bits/app-bits-checksum", To: "/usr/local/app-checksum", CacheKey: "cache-key", LogSource: "log-source", ChecksumAlgorithm: "md5", ChecksumValue: "checksum-value"},
		},
		Setup:          models.WrapAction(&models.RunAction{Path: "ls", User: "******"}),
		Action:         models.WrapAction(&models.RunAction{Path: "ls", User: "******"}),
		StartTimeoutMs: 15000,
		Monitor: models.WrapAction(models.EmitProgressFor(
			models.Timeout(models.Try(models.Parallel(models.Serial(&models.RunAction{Path: "ls", User: "******"}))),
				10*time.Second,
			),
			"start-message",
			"success-message",
			"failure-message",
		)),
		DiskMb:      512,
		MemoryMb:    1024,
		CpuWeight:   42,
		Routes:      &models.Routes{"my-router": &myRouterJSON},
		LogSource:   "some-log-source",
		LogGuid:     "some-log-guid",
		MetricsGuid: "some-metrics-guid",
		Annotation:  "some-annotation",
		Network: &models.Network{
			Properties: map[string]string{
				"some-key":       "some-value",
				"some-other-key": "some-other-value",
			},
		},
		EgressRules: []*models.SecurityGroupRule{{
			Protocol:     models.TCPProtocol,
			Destinations: []string{"1.1.1.1/32", "2.2.2.2/32"},
			PortRange:    &models.PortRange{Start: 10, End: 16000},
		}},
		ModificationTag:               &modTag,
		LegacyDownloadUser:            "******",
		TrustedSystemCertificatesPath: "/etc/somepath",
		VolumeMounts: []*models.VolumeMount{
			{
				Driver:        "my-driver",
				VolumeId:      "my-volume",
				ContainerPath: "/mnt/mypath",
				Mode:          models.BindMountMode_RO,
			},
		},
	}
	err := desiredLRP.Validate()
	Expect(err).NotTo(HaveOccurred())

	return desiredLRP
}
Exemplo n.º 4
0
func (b *BlobStore) DownloadDropletAction(dropletName string) *models.Action {
	return models.WrapAction(&models.SerialAction{
		Actions: []*models.Action{
			models.WrapAction(&models.RunAction{
				Path: "/tmp/s3tool",
				Dir:  "/",
				Args: []string{
					"get",
					b.blobTarget.AccessKey,
					b.blobTarget.SecretKey,
					b.Bucket,
					b.blobTarget.Region,
					"/" + dropletName + "/droplet.tgz",
					"/tmp/droplet.tgz",
				},
				User: "******",
			}),
			models.WrapAction(&models.RunAction{
				Path: "/bin/tar",
				Args: []string{"zxf", "/tmp/droplet.tgz"},
				Dir:  "/home/vcap",
				User: "******",
			}),
		},
	})
}
Exemplo n.º 5
0
func (dr *dropletRunner) LaunchDroplet(appName, dropletName string, startCommand string, startArgs []string, appEnvironmentParams app_runner.AppEnvironmentParams) error {
	executionMetadata, err := dr.getExecutionMetadata(path.Join(dropletName, "result.json"))
	if err != nil {
		return err
	}

	dropletAnnotation := annotation{}
	dropletAnnotation.DropletSource.DropletName = dropletName

	annotationBytes, err := json.Marshal(dropletAnnotation)
	if err != nil {
		return err
	}

	if appEnvironmentParams.EnvironmentVariables == nil {
		appEnvironmentParams.EnvironmentVariables = map[string]string{}
	}

	appEnvironmentParams.EnvironmentVariables["PWD"] = "/home/vcap"
	appEnvironmentParams.EnvironmentVariables["TMPDIR"] = "/home/vcap/tmp"
	appEnvironmentParams.WorkingDir = "/home/vcap"

	proxyConf, err := dr.proxyConfReader.ProxyConf()
	if err != nil {
		return err
	}
	appEnvironmentParams.EnvironmentVariables["http_proxy"] = proxyConf.HTTPProxy
	appEnvironmentParams.EnvironmentVariables["https_proxy"] = proxyConf.HTTPSProxy
	appEnvironmentParams.EnvironmentVariables["no_proxy"] = proxyConf.NoProxy

	appParams := app_runner.CreateAppParams{
		AppEnvironmentParams: appEnvironmentParams,

		Name:         appName,
		RootFS:       DropletRootFS,
		StartCommand: "/tmp/launcher",
		AppArgs: []string{
			"/home/vcap/app",
			strings.Join(append([]string{startCommand}, startArgs...), " "),
			executionMetadata,
		},

		Annotation: string(annotationBytes),

		Setup: models.WrapAction(&models.SerialAction{
			LogSource: appName,
			Actions: []*models.Action{
				models.WrapAction(&models.DownloadAction{
					From: "http://file-server.service.cf.internal:8080/v1/static/cell-helpers/cell-helpers.tgz",
					To:   "/tmp",
					User: "******",
				}),
				dr.blobStore.DownloadDropletAction(dropletName),
			},
		}),
	}

	return dr.appRunner.CreateApp(appParams)
}
Exemplo n.º 6
0
func createTestTask(taskGuid string) *models.Task {
	task := model_helpers.NewValidTask(taskGuid)
	task.Domain = "test-domain"
	task.TaskDefinition.RootFs = "some:rootfs"
	task.TaskDefinition.Action = models.WrapAction(&models.RunAction{User: "******", Path: "/bin/true"})
	return task
}
Exemplo n.º 7
0
func (b *BlobStore) DownloadDropletAction(dropletName string) *models.Action {
	return models.WrapAction(&models.DownloadAction{
		From: b.URL.String() + "/blobs/" + dropletName + "/droplet.tgz",
		To:   "/home/vcap",
		User: "******",
	})
}
Exemplo n.º 8
0
func (b *BlobStore) DownloadAppBitsAction(dropletName string) *models.Action {
	return models.WrapAction(&models.DownloadAction{
		From: b.URL.String() + "/blobs/" + dropletName + "/bits.zip",
		To:   "/tmp/app",
		User: "******",
	})
}
Exemplo n.º 9
0
func (b *BlobStore) DeleteAppBitsAction(dropletName string) *models.Action {
	return models.WrapAction(&models.RunAction{
		Path: "/tmp/davtool",
		Dir:  "/",
		Args: []string{"delete", b.URL.String() + "/blobs/" + dropletName + "/bits.zip"},
		User: "******",
	})
}
Exemplo n.º 10
0
func (b *BlobStore) UploadDropletMetadataAction(dropletName string) *models.Action {
	return models.WrapAction(&models.RunAction{
		Path: "/tmp/davtool",
		Dir:  "/",
		Args: []string{"put", b.URL.String() + "/blobs/" + dropletName + "/result.json", "/tmp/result.json"},
		User: "******",
	})
}
Exemplo n.º 11
0
func (b *BlobStore) UploadDropletAction(dropletName string) *models.Action {
	return models.WrapAction(&models.RunAction{
		Path:      "/tmp/davtool",
		Dir:       "/",
		Args:      []string{"put", b.URL.String() + "/blobs/" + dropletName + "-droplet.tgz", "/tmp/droplet"},
		User:      "******",
		LogSource: "DROPLET",
	})
}
Exemplo n.º 12
0
func taskCreateRequest(taskGuid, rootFS string, action models.ActionInterface, memoryMB, diskMB int) receptor.TaskCreateRequest {
	return receptor.TaskCreateRequest{
		TaskGuid: taskGuid,
		Domain:   defaultDomain,
		RootFS:   rootFS,
		MemoryMB: memoryMB,
		DiskMB:   diskMB,
		Action:   models.WrapAction(action),
	}
}
Exemplo n.º 13
0
func NewValidDesiredLRP(guid string) *models.DesiredLRP {
	myRouterJSON := json.RawMessage(`{"foo":"bar"}`)
	modTag := models.NewModificationTag("epoch", 0)
	desiredLRP := &models.DesiredLRP{
		ProcessGuid:          guid,
		Domain:               "some-domain",
		RootFs:               "some:rootfs",
		Instances:            1,
		EnvironmentVariables: []*models.EnvironmentVariable{{Name: "FOO", Value: "bar"}},
		Setup:                models.WrapAction(&models.RunAction{Path: "ls", User: "******"}),
		Action:               models.WrapAction(&models.RunAction{Path: "ls", User: "******"}),
		StartTimeout:         15,
		Monitor: models.WrapAction(models.EmitProgressFor(
			models.Timeout(models.Try(models.Parallel(models.Serial(&models.RunAction{Path: "ls", User: "******"}))),
				10*time.Second,
			),
			"start-message",
			"success-message",
			"failure-message",
		)),
		DiskMb:      512,
		MemoryMb:    1024,
		CpuWeight:   42,
		Routes:      &models.Routes{"my-router": &myRouterJSON},
		LogSource:   "some-log-source",
		LogGuid:     "some-log-guid",
		MetricsGuid: "some-metrics-guid",
		Annotation:  "some-annotation",
		EgressRules: []*models.SecurityGroupRule{{
			Protocol:     models.TCPProtocol,
			Destinations: []string{"1.1.1.1/32", "2.2.2.2/32"},
			PortRange:    &models.PortRange{Start: 10, End: 16000},
		}},
		ModificationTag: &modTag,
	}
	err := desiredLRP.Validate()
	Expect(err).NotTo(HaveOccurred())

	return desiredLRP
}
Exemplo n.º 14
0
func (b *BlobStore) DeleteAppBitsAction(dropletName string) *models.Action {
	return models.WrapAction(&models.RunAction{
		Path: "/tmp/s3tool",
		Dir:  "/",
		Args: []string{
			"delete",
			b.blobTarget.AccessKey,
			b.blobTarget.SecretKey,
			b.Bucket,
			b.blobTarget.Region,
			"/" + dropletName + "/bits.zip",
		},
		User: "******",
	})
}
Exemplo n.º 15
0
func (b *BlobStore) UploadDropletMetadataAction(dropletName string) *models.Action {
	return models.WrapAction(&models.RunAction{
		Path: "/tmp/s3tool",
		Dir:  "/",
		Args: []string{
			"put",
			b.blobTarget.AccessKey,
			b.blobTarget.SecretKey,
			b.Bucket,
			b.blobTarget.Region,
			"/" + dropletName + "/result.json",
			"/tmp/result.json",
		},
		User: "******",
	})
}
Exemplo n.º 16
0
func (b *BlobStore) UploadDropletAction(dropletName string) *models.Action {
	return models.WrapAction(&models.RunAction{
		Path: "/tmp/s3tool",
		Dir:  "/",
		Args: []string{
			"put",
			b.blobTarget.AccessKey,
			b.blobTarget.SecretKey,
			b.Bucket,
			b.blobTarget.Region,
			"/" + dropletName + "-droplet.tgz",
			"/tmp/droplet",
		},
		User:      "******",
		LogSource: "DROPLET",
	})
}
Exemplo n.º 17
0
func NewValidTaskDefinition() *models.TaskDefinition {
	return &models.TaskDefinition{
		RootFs: "docker:///docker.com/docker",
		EnvironmentVariables: []*models.EnvironmentVariable{
			{
				Name:  "FOO",
				Value: "BAR",
			},
		},
		Action: models.WrapAction(&models.RunAction{
			User:           "******",
			Path:           "echo",
			Args:           []string{"hello world"},
			ResourceLimits: &models.ResourceLimits{},
		}),
		MemoryMb:    256,
		DiskMb:      1024,
		CpuWeight:   42,
		Privileged:  true,
		LogGuid:     "123",
		LogSource:   "APP",
		MetricsGuid: "456",
		ResultFile:  "some-file.txt",
		EgressRules: []*models.SecurityGroupRule{
			{
				Protocol:     "tcp",
				Destinations: []string{"0.0.0.0/0"},
				PortRange: &models.PortRange{
					Start: 1,
					End:   1024,
				},
				Log: true,
			},
			{
				Protocol:     "udp",
				Destinations: []string{"8.8.0.0/16"},
				Ports:        []uint32{53},
			},
		},

		Annotation: `[{"anything": "you want!"}]... dude`,
	}
}
Exemplo n.º 18
0
func newLRPContainer(lrpKey models.ActualLRPKey, instanceKey models.ActualLRPInstanceKey, netInfo models.ActualLRPNetInfo) executor.Container {
	ports := []executor.PortMapping{}
	for _, portMap := range netInfo.Ports {
		ports = append(ports, executor.PortMapping{
			ContainerPort: uint16(portMap.ContainerPort),
			HostPort:      uint16(portMap.HostPort),
		})
	}

	return executor.Container{
		Guid: rep.LRPContainerGuid(lrpKey.ProcessGuid, instanceKey.InstanceGuid),
		RunInfo: executor.RunInfo{
			Action: models.WrapAction(&models.RunAction{Path: "true"}),
			Ports:  ports,
		},
		ExternalIP: netInfo.Address,
		Tags: executor.Tags{
			rep.ProcessGuidTag:  lrpKey.ProcessGuid,
			rep.InstanceGuidTag: instanceKey.InstanceGuid,
			rep.ProcessIndexTag: strconv.Itoa(int(lrpKey.Index)),
			rep.DomainTag:       lrpKey.Domain,
		},
	}
}
Exemplo n.º 19
0
			Expect(err).To(MatchError(ContainSubstring("connection refused")))
		})
	})

	Context("Droplet Actions", func() {
		var dropletURL string

		BeforeEach(func() {
			dropletURL = fmt.Sprintf("http://%s:%s@%s:%s/blobs/droplet-name", blobTargetInfo.Username, blobTargetInfo.Password, blobTargetInfo.Host, blobTargetInfo.Port)
		})

		Describe("#DownloadAppBitsAction", func() {
			It("constructs the correct Action to download app bits", func() {
				Expect(blobStore.DownloadAppBitsAction("droplet-name")).To(Equal(models.WrapAction(&models.DownloadAction{
					From: dropletURL + "/bits.zip",
					To:   "/tmp/app",
					User: "******",
				})))
			})
		})

		Describe("#DeleteAppBitsAction", func() {
			It("constructs the correct Action to delete app bits", func() {
				Expect(blobStore.DeleteAppBitsAction("droplet-name")).To(Equal(models.WrapAction(&models.RunAction{
					Path: "/tmp/davtool",
					Dir:  "/",
					Args: []string{"delete", dropletURL + "/bits.zip"},
					User: "******",
				})))
			})
		})
Exemplo n.º 20
0
				&models.CachedDependency{
					From:     "http://file-server.com/v1/static/the/docker/lifecycle/path.tgz",
					To:       "/tmp/lifecycle",
					CacheKey: "docker-lifecycle",
				},
			}

			Expect(taskDefinition.LegacyDownloadUser).To(Equal("vcap"))
			Expect(taskDefinition.CachedDependencies).To(BeEquivalentTo(expectedCacheDependencies))

			expectedAction := models.WrapAction(&models.RunAction{
				User: "******",
				Path: "/tmp/lifecycle/launcher",
				Args: append(
					[]string{"app"},
					"docker run fast",
					"{}",
				),
				Env:            taskRequest.EnvironmentVariables,
				ResourceLimits: &models.ResourceLimits{},
				LogSource:      "TASK",
			})

			Expect(taskDefinition.Action).To(BeEquivalentTo(expectedAction))
		})

		Context("when the docker path is not specified", func() {
			BeforeEach(func() {
				taskRequest.DockerPath = ""
			})

			It("returns an error", func() {
Exemplo n.º 21
0
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
}
Exemplo n.º 22
0
		logger.RegisterSink(lager.NewWriterSink(GinkgoWriter, lager.DEBUG))
		runner = new(fake_auction_runner.FakeAuctionRunner)
		responseRecorder = httptest.NewRecorder()

		handler = New(runner, logger)
	})

	Describe("Task Handler", func() {
		Context("with a valid task", func() {
			BeforeEach(func() {
				tasks := []models.Task{{
					TaskGuid: "the-task-guid",
					Domain:   "some-domain",
					RootFs:   "some:rootfs",
					Action: models.WrapAction(&models.RunAction{
						User: "******",
						Path: "ls",
					}),
				}}

				reqGen := rata.NewRequestGenerator("http://localhost", Routes)

				payload, err := json.Marshal(tasks)
				Expect(err).NotTo(HaveOccurred())

				req, err := reqGen.CreateRequest(CreateTaskAuctionsRoute, rata.Params{}, bytes.NewBuffer(payload))
				Expect(err).NotTo(HaveOccurred())

				handler.ServeHTTP(responseRecorder, req)
			})

			It("responds with 202", func() {
		fakeRawEventSource = new(fake_receptor.FakeRawEventSource)
		eventSource = receptor.NewEventSource(fakeRawEventSource)
	})

	Describe("Next", func() {
		Describe("Desired LRP events", func() {
			var desiredLRPResponse receptor.DesiredLRPResponse

			BeforeEach(func() {
				desiredLRPResponse = serialization.DesiredLRPProtoToResponse(
					&models.DesiredLRP{
						ProcessGuid: "some-guid",
						Domain:      "some-domain",
						RootFs:      "some-rootfs",
						Action: models.WrapAction(&models.RunAction{
							Path: "true",
							User: "******",
						}),
					},
				)
			})

			Context("when receiving a DesiredLRPCreatedEvent", func() {
				var expectedEvent receptor.DesiredLRPCreatedEvent

				BeforeEach(func() {
					expectedEvent = receptor.NewDesiredLRPCreatedEvent(desiredLRPResponse)
					payload, err := json.Marshal(expectedEvent)
					Expect(err).NotTo(HaveOccurred())

					fakeRawEventSource.NextReturns(
						sse.Event{
Exemplo n.º 24
0
				Expect(completedTasks[0].TaskGuid).To(Equal(task.TaskGuid))
				Expect(completedTasks[0].Failed).To(BeTrue())
			})
		})

		Describe("polling the BBS for actual LRPs to reap", func() {
			JustBeforeEach(func() {
				desiredLRP := &models.DesiredLRP{
					ProcessGuid: "process-guid",
					RootFs:      "some:rootfs",
					Domain:      "some-domain",
					Instances:   1,
					Action: models.WrapAction(&models.RunAction{
						User: "******",
						Path: "the-path",
						Args: []string{},
					}),
				}
				index := 0

				err := bbsClient.DesireLRP(desiredLRP)
				Expect(err).NotTo(HaveOccurred())

				instanceKey := models.NewActualLRPInstanceKey("some-instance-guid", cellID)
				err = bbsClient.ClaimActualLRP(desiredLRP.ProcessGuid, index, &instanceKey)
				Expect(err).NotTo(HaveOccurred())
			})

			It("eventually reaps actual LRPs with no corresponding container", func() {
				Eventually(getActualLRPGroups, 5*pollingInterval).Should(BeEmpty())
Exemplo n.º 25
0
					DiskMB:       1024,
					ExposedPorts: []uint16{2000, 4000},
					WorkingDir:   "/user/web/myappdir",
					Privileged:   true,
					User:         "******",
				},

				Name:         "americano-app",
				StartCommand: "/app-run-statement",
				RootFS:       "/runtest/runner",
				AppArgs:      []string{"app", "arg1", "--app", "arg 2"},
				Annotation:   "some annotation",

				Setup: models.WrapAction(&models.DownloadAction{
					From: "some-cell-helper-url",
					To:   "/tmp",
					User: "******",
				}),
			}
		})

		It("Upserts lattice domain so that it is always fresh, then starts the Docker App", func() {
			err := appRunner.CreateApp(createAppParams)
			Expect(err).ToNot(HaveOccurred())

			Expect(fakeReceptorClient.UpsertDomainCallCount()).To(Equal(1))
			domain, ttl := fakeReceptorClient.UpsertDomainArgsForCall(0)
			Expect(domain).To(Equal("lattice"))
			Expect(ttl).To(Equal(time.Duration(0)))

			Expect(fakeReceptorClient.CreateDesiredLRPCallCount()).To(Equal(1))
Exemplo n.º 26
0
					return
				}
				eventChannel <- event
			}
		}()

		rawMessage := json.RawMessage([]byte(`{"port":8080,"hosts":["primer-route"]}`))
		primerLRP := &models.DesiredLRP{
			ProcessGuid: "primer-guid",
			Domain:      "primer-domain",
			RootFs:      "primer:rootfs",
			Routes: &models.Routes{
				"router": &rawMessage,
			},
			Action: models.WrapAction(&models.RunAction{
				User: "******",
				Path: "true",
			}),
		}

		etcdHelper.SetRawDesiredLRP(primerLRP)

	PRIMING:
		for {
			select {
			case <-eventChannel:
				break PRIMING
			case <-time.After(50 * time.Millisecond):
				etcdHelper.SetRawDesiredLRP(primerLRP)
				Expect(err).NotTo(HaveOccurred())
			}
		}
Exemplo n.º 27
0
func (t crashTest) Test() {
	Context(t.Name, func() {
		var (
			crashErr                 error
			actualLRPKey             *models.ActualLRPKey
			instanceKey              *models.ActualLRPInstanceKey
			initialTimestamp         int64
			initialModificationIndex uint32
		)

		BeforeEach(func() {
			actualLRP := t.LRP()
			actualLRPKey = &actualLRP.ActualLRPKey
			instanceKey = &actualLRP.ActualLRPInstanceKey

			initialTimestamp = actualLRP.Since
			initialModificationIndex = actualLRP.ModificationTag.Index

			desiredLRP := models.DesiredLRP{
				ProcessGuid: actualLRPKey.ProcessGuid,
				Domain:      actualLRPKey.Domain,
				Instances:   actualLRPKey.Index + 1,
				RootFs:      "foo:bar",
				Action:      models.WrapAction(&models.RunAction{Path: "true", User: "******"}),
			}

			etcdHelper.SetRawDesiredLRP(&desiredLRP)
			etcdHelper.SetRawActualLRP(&actualLRP)
		})

		JustBeforeEach(func() {
			clock.Increment(600)
			crashErr = etcdDB.CrashActualLRP(logger, actualLRPKey, instanceKey, "crashed")
		})

		if t.Result.ReturnedErr == nil {
			It("does not return an error", func() {
				Expect(crashErr).NotTo(HaveOccurred())
			})
		} else {
			It(fmt.Sprintf("returned error should be '%s'", t.Result.ReturnedErr.Error()), func() {
				Expect(crashErr).To(Equal(t.Result.ReturnedErr))
			})
		}

		It(fmt.Sprintf("has crash count %d", t.Result.CrashCount), func() {
			actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
			Expect(err).NotTo(HaveOccurred())
			Expect(actualLRP.CrashCount).To(Equal(t.Result.CrashCount))
		})

		It(fmt.Sprintf("has crash reason %s", t.Result.CrashReason), func() {
			actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
			Expect(err).NotTo(HaveOccurred())
			Expect(actualLRP.CrashReason).To(Equal(t.Result.CrashReason))
		})

		if t.Result.ShouldUpdate {
			It("updates the Since", func() {
				actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
				Expect(err).NotTo(HaveOccurred())
				Expect(actualLRP.Since).To(Equal(clock.Now().UnixNano()))
			})

			It("updates the ModificationIndex", func() {
				actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
				Expect(err).NotTo(HaveOccurred())
				Expect(actualLRP.ModificationTag.Index).To(Equal(initialModificationIndex + 1))
			})
		} else {
			It("does not update the Since", func() {
				actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
				Expect(err).NotTo(HaveOccurred())
				Expect(actualLRP.Since).To(Equal(initialTimestamp))
			})

			It("does not update the ModificationIndex", func() {
				actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
				Expect(err).NotTo(HaveOccurred())
				Expect(actualLRP.ModificationTag.Index).To(Equal(initialModificationIndex))
			})
		}

		It(fmt.Sprintf("CAS to %s", t.Result.State), func() {
			actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
			Expect(err).NotTo(HaveOccurred())
			Expect(actualLRP.State).To(Equal(t.Result.State))
		})

		if t.Result.Auction {
			It("starts an auction", func() {
				Expect(fakeAuctioneerClient.RequestLRPAuctionsCallCount()).To(Equal(1))

				requestedAuctions := fakeAuctioneerClient.RequestLRPAuctionsArgsForCall(0)
				Expect(requestedAuctions).To(HaveLen(1))

				desiredLRP, err := etcdDB.DesiredLRPByProcessGuid(logger, actualLRPKey.ProcessGuid)
				Expect(err).NotTo(HaveOccurred())
				expectedStartRequest := auctioneer.NewLRPStartRequestFromModel(desiredLRP, int(actualLRPKey.Index))
				Expect(*requestedAuctions[0]).To(Equal(expectedStartRequest))
			})

			Context("when the desired LRP no longer exists", func() {
				BeforeEach(func() {
					etcdHelper.DeleteDesiredLRP(actualLRPKey.ProcessGuid)
				})

				It("the actual LRP is also deleted", func() {
					Expect(crashErr).NotTo(HaveOccurred())

					_, err := etcdDB.ActualLRPGroupByProcessGuidAndIndex(logger, actualLRPKey.ProcessGuid, actualLRPKey.Index)
					Expect(err).To(Equal(models.ErrResourceNotFound))
				})
			})
		} else {
			It("does not start an auction", func() {
				Expect(fakeAuctioneerClient.RequestLRPAuctionsCallCount()).To(Equal(0))
			})
		}

		Context("when crashing a different instance key", func() {
			var beforeActualGroup *models.ActualLRPGroup

			BeforeEach(func() {
				var err error
				beforeActualGroup, err = etcdDB.ActualLRPGroupByProcessGuidAndIndex(logger, actualLRPKey.ProcessGuid, actualLRPKey.Index)
				Expect(err).NotTo(HaveOccurred())
				instanceKey.InstanceGuid = "another-guid"
			})

			It("does not crash", func() {
				Expect(crashErr).To(Equal(models.ErrActualLRPCannotBeCrashed))

				afterActualGroup, err := etcdDB.ActualLRPGroupByProcessGuidAndIndex(logger, actualLRPKey.ProcessGuid, actualLRPKey.Index)
				Expect(err).NotTo(HaveOccurred())
				Expect(afterActualGroup).To(Equal(beforeActualGroup))
			})
		})
	})
}
Exemplo n.º 28
0
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
}
Exemplo n.º 29
0
		responseRecorder = httptest.NewRecorder()
		handler = auctionhandlers.NewTaskAuctionHandler(runner)
	})

	Describe("Create", func() {
		Context("when the request body is a task", func() {
			var tasks []*models.Task

			BeforeEach(func() {
				tasks = []*models.Task{{
					TaskGuid: "the-task-guid",
					Domain:   "some-domain",
					RootFs:   "some:rootfs",
					Action: models.WrapAction(&models.RunAction{
						User:           "******",
						Path:           "ls",
						ResourceLimits: &models.ResourceLimits{},
					}),
				}}

				handler.Create(responseRecorder, newTestRequest(tasks), logger)
			})

			It("responds with 202", func() {
				Expect(responseRecorder.Code).To(Equal(http.StatusAccepted))
			})

			It("responds with an empty JSON body", func() {
				Expect(responseRecorder.Body.String()).To(Equal("{}"))
			})
Exemplo n.º 30
0
	BeforeEach(func() {
		fakeRawEventSource = new(eventfakes.FakeRawEventSource)
		eventSource = events.NewEventSource(fakeRawEventSource)
	})

	Describe("Next", func() {
		Describe("Desired LRP events", func() {
			var desiredLRP *models.DesiredLRP

			BeforeEach(func() {
				desiredLRP = &models.DesiredLRP{
					ProcessGuid: "some-guid",
					Domain:      "some-domain",
					RootFs:      "some-rootfs",
					Action: models.WrapAction(&models.RunAction{
						Path: "true",
						User: "******",
					}),
				}
			})

			Context("when receiving a DesiredLRPCreatedEvent", func() {
				var expectedEvent *models.DesiredLRPCreatedEvent

				BeforeEach(func() {
					expectedEvent = models.NewDesiredLRPCreatedEvent(desiredLRP)
					payload, err := proto.Marshal(expectedEvent)
					Expect(err).NotTo(HaveOccurred())
					payload = []byte(base64.StdEncoding.EncodeToString(payload))

					fakeRawEventSource.NextReturns(
						sse.Event{