本文整理匯總了Golang中github.com/flynn/flynn/controller/client.CreateArtifact函數的典型用法代碼示例。如果您正苦於以下問題:Golang CreateArtifact函數的具體用法?Golang CreateArtifact怎麽用?Golang CreateArtifact使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了CreateArtifact函數的14個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: createApp
func (h *Helper) createApp(t *c.C) (*ct.App, *ct.Release) {
client := h.controllerClient(t)
app := &ct.App{}
t.Assert(client.CreateApp(app), c.IsNil)
debugf(t, "created app %s (%s)", app.Name, app.ID)
artifact := &ct.Artifact{Type: "docker", URI: imageURIs["test-apps"]}
t.Assert(client.CreateArtifact(artifact), c.IsNil)
release := &ct.Release{
ArtifactID: artifact.ID,
Processes: map[string]ct.ProcessType{
"echoer": {
Cmd: []string{"/bin/echoer"},
Service: "echo-service",
Ports: []ct.Port{{
Proto: "tcp",
Service: &host.Service{
Name: "echo-service",
Create: true,
},
}},
},
"ping": {
Cmd: []string{"/bin/pingserv"},
Ports: []ct.Port{{Proto: "tcp"}},
},
"printer": {
Cmd: []string{"sh", "-c", "while true; do echo I like to print; sleep 1; done"},
},
"crasher": {
Cmd: []string{"sh", "-c", "trap 'exit 1' SIGTERM; while true; do echo I like to crash; sleep 1; done"},
},
"omni": {
Cmd: []string{"sh", "-c", "while true; do echo I am everywhere; sleep 1; done"},
Omni: true,
},
"resources": {
Cmd: []string{"sh", "-c", resourceCmd},
Resources: testResources(),
},
"ish": {
Cmd: []string{"/bin/ish"},
Ports: []ct.Port{{Proto: "tcp"}},
Env: map[string]string{
"NAME": app.Name,
},
},
},
}
t.Assert(client.CreateRelease(release), c.IsNil)
t.Assert(client.SetAppRelease(app.ID, release.ID), c.IsNil)
return app, release
}
示例2: createApp
func (h *Helper) createApp(t *c.C) (*ct.App, *ct.Release) {
client := h.controllerClient(t)
app := &ct.App{}
t.Assert(client.CreateApp(app), c.IsNil)
debugf(t, "created app %s (%s)", app.Name, app.ID)
artifact := h.newSlugrunnerArtifact(t)
t.Assert(client.CreateArtifact(artifact), c.IsNil)
release := &ct.Release{
ArtifactID: artifact.ID,
Processes: map[string]ct.ProcessType{
"echoer": {
Entrypoint: []string{"bash", "-c"},
Cmd: []string{"sdutil exec -s echo-service:$PORT socat -v tcp-l:$PORT,fork exec:/bin/cat"},
Ports: []ct.Port{{Proto: "tcp"}},
},
"printer": {
Entrypoint: []string{"bash", "-c"},
Cmd: []string{"while true; do echo I like to print; sleep 1; done"},
Ports: []ct.Port{{Proto: "tcp"}},
},
"crasher": {
Entrypoint: []string{"bash", "-c"},
Cmd: []string{"trap 'exit 1' SIGTERM; while true; do echo I like to crash; sleep 1; done"},
},
"omni": {
Entrypoint: []string{"bash", "-c"},
Cmd: []string{"while true; do echo I am everywhere; sleep 1; done"},
Omni: true,
},
},
}
t.Assert(client.CreateRelease(release), c.IsNil)
t.Assert(client.SetAppRelease(app.ID, release.ID), c.IsNil)
return app, release
}
示例3: main
func main() {
client, err := controller.NewClient("", os.Getenv("CONTROLLER_AUTH_KEY"))
if err != nil {
log.Fatalln("Unable to connect to controller:", err)
}
// TODO: use discoverd http dialer here?
services, err := discoverd.Services("shelf", discoverd.DefaultTimeout)
if err != nil || len(services) < 1 {
log.Fatalf("Unable to discover shelf %q", err)
}
shelfHost := services[0].Addr
app := os.Args[1]
commit := os.Args[2]
_, err = client.GetApp(app)
if err == controller.ErrNotFound {
log.Fatalf("Unknown app %q", app)
} else if err != nil {
log.Fatalln("Error retrieving app:", err)
}
prevRelease, err := client.GetAppRelease(app)
if err == controller.ErrNotFound {
prevRelease = &ct.Release{}
} else if err != nil {
log.Fatalln("Error creating getting current app release:", err)
}
fmt.Printf("-----> Building %s...\n", app)
var output bytes.Buffer
slugURL := fmt.Sprintf("http://%s/%s.tgz", shelfHost, commit)
cmd := exec.Command("flynn/slugbuilder", slugURL)
cmd.Stdout = io.MultiWriter(os.Stdout, &output)
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if buildpackURL, ok := prevRelease.Env["BUILDPACK_URL"]; ok {
cmd.Env = map[string]string{"BUILDPACK_URL": buildpackURL}
}
if err := cmd.Run(); err != nil {
log.Fatalln("Build failed:", err)
}
var types []string
if match := typesPattern.FindSubmatch(output.Bytes()); match != nil {
types = strings.Split(string(match[1]), ", ")
}
fmt.Printf("-----> Creating release...\n")
artifact := &ct.Artifact{URI: "docker://flynn/slugrunner"}
if err := client.CreateArtifact(artifact); err != nil {
log.Fatalln("Error creating artifact:", err)
}
release := &ct.Release{
ArtifactID: artifact.ID,
Env: prevRelease.Env,
}
procs := make(map[string]ct.ProcessType)
for _, t := range types {
proc := prevRelease.Processes[t]
proc.Cmd = []string{"start", t}
if t == "web" {
proc.Ports.TCP = 1
if proc.Env == nil {
proc.Env = make(map[string]string)
}
proc.Env["SD_NAME"] = app + "-web"
}
procs[t] = proc
}
release.Processes = procs
if release.Env == nil {
release.Env = make(map[string]string)
}
release.Env["SLUG_URL"] = slugURL
if err := client.CreateRelease(release); err != nil {
log.Fatalln("Error creating release:", err)
}
if err := client.SetAppRelease(app, release.ID); err != nil {
log.Fatalln("Error setting app release:", err)
}
fmt.Println("=====> Application deployed")
}
示例4: run
func run() error {
log := log15.New()
if *isTTY {
log.SetHandler(log15.StreamHandler(colorable.NewColorableStdout(), log15.TerminalFormat()))
}
var images map[string]*ct.Artifact
if err := json.NewDecoder(os.Stdin).Decode(&images); err != nil {
log.Error("error decoding images", "err", err)
return err
}
req, err := http.NewRequest("GET", "http://status-web.discoverd", nil)
if err != nil {
return err
}
req.Header = make(http.Header)
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Error("error getting cluster status", "err", err)
return err
}
defer res.Body.Close()
if res.StatusCode != 200 {
log.Error("cluster status is unhealthy", "code", res.StatusCode)
return fmt.Errorf("cluster is unhealthy")
}
var statusWrapper struct {
Data struct {
Detail map[string]status.Status
}
}
if err := json.NewDecoder(res.Body).Decode(&statusWrapper); err != nil {
log.Error("error decoding cluster status JSON", "err", err)
return err
}
statuses := statusWrapper.Data.Detail
instances, err := discoverd.GetInstances("controller", 10*time.Second)
if err != nil {
log.Error("error looking up controller in service discovery", "err", err)
return err
}
client, err := controller.NewClient("", instances[0].Meta["AUTH_KEY"])
if err != nil {
log.Error("error creating controller client", "err", err)
return err
}
log.Info("validating images")
for _, app := range updater.SystemApps {
if v := version.Parse(statuses[app.Name].Version); !v.Dev && app.MinVersion != "" && v.Before(version.Parse(app.MinVersion)) {
log.Info(
"not updating image of system app, can't upgrade from running version",
"app", app.Name,
"version", v,
)
continue
}
if _, ok := images[app.Name]; !ok {
err := fmt.Errorf("missing image: %s", app.Name)
log.Error(err.Error())
return err
}
}
log.Info("creating new image artifacts")
redisImage = images["redis"]
if err := client.CreateArtifact(redisImage); err != nil {
log.Error("error creating redis image artifact", "err", err)
return err
}
slugRunner = images["slugrunner"]
if err := client.CreateArtifact(slugRunner); err != nil {
log.Error("error creating slugrunner image artifact", "err", err)
return err
}
slugBuilder = images["slugbuilder"]
if err := client.CreateArtifact(slugBuilder); err != nil {
log.Error("error creating slugbuilder image artifact", "err", err)
return err
}
// deploy system apps in order first
for _, appInfo := range updater.SystemApps {
if appInfo.ImageOnly {
continue // skip ImageOnly updates
}
log := log.New("name", appInfo.Name)
log.Info("starting deploy of system app")
app, err := client.GetApp(appInfo.Name)
if err == controller.ErrNotFound && appInfo.Optional {
log.Info(
"skipped deploy of system app",
"reason", "optional app not present",
"app", appInfo.Name,
)
continue
//.........這裏部分代碼省略.........
示例5: main
func main() {
client, err := controller.NewClient("", os.Getenv("CONTROLLER_AUTH_KEY"))
if err != nil {
log.Fatalln("Unable to connect to controller:", err)
}
appName := os.Args[1]
app, err := client.GetApp(appName)
if err == controller.ErrNotFound {
log.Fatalf("Unknown app %q", appName)
} else if err != nil {
log.Fatalln("Error retrieving app:", err)
}
prevRelease, err := client.GetAppRelease(app.Name)
if err == controller.ErrNotFound {
prevRelease = &ct.Release{}
} else if err != nil {
log.Fatalln("Error getting current app release:", err)
}
fmt.Printf("-----> Building %s...\n", app.Name)
var output bytes.Buffer
slugURL := fmt.Sprintf("%s/%s.tgz", blobstoreURL, random.UUID())
cmd := exec.Command(exec.DockerImage(os.Getenv("SLUGBUILDER_IMAGE_URI")), slugURL)
cmd.Stdout = io.MultiWriter(os.Stdout, &output)
cmd.Stderr = os.Stderr
if len(prevRelease.Env) > 0 {
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatalln(err)
}
go appendEnvDir(os.Stdin, stdin, prevRelease.Env)
} else {
cmd.Stdin = os.Stdin
}
cmd.Env = make(map[string]string)
cmd.Env["BUILD_CACHE_URL"] = fmt.Sprintf("%s/%s-cache.tgz", blobstoreURL, app.ID)
if buildpackURL, ok := prevRelease.Env["BUILDPACK_URL"]; ok {
cmd.Env["BUILDPACK_URL"] = buildpackURL
}
if err := cmd.Run(); err != nil {
log.Fatalln("Build failed:", err)
}
var types []string
if match := typesPattern.FindSubmatch(output.Bytes()); match != nil {
types = strings.Split(string(match[1]), ", ")
}
fmt.Printf("-----> Creating release...\n")
artifact := &ct.Artifact{Type: "docker", URI: os.Getenv("SLUGRUNNER_IMAGE_URI")}
if err := client.CreateArtifact(artifact); err != nil {
log.Fatalln("Error creating artifact:", err)
}
release := &ct.Release{
ArtifactID: artifact.ID,
Env: prevRelease.Env,
}
procs := make(map[string]ct.ProcessType)
for _, t := range types {
proc := prevRelease.Processes[t]
proc.Cmd = []string{"start", t}
if t == "web" {
proc.Ports = []ct.Port{{
Port: 8080,
Proto: "tcp",
Service: &host.Service{
Name: app.Name + "-web",
Create: true,
Check: &host.HealthCheck{Type: "tcp"},
},
}}
}
procs[t] = proc
}
release.Processes = procs
if release.Env == nil {
release.Env = make(map[string]string)
}
release.Env["SLUG_URL"] = slugURL
if err := client.CreateRelease(release); err != nil {
log.Fatalln("Error creating release:", err)
}
if err := client.DeployAppRelease(app.Name, release.ID); err != nil {
log.Fatalln("Error deploying app release:", err)
}
fmt.Println("=====> Application deployed")
// If the app is new and the web process type exists,
// it should scale to one process after the release is created.
if _, ok := procs["web"]; ok && prevRelease.ID == "" {
formation := &ct.Formation{
AppID: app.ID,
//.........這裏部分代碼省略.........
示例6: TestSlugReleaseGarbageCollection
func (s *CLISuite) TestSlugReleaseGarbageCollection(t *c.C) {
client := s.controllerClient(t)
// create app with gc.max_inactive_slug_releases=3
maxInactiveSlugReleases := 3
app := &ct.App{Meta: map[string]string{"gc.max_inactive_slug_releases": strconv.Itoa(maxInactiveSlugReleases)}}
t.Assert(client.CreateApp(app), c.IsNil)
// create an image artifact
imageArtifact := s.createArtifact(t, "test-apps")
// create 5 slug artifacts
tmp, err := ioutil.TempFile("", "squashfs-")
t.Assert(err, c.IsNil)
defer os.Remove(tmp.Name())
defer tmp.Close()
t.Assert(exec.Command("mksquashfs", t.MkDir(), tmp.Name(), "-noappend").Run(), c.IsNil)
slug, err := ioutil.ReadAll(tmp)
t.Assert(err, c.IsNil)
slugHash := sha512.Sum512(slug)
slugs := []string{
"http://blobstore.discoverd/layer/1.squashfs",
"http://blobstore.discoverd/layer/2.squashfs",
"http://blobstore.discoverd/layer/3.squashfs",
"http://blobstore.discoverd/layer/4.squashfs",
"http://blobstore.discoverd/layer/5.squashfs",
}
slugArtifacts := make([]*ct.Artifact, len(slugs))
put := func(url string, data []byte) {
req, err := http.NewRequest("PUT", url, bytes.NewReader(data))
t.Assert(err, c.IsNil)
res, err := http.DefaultClient.Do(req)
t.Assert(err, c.IsNil)
res.Body.Close()
t.Assert(res.StatusCode, c.Equals, http.StatusOK)
}
for i, layerURL := range slugs {
manifest := &ct.ImageManifest{
Type: ct.ImageManifestTypeV1,
Rootfs: []*ct.ImageRootfs{{
Layers: []*ct.ImageLayer{{
ID: strconv.Itoa(i + 1),
Type: ct.ImageLayerTypeSquashfs,
Length: int64(len(slug)),
Hashes: map[string]string{"sha512": hex.EncodeToString(slugHash[:])},
}},
}},
}
data := manifest.RawManifest()
url := fmt.Sprintf("http://blobstore.discoverd/image/%s.json", manifest.ID())
put(url, data)
put(layerURL, slug)
artifact := &ct.Artifact{
Type: ct.ArtifactTypeFlynn,
URI: url,
Meta: map[string]string{"blobstore": "true"},
RawManifest: data,
Hashes: manifest.Hashes(),
Size: int64(len(data)),
LayerURLTemplate: "http://blobstore.discoverd/layer/{id}.squashfs",
}
t.Assert(client.CreateArtifact(artifact), c.IsNil)
slugArtifacts[i] = artifact
}
// create 6 releases, the second being scaled up and having the
// same slug as the third (so prevents the slug being deleted)
releases := make([]*ct.Release, 6)
for i, r := range []struct {
slug *ct.Artifact
active bool
}{
{slugArtifacts[0], false},
{slugArtifacts[1], true},
{slugArtifacts[1], false},
{slugArtifacts[2], false},
{slugArtifacts[3], false},
{slugArtifacts[4], false},
} {
release := &ct.Release{
ArtifactIDs: []string{imageArtifact.ID, r.slug.ID},
Processes: map[string]ct.ProcessType{
"app": {Args: []string{"/bin/pingserv"}, Ports: []ct.Port{{Proto: "tcp"}}},
},
Meta: map[string]string{"git": "true"},
}
t.Assert(client.CreateRelease(release), c.IsNil)
procs := map[string]int{"app": 0}
if r.active {
procs["app"] = 1
}
t.Assert(client.PutFormation(&ct.Formation{
AppID: app.ID,
ReleaseID: release.ID,
Processes: procs,
}), c.IsNil)
releases[i] = release
}
// scale the last release so we can deploy it
//.........這裏部分代碼省略.........
示例7: main
func main() {
client, err := controller.NewClient("", os.Getenv("CONTROLLER_AUTH_KEY"))
if err != nil {
log.Fatalln("Unable to connect to controller:", err)
}
// TODO: use discoverd http dialer here?
services, err := discoverd.Services("blobstore", discoverd.DefaultTimeout)
if err != nil || len(services) < 1 {
log.Fatalf("Unable to discover blobstore %q", err)
}
blobstoreHost := services[0].Addr
appName := os.Args[1]
app, err := client.GetApp(appName)
if err == controller.ErrNotFound {
log.Fatalf("Unknown app %q", appName)
} else if err != nil {
log.Fatalln("Error retrieving app:", err)
}
prevRelease, err := client.GetAppRelease(app.Name)
if err == controller.ErrNotFound {
prevRelease = &ct.Release{}
} else if err != nil {
log.Fatalln("Error creating getting current app release:", err)
}
fmt.Printf("-----> Building %s...\n", app.Name)
var output bytes.Buffer
slugURL := fmt.Sprintf("http://%s/%s.tgz", blobstoreHost, random.UUID())
cmd := exec.Command(exec.DockerImage("flynn/slugbuilder", os.Getenv("SLUGBUILDER_IMAGE_ID")), slugURL)
cmd.Stdout = io.MultiWriter(os.Stdout, &output)
cmd.Stderr = os.Stderr
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatalln(err)
}
go appendEnvDir(os.Stdin, stdin, prevRelease.Env)
if buildpackURL, ok := prevRelease.Env["BUILDPACK_URL"]; ok {
cmd.Env = map[string]string{"BUILDPACK_URL": buildpackURL}
}
if err := cmd.Run(); err != nil {
log.Fatalln("Build failed:", err)
}
var types []string
if match := typesPattern.FindSubmatch(output.Bytes()); match != nil {
types = strings.Split(string(match[1]), ", ")
}
fmt.Printf("-----> Creating release...\n")
artifact := &ct.Artifact{Type: "docker", URI: "https://registry.hub.docker.com/flynn/slugrunner?id=" + os.Getenv("SLUGRUNNER_IMAGE_ID")}
if err := client.CreateArtifact(artifact); err != nil {
log.Fatalln("Error creating artifact:", err)
}
release := &ct.Release{
ArtifactID: artifact.ID,
Env: prevRelease.Env,
}
procs := make(map[string]ct.ProcessType)
for _, t := range types {
proc := prevRelease.Processes[t]
proc.Cmd = []string{"start", t}
if t == "web" {
proc.Ports = []ct.Port{{Proto: "tcp"}}
if proc.Env == nil {
proc.Env = make(map[string]string)
}
proc.Env["SD_NAME"] = app.Name + "-web"
}
procs[t] = proc
}
release.Processes = procs
if release.Env == nil {
release.Env = make(map[string]string)
}
release.Env["SLUG_URL"] = slugURL
if err := client.CreateRelease(release); err != nil {
log.Fatalln("Error creating release:", err)
}
if err := client.SetAppRelease(app.Name, release.ID); err != nil {
log.Fatalln("Error setting app release:", err)
}
fmt.Println("=====> Application deployed")
// If the app is new and the web process type exists,
// it should scale to one process after the release is created.
if _, ok := procs["web"]; ok && prevRelease.ID == "" {
formation := &ct.Formation{
AppID: app.ID,
ReleaseID: release.ID,
Processes: map[string]int{"web": 1},
}
if err := client.PutFormation(formation); err != nil {
//.........這裏部分代碼省略.........
示例8: TestReleaseImages
func (s *ReleaseSuite) TestReleaseImages(t *c.C) {
if testCluster == nil {
t.Skip("cannot boot release cluster")
}
// stream script output to t.Log
logReader, logWriter := io.Pipe()
defer logWriter.Close()
go func() {
buf := bufio.NewReader(logReader)
for {
line, err := buf.ReadString('\n')
if err != nil {
return
}
debug(t, line[0:len(line)-1])
}
}()
// boot the release cluster, release components to a blobstore and output the new version.json
releaseCluster := s.addReleaseHosts(t)
buildHost := releaseCluster.Instances[0]
var versionJSON bytes.Buffer
t.Assert(buildHost.Run("bash -ex", &tc.Streams{Stdin: releaseScript, Stdout: &versionJSON, Stderr: logWriter}), c.IsNil)
var versions map[string]string
t.Assert(json.Unmarshal(versionJSON.Bytes(), &versions), c.IsNil)
// install Flynn from the blobstore on the vanilla host
blobstore := struct{ Blobstore string }{buildHost.IP + ":8080"}
installHost := releaseCluster.Instances[3]
var script bytes.Buffer
installScript.Execute(&script, blobstore)
var installOutput bytes.Buffer
out := io.MultiWriter(logWriter, &installOutput)
t.Assert(installHost.Run("sudo bash -ex", &tc.Streams{Stdin: &script, Stdout: out, Stderr: out}), c.IsNil)
// check the flynn-host version is correct
var hostVersion bytes.Buffer
t.Assert(installHost.Run("flynn-host version", &tc.Streams{Stdout: &hostVersion}), c.IsNil)
t.Assert(strings.TrimSpace(hostVersion.String()), c.Equals, "v20160711.0-test")
// check rebuilt images were downloaded
for name, id := range versions {
expected := fmt.Sprintf("%s image %s downloaded", name, id)
if !strings.Contains(installOutput.String(), expected) {
t.Fatalf(`expected install to download %s %s`, name, id)
}
}
// installing on an instance with Flynn running should fail
script.Reset()
installScript.Execute(&script, blobstore)
installOutput.Reset()
err := buildHost.Run("sudo bash -ex", &tc.Streams{Stdin: &script, Stdout: out, Stderr: out})
if err == nil || !strings.Contains(installOutput.String(), "ERROR: Flynn is already installed.") {
t.Fatal("expected Flynn install to fail but it didn't")
}
// create a controller client for the release cluster
pin, err := base64.StdEncoding.DecodeString(releaseCluster.ControllerPin)
t.Assert(err, c.IsNil)
client, err := controller.NewClientWithConfig(
"https://"+buildHost.IP,
releaseCluster.ControllerKey,
controller.Config{Pin: pin, Domain: releaseCluster.ControllerDomain},
)
t.Assert(err, c.IsNil)
// deploy a slug based app + Redis resource
slugApp := &ct.App{}
t.Assert(client.CreateApp(slugApp), c.IsNil)
gitreceive, err := client.GetAppRelease("gitreceive")
t.Assert(err, c.IsNil)
imageArtifact, err := client.GetArtifact(gitreceive.Env["SLUGRUNNER_IMAGE_ID"])
t.Assert(err, c.IsNil)
slugArtifact := &ct.Artifact{Type: host.ArtifactTypeFile, URI: fmt.Sprintf("http://%s:8080/slug.tgz", buildHost.IP)}
t.Assert(client.CreateArtifact(slugArtifact), c.IsNil)
resource, err := client.ProvisionResource(&ct.ResourceReq{ProviderID: "redis", Apps: []string{slugApp.ID}})
t.Assert(err, c.IsNil)
release := &ct.Release{
ArtifactIDs: []string{imageArtifact.ID, slugArtifact.ID},
Processes: map[string]ct.ProcessType{"web": {Args: []string{"/runner/init", "bin/http"}}},
Meta: map[string]string{"git": "true"},
Env: resource.Env,
}
t.Assert(client.CreateRelease(release), c.IsNil)
t.Assert(client.SetAppRelease(slugApp.ID, release.ID), c.IsNil)
watcher, err := client.WatchJobEvents(slugApp.ID, release.ID)
t.Assert(err, c.IsNil)
defer watcher.Close()
t.Assert(client.PutFormation(&ct.Formation{
AppID: slugApp.ID,
ReleaseID: release.ID,
Processes: map[string]int{"web": 1},
}), c.IsNil)
err = watcher.WaitFor(ct.JobEvents{"web": {ct.JobStateUp: 1}}, scaleTimeout, nil)
t.Assert(err, c.IsNil)
// run a cluster update from the blobstore
updateHost := releaseCluster.Instances[1]
//.........這裏部分代碼省略.........
示例9: main
func main() {
client, err := controller.NewClient("", os.Getenv("CONTROLLER_KEY"))
if err != nil {
log.Fatalln("Unable to connect to controller:", err)
}
appName := os.Args[1]
app, err := client.GetApp(appName)
if err == controller.ErrNotFound {
log.Fatalf("Unknown app %q", appName)
} else if err != nil {
log.Fatalln("Error retrieving app:", err)
}
prevRelease, err := client.GetAppRelease(app.Name)
if err == controller.ErrNotFound {
prevRelease = &ct.Release{}
} else if err != nil {
log.Fatalln("Error getting current app release:", err)
}
fmt.Printf("-----> Building %s...\n", app.Name)
var output bytes.Buffer
slugURL := fmt.Sprintf("%s/%s.tgz", blobstoreURL, random.UUID())
cmd := exec.Command(exec.DockerImage(os.Getenv("SLUGBUILDER_IMAGE_URI")), slugURL)
cmd.Stdout = io.MultiWriter(os.Stdout, &output)
cmd.Stderr = os.Stderr
cmd.Meta = map[string]string{
"flynn-controller.app": app.ID,
"flynn-controller.app_name": app.Name,
"flynn-controller.release": prevRelease.ID,
"flynn-controller.type": "slugbuilder",
}
if len(prevRelease.Env) > 0 {
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatalln(err)
}
go appendEnvDir(os.Stdin, stdin, prevRelease.Env)
} else {
cmd.Stdin = os.Stdin
}
cmd.Env = make(map[string]string)
cmd.Env["BUILD_CACHE_URL"] = fmt.Sprintf("%s/%s-cache.tgz", blobstoreURL, app.ID)
if buildpackURL, ok := prevRelease.Env["BUILDPACK_URL"]; ok {
cmd.Env["BUILDPACK_URL"] = buildpackURL
}
for _, k := range []string{"SSH_CLIENT_KEY", "SSH_CLIENT_HOSTS"} {
if v := os.Getenv(k); v != "" {
cmd.Env[k] = v
}
}
if err := cmd.Run(); err != nil {
log.Fatalln("Build failed:", err)
}
var types []string
if match := typesPattern.FindSubmatch(output.Bytes()); match != nil {
types = strings.Split(string(match[1]), ", ")
}
fmt.Printf("-----> Creating release...\n")
artifact := &ct.Artifact{Type: "docker", URI: os.Getenv("SLUGRUNNER_IMAGE_URI")}
if err := client.CreateArtifact(artifact); err != nil {
log.Fatalln("Error creating artifact:", err)
}
release := &ct.Release{
ArtifactID: artifact.ID,
Env: prevRelease.Env,
}
procs := make(map[string]ct.ProcessType)
for _, t := range types {
proc := prevRelease.Processes[t]
proc.Cmd = []string{"start", t}
if t == "web" {
proc.Ports = []ct.Port{{
Port: 8080,
Proto: "tcp",
Service: &host.Service{
Name: app.Name + "-web",
Create: true,
Check: &host.HealthCheck{Type: "tcp"},
},
}}
}
procs[t] = proc
}
release.Processes = procs
if release.Env == nil {
release.Env = make(map[string]string)
}
release.Env["SLUG_URL"] = slugURL
if err := client.CreateRelease(release); err != nil {
log.Fatalln("Error creating release:", err)
}
//.........這裏部分代碼省略.........
示例10: TestSlugReleaseGarbageCollection
func (s *CLISuite) TestSlugReleaseGarbageCollection(t *c.C) {
client := s.controllerClient(t)
// create app with gc.max_inactive_slug_releases=3
maxInactiveSlugReleases := 3
app := &ct.App{Meta: map[string]string{"gc.max_inactive_slug_releases": strconv.Itoa(maxInactiveSlugReleases)}}
t.Assert(client.CreateApp(app), c.IsNil)
// create an image artifact
imageArtifact := &ct.Artifact{Type: host.ArtifactTypeDocker, URI: imageURIs["test-apps"]}
t.Assert(client.CreateArtifact(imageArtifact), c.IsNil)
// create 5 slug artifacts
var slug bytes.Buffer
gz := gzip.NewWriter(&slug)
t.Assert(tar.NewWriter(gz).Close(), c.IsNil)
t.Assert(gz.Close(), c.IsNil)
slugs := []string{
"http://blobstore.discoverd/1/slug.tgz",
"http://blobstore.discoverd/2/slug.tgz",
"http://blobstore.discoverd/3/slug.tgz",
"http://blobstore.discoverd/4/slug.tgz",
"http://blobstore.discoverd/5/slug.tgz",
}
slugArtifacts := make([]*ct.Artifact, len(slugs))
for i, uri := range slugs {
req, err := http.NewRequest("PUT", uri, bytes.NewReader(slug.Bytes()))
t.Assert(err, c.IsNil)
res, err := http.DefaultClient.Do(req)
t.Assert(err, c.IsNil)
res.Body.Close()
t.Assert(res.StatusCode, c.Equals, http.StatusOK)
artifact := &ct.Artifact{
Type: host.ArtifactTypeFile,
URI: uri,
Meta: map[string]string{"blobstore": "true"},
}
t.Assert(client.CreateArtifact(artifact), c.IsNil)
slugArtifacts[i] = artifact
}
// create 6 releases, the second being scaled up and having the
// same slug as the third (so prevents the slug being deleted)
releases := make([]*ct.Release, 6)
for i, r := range []struct {
slug *ct.Artifact
active bool
}{
{slugArtifacts[0], false},
{slugArtifacts[1], true},
{slugArtifacts[1], false},
{slugArtifacts[2], false},
{slugArtifacts[3], false},
{slugArtifacts[4], false},
} {
release := &ct.Release{
ArtifactIDs: []string{imageArtifact.ID, r.slug.ID},
Processes: map[string]ct.ProcessType{
"app": {Args: []string{"/bin/pingserv"}, Ports: []ct.Port{{Proto: "tcp"}}},
},
}
t.Assert(client.CreateRelease(release), c.IsNil)
procs := map[string]int{"app": 0}
if r.active {
procs["app"] = 1
}
t.Assert(client.PutFormation(&ct.Formation{
AppID: app.ID,
ReleaseID: release.ID,
Processes: procs,
}), c.IsNil)
releases[i] = release
}
// scale the last release so we can deploy it
lastRelease := releases[len(releases)-1]
watcher, err := client.WatchJobEvents(app.ID, lastRelease.ID)
t.Assert(err, c.IsNil)
defer watcher.Close()
t.Assert(client.PutFormation(&ct.Formation{
AppID: app.ID,
ReleaseID: lastRelease.ID,
Processes: map[string]int{"app": 1},
}), c.IsNil)
t.Assert(watcher.WaitFor(ct.JobEvents{"app": ct.JobUpEvents(1)}, scaleTimeout, nil), c.IsNil)
t.Assert(client.SetAppRelease(app.ID, lastRelease.ID), c.IsNil)
// subscribe to garbage collection events
gcEvents := make(chan *ct.Event)
stream, err := client.StreamEvents(ct.StreamEventsOptions{
AppID: app.ID,
ObjectTypes: []ct.EventType{ct.EventTypeAppGarbageCollection},
}, gcEvents)
t.Assert(err, c.IsNil)
defer stream.Close()
// deploy a new release with the same slug as the last release
timeoutCh := make(chan struct{})
time.AfterFunc(5*time.Minute, func() { close(timeoutCh) })
newRelease := *lastRelease
//.........這裏部分代碼省略.........
示例11: main
func main() {
client, err := controller.NewClient("", os.Getenv("CONTROLLER_KEY"))
if err != nil {
log.Fatalln("Unable to connect to controller:", err)
}
usage := `
Usage: flynn-receiver <app> <rev> [-e <var>=<val>]... [-m <key>=<val>]...
Options:
-e,--env <var>=<val>
-m,--meta <key>=<val>
`[1:]
args, _ := docopt.Parse(usage, nil, true, version.String(), false)
appName := args.String["<app>"]
env, err := parsePairs(args, "--env")
if err != nil {
log.Fatal(err)
}
meta, err := parsePairs(args, "--meta")
if err != nil {
log.Fatal(err)
}
app, err := client.GetApp(appName)
if err == controller.ErrNotFound {
log.Fatalf("Unknown app %q", appName)
} else if err != nil {
log.Fatalln("Error retrieving app:", err)
}
prevRelease, err := client.GetAppRelease(app.Name)
if err == controller.ErrNotFound {
prevRelease = &ct.Release{}
} else if err != nil {
log.Fatalln("Error getting current app release:", err)
}
fmt.Printf("-----> Building %s...\n", app.Name)
jobEnv := make(map[string]string)
jobEnv["BUILD_CACHE_URL"] = fmt.Sprintf("%s/%s-cache.tgz", blobstoreURL, app.ID)
if buildpackURL, ok := env["BUILDPACK_URL"]; ok {
jobEnv["BUILDPACK_URL"] = buildpackURL
} else if buildpackURL, ok := prevRelease.Env["BUILDPACK_URL"]; ok {
jobEnv["BUILDPACK_URL"] = buildpackURL
}
for _, k := range []string{"SSH_CLIENT_KEY", "SSH_CLIENT_HOSTS"} {
if v := os.Getenv(k); v != "" {
jobEnv[k] = v
}
}
slugURL := fmt.Sprintf("%s/%s.tgz", blobstoreURL, random.UUID())
cmd := exec.Job(exec.DockerImage(os.Getenv("SLUGBUILDER_IMAGE_URI")), &host.Job{
Config: host.ContainerConfig{
Cmd: []string{slugURL},
Env: jobEnv,
Stdin: true,
DisableLog: true,
},
Partition: "background",
Metadata: map[string]string{
"flynn-controller.app": app.ID,
"flynn-controller.app_name": app.Name,
"flynn-controller.release": prevRelease.ID,
"flynn-controller.type": "slugbuilder",
},
})
var output bytes.Buffer
cmd.Stdout = io.MultiWriter(os.Stdout, &output)
cmd.Stderr = os.Stderr
if len(prevRelease.Env) > 0 {
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatalln(err)
}
go appendEnvDir(os.Stdin, stdin, prevRelease.Env)
} else {
cmd.Stdin = os.Stdin
}
if err := cmd.Run(); err != nil {
log.Fatalln("Build failed:", err)
}
var types []string
if match := typesPattern.FindSubmatch(output.Bytes()); match != nil {
types = strings.Split(string(match[1]), ", ")
}
fmt.Printf("-----> Creating release...\n")
artifact := &ct.Artifact{Type: "docker", URI: os.Getenv("SLUGRUNNER_IMAGE_URI")}
if err := client.CreateArtifact(artifact); err != nil {
log.Fatalln("Error creating artifact:", err)
}
release := &ct.Release{
//.........這裏部分代碼省略.........
示例12: run
func run(dir string, uid, gid int) error {
client, err := controller.NewClient("", os.Getenv("CONTROLLER_KEY"))
if err != nil {
return err
}
// create a squashfs layer
layer, err := ioutil.TempFile("", "squashfs-")
if err != nil {
return err
}
defer os.Remove(layer.Name())
defer layer.Close()
if out, err := exec.Command("mksquashfs", dir, layer.Name(), "-noappend").CombinedOutput(); err != nil {
return fmt.Errorf("mksquashfs error: %s: %s", err, out)
}
h := sha512.New512_256()
length, err := io.Copy(h, layer)
if err != nil {
return err
}
layerSHA := hex.EncodeToString(h.Sum(nil))
// upload the layer to the blobstore
if _, err := layer.Seek(0, os.SEEK_SET); err != nil {
return err
}
layerURL := fmt.Sprintf("http://blobstore.discoverd/slugs/layers/%s.squashfs", layerSHA)
if err := upload(layer, layerURL); err != nil {
return err
}
manifest := &ct.ImageManifest{
Type: ct.ImageManifestTypeV1,
// TODO: parse Procfile / .release and add to manifest.Entrypoints
Entrypoints: map[string]*ct.ImageEntrypoint{
"_default": {
Env: map[string]string{
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM": "xterm",
"HOME": "/app",
},
WorkingDir: "/app",
Args: []string{"/runner/init", "bash"},
Uid: typeconv.Uint32Ptr(uint32(uid)),
Gid: typeconv.Uint32Ptr(uint32(gid)),
},
},
Rootfs: []*ct.ImageRootfs{{
Platform: ct.DefaultImagePlatform,
Layers: []*ct.ImageLayer{{
ID: layerSHA,
Type: ct.ImageLayerTypeSquashfs,
Length: length,
Hashes: map[string]string{"sha512_256": layerSHA},
}},
}},
}
rawManifest := manifest.RawManifest()
manifestURL := fmt.Sprintf("http://blobstore.discoverd/slugs/images/%s.json", manifest.ID())
if err := upload(bytes.NewReader(rawManifest), manifestURL); err != nil {
return err
}
artifact := &ct.Artifact{
ID: os.Getenv("SLUG_IMAGE_ID"),
Type: ct.ArtifactTypeFlynn,
URI: manifestURL,
Meta: map[string]string{
"blobstore": "true",
},
RawManifest: rawManifest,
Hashes: manifest.Hashes(),
Size: int64(len(rawManifest)),
LayerURLTemplate: "http://blobstore.discoverd/slugs/layers/{id}.squashfs",
}
// create artifact
if err := client.CreateArtifact(artifact); err != nil {
return err
}
fmt.Printf("-----> Compiled slug size is %s\n", units.BytesSize(float64(length)))
return nil
}
示例13: run
func run(url string) error {
client, err := controller.NewClient("", os.Getenv("CONTROLLER_KEY"))
if err != nil {
return err
}
context, err := pinkerton.BuildContext("flynn", "/tmp/docker")
if err != nil {
return err
}
builder := &imagebuilder.Builder{
Store: &layerStore{},
Context: context,
}
// pull the docker image
ref, err := pinkerton.NewRef(url)
if err != nil {
return err
}
if _, err := context.PullDocker(url, ioutil.Discard); err != nil {
return err
}
// create squashfs for each layer
image, err := builder.Build(ref.DockerRef(), false)
if err != nil {
return err
}
// add the app name to the manifest to change its resulting ID so
// pushing the same image to multiple apps leads to different artifacts
// in the controller (and hence distinct artifact events)
if image.Meta == nil {
image.Meta = make(map[string]string, 1)
}
image.Meta["docker-receive.repository"] = ref.Name()
// upload manifest to blobstore
rawManifest := image.RawManifest()
imageURL := fmt.Sprintf("http://blobstore.discoverd/docker-receive/images/%s.json", image.ID())
if err := upload(bytes.NewReader(rawManifest), imageURL); err != nil {
return err
}
// create the artifact
artifact := &ct.Artifact{
ID: os.Getenv("ARTIFACT_ID"),
Type: ct.ArtifactTypeFlynn,
URI: imageURL,
Meta: map[string]string{
"blobstore": "true",
"docker-receive.uri": url,
"docker-receive.repository": ref.Name(),
"docker-receive.digest": ref.ID(),
},
RawManifest: rawManifest,
Hashes: image.Hashes(),
Size: int64(len(rawManifest)),
LayerURLTemplate: layerURLTemplate,
}
return client.CreateArtifact(artifact)
}
示例14: run
//.........這裏部分代碼省略.........
cmd.Stderr = os.Stderr
if len(prevRelease.Env) > 0 {
stdin, err := cmd.StdinPipe()
if err != nil {
return err
}
go func() {
if err := appendEnvDir(os.Stdin, stdin, prevRelease.Env); err != nil {
log.Fatalln("ERROR:", err)
}
}()
} else {
cmd.Stdin = os.Stdin
}
shutdown.BeforeExit(func() { cmd.Kill() })
if err := cmd.Run(); err != nil {
return fmt.Errorf("Build failed: %s", err)
}
var types []string
if match := typesPattern.FindSubmatch(output.Bytes()); match != nil {
types = strings.Split(string(match[1]), ", ")
}
fmt.Printf("-----> Creating release...\n")
slugArtifact := &ct.Artifact{
Type: host.ArtifactTypeFile,
URI: slugURL,
Meta: map[string]string{"blobstore": "true"},
}
if err := client.CreateArtifact(slugArtifact); err != nil {
return fmt.Errorf("Error creating slug artifact: %s", err)
}
release := &ct.Release{
ArtifactIDs: []string{slugRunnerID, slugArtifact.ID},
Env: prevRelease.Env,
Meta: prevRelease.Meta,
}
if release.Meta == nil {
release.Meta = make(map[string]string, len(meta))
}
if release.Env == nil {
release.Env = make(map[string]string, len(env))
}
for k, v := range env {
release.Env[k] = v
}
for k, v := range meta {
release.Meta[k] = v
}
procs := make(map[string]ct.ProcessType)
for _, t := range types {
proc := prevRelease.Processes[t]
proc.Args = []string{"/runner/init", "start", t}
if t == "web" || strings.HasSuffix(t, "-web") {
proc.Service = app.Name + "-" + t
proc.Ports = []ct.Port{{
Port: 8080,
Proto: "tcp",
Service: &host.Service{
Name: proc.Service,
Create: true,