Skip to content

Commit

Permalink
Read PACK_USER_ID:PACK_USER_GID for daemon export
Browse files Browse the repository at this point in the history
[#50]
  • Loading branch information
dgodd committed Oct 18, 2018
1 parent bace2a6 commit fed01a5
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 6 deletions.
32 changes: 32 additions & 0 deletions build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,38 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
assertEq(t, metadata.Buildpacks[0].Layers["mylayer"].Data, map[string]interface{}{"key": "myval"})
assertContains(t, metadata.Buildpacks[0].Layers["other"].SHA, "sha256:")
})

it("sets owner of layer files to PACK_USER_ID:PACK_USER_GID", func() {
subject.RunImage = "packs/run-" + randString(8)
defer exec.Command("docker", "rmi", subject.RunImage)
cmd := exec.Command("docker", "build", "-t", subject.RunImage, "-")
cmd.Stdin = strings.NewReader(`
FROM packs/run
ENV PACK_USER_ID 1234
ENV PACK_USER_GID 5678
`)
assertNil(t, cmd.Run())

assertNil(t, subject.Export(group))
txt, err := exec.Command("docker", "run", subject.RepoName, "ls", "-la", "/workspace/app/file.txt").Output()
assertNil(t, err)
assertContains(t, string(txt), " 1234 5678 ")
})

it("errors if run image is missing PACK_USER_ID", func() {
subject.RunImage = "packs/run-" + randString(8)
defer exec.Command("docker", "rmi", subject.RunImage)
cmd := exec.Command("docker", "build", "-t", subject.RunImage, "-")
cmd.Stdin = strings.NewReader(`
FROM packs/run
ENV PACK_USER_ID ''
ENV PACK_USER_GID 5678
`)
assertNil(t, cmd.Run())

err := subject.Export(group)
assertError(t, err, "export uid/gid: could not find PACK_USER_ID && PACK_USER_GID from run image")
})
})
})

Expand Down
38 changes: 32 additions & 6 deletions exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"github.com/buildpack/pack/fs"
"github.com/buildpack/pack/image"
"github.com/buildpack/packs"

"github.com/buildpack/packs"
)

func exportRegistry(group *lifecycle.BuildpackGroup, workspaceDir, repoName, stackName string, stdout, stderr io.Writer) (string, error) {
Expand Down Expand Up @@ -73,6 +75,25 @@ func exportRegistry(group *lifecycle.BuildpackGroup, workspaceDir, repoName, sta
return sha.String(), nil
}

func runImageUIDGID(cli Docker, ctx context.Context, runImage string) (string, error) {
i, _, err := cli.ImageInspectWithRaw(ctx, runImage)
if err != nil {
return "", errors.Wrap(err, "inspect image to find UID & GID")
}
var uid, gid string
for _, e := range i.Config.Env {
if strings.HasPrefix(e, "PACK_USER_ID=") {
uid = e[13:]
} else if strings.HasPrefix(e, "PACK_USER_GID=") {
gid = e[14:]
}
}
if uid == "" || gid == "" {
return "", errors.New("could not find PACK_USER_ID && PACK_USER_GID from run image")
}
return uid + ":" + gid, nil
}

func exportDaemon(cli Docker, buildpacks []string, workspaceVolume, repoName, runImage string, stdout io.Writer) error {
ctx := context.Background()
ctr, err := cli.ContainerCreate(ctx, &container.Config{
Expand All @@ -94,7 +115,12 @@ func exportDaemon(cli Docker, buildpacks []string, workspaceVolume, repoName, ru
return errors.Wrap(err, "copy from container")
}

r2, layerChan, errChan := addDockerfileToTar(runImage, repoName, buildpacks, r)
chownUser, err := runImageUIDGID(cli, ctx, runImage)
if err != nil {
return errors.Wrap(err, "export uid/gid")
}

r2, layerChan, errChan := addDockerfileToTar(chownUser, runImage, repoName, buildpacks, r)

res, err := cli.ImageBuild(ctx, r2, dockertypes.ImageBuildOptions{Tags: []string{repoName}})
if err != nil {
Expand Down Expand Up @@ -183,10 +209,10 @@ type dockerfileLayer struct {
data interface{}
}

func addDockerfileToTar(runImage, repoName string, buildpacks []string, r io.Reader) (io.Reader, chan []dockerfileLayer, chan error) {
func addDockerfileToTar(chownUser, runImage, repoName string, buildpacks []string, r io.Reader) (io.Reader, chan []dockerfileLayer, chan error) {
dockerFile := "FROM " + runImage + "\n"
dockerFile += "ADD --chown=pack:pack /workspace/app /workspace/app\n"
dockerFile += "ADD --chown=pack:pack /workspace/config /workspace/config\n"
dockerFile += fmt.Sprintf("ADD --chown=%s /workspace/app /workspace/app\n", chownUser)
dockerFile += fmt.Sprintf("ADD --chown=%s /workspace/config /workspace/config\n", chownUser)
layerChan := make(chan []dockerfileLayer, 1)
var layerNames []dockerfileLayer
errChan := make(chan error, 1)
Expand Down Expand Up @@ -263,9 +289,9 @@ func addDockerfileToTar(runImage, repoName string, buildpacks []string, r io.Rea
for _, layer := range layers {
layerNames = append(layerNames, dockerfileLayer{buildpack, layer, tomlFiles[buildpack][layer]})
if dirs[buildpack][layer] {
dockerFile += fmt.Sprintf("ADD --chown=pack:pack /workspace/%s/%s /workspace/%s/%s\n", buildpack, layer, buildpack, layer)
dockerFile += fmt.Sprintf("ADD --chown=%s /workspace/%s/%s /workspace/%s/%s\n", chownUser, buildpack, layer, buildpack, layer)
} else {
dockerFile += fmt.Sprintf("COPY --from=prev --chown=pack:pack /workspace/%s/%s /workspace/%s/%s\n", buildpack, layer, buildpack, layer)
dockerFile += fmt.Sprintf("COPY --from=prev --chown=%s /workspace/%s/%s /workspace/%s/%s\n", chownUser, buildpack, layer, buildpack, layer)
copyFromPrev = true
}
}
Expand Down

0 comments on commit fed01a5

Please sign in to comment.