Exemplo n.º 1
0
func (e *generator) createArtifact() {
	manifest := &ct.ImageManifest{
		Type: ct.ImageManifestTypeV1,
		Meta: map[string]string{"foo": "bar"},
		Entrypoints: map[string]*ct.ImageEntrypoint{
			"_default": {
				Env:        map[string]string{"key": "default-val"},
				WorkingDir: "/",
				Args:       []string{"bash"},
			},
			"web": {
				Env:        map[string]string{"key": "other-val"},
				WorkingDir: "/app",
				Args:       []string{"/bin/web-server"},
				Uid:        typeconv.Uint32Ptr(1000),
				Gid:        typeconv.Uint32Ptr(1000),
			},
		},
		Rootfs: []*ct.ImageRootfs{
			{
				Platform: &ct.ImagePlatform{
					Architecture: "amd64",
					OS:           "linux",
				},
				Layers: []*ct.ImageLayer{
					{
						ID:     "34510d7fb6c0b108121b5f5f2e86f0c4c27a1e6d1dbbbd131189a65fab641775",
						Type:   ct.ImageLayerTypeSquashfs,
						Length: 34570240,
						Hashes: map[string]string{"sha512_256": "34510d7fb6c0b108121b5f5f2e86f0c4c27a1e6d1dbbbd131189a65fab641775"},
					},
					{
						ID:     "d038205ed955b94a475dfaf81b4e593b77d3b74420d673fb0bf0a7ca8c4cc345",
						Type:   ct.ImageLayerTypeSquashfs,
						Length: 92368896,
						Hashes: map[string]string{"sha512_256": "d038205ed955b94a475dfaf81b4e593b77d3b74420d673fb0bf0a7ca8c4cc345"},
					},
				},
			},
		},
	}
	artifact := &ct.Artifact{
		Type:             ct.ArtifactTypeFlynn,
		URI:              e.resourceIds["SLUGRUNNER_IMAGE_URI"],
		RawManifest:      manifest.RawManifest(),
		Hashes:           manifest.Hashes(),
		Size:             int64(len(manifest.RawManifest())),
		LayerURLTemplate: "https://dl.flynn.io/tuf?target=/layers/{id}.squashfs",
	}
	err := e.client.CreateArtifact(artifact)
	if err != nil {
		log.Fatal(err)
	}
	e.resourceIds["artifact"] = artifact.ID
}
Exemplo n.º 2
0
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
}