dockerfile: add support for user

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2017-12-11 15:08:35 -08:00
parent 7a5390f355
commit 6626255a71
2 changed files with 97 additions and 0 deletions

View File

@ -477,6 +477,7 @@ func dispatchExpose(d *dispatchState, c *instructions.ExposeCommand, shlex *Shel
return commitToHistory(&d.image, fmt.Sprintf("EXPOSE %v", ps), false, nil) return commitToHistory(&d.image, fmt.Sprintf("EXPOSE %v", ps), false, nil)
} }
func dispatchUser(d *dispatchState, c *instructions.UserCommand, commit bool) error { func dispatchUser(d *dispatchState, c *instructions.UserCommand, commit bool) error {
d.state = d.state.User(c.User)
d.image.Config.User = c.User d.image.Config.User = c.User
if commit { if commit {
return commitToHistory(&d.image, fmt.Sprintf("USER %v", c.User), false, nil) return commitToHistory(&d.image, fmt.Sprintf("USER %v", c.User), false, nil)

View File

@ -38,6 +38,7 @@ func TestIntegration(t *testing.T) {
testDockerfileScratchConfig, testDockerfileScratchConfig,
testExportedHistory, testExportedHistory,
testExposeExpansion, testExposeExpansion,
testUser,
}) })
} }
@ -575,6 +576,101 @@ RUN ["ls"]
require.Equal(t, true, ociimg.History[5].EmptyLayer) require.Equal(t, true, ociimg.History[5].EmptyLayer)
} }
func testUser(t *testing.T, sb integration.Sandbox) {
t.Parallel()
dockerfile := []byte(`
FROM busybox AS base
RUN mkdir -m 0777 /out
RUN id -un > /out/rootuser
USER daemon
RUN id -un > /out/daemonuser
FROM scratch
COPY --from=base /out /
USER nobody
`)
dir, err := tmpdir(
fstest.CreateFile("Dockerfile", dockerfile, 0600),
)
require.NoError(t, err)
defer os.RemoveAll(dir)
c, err := client.New(sb.Address())
require.NoError(t, err)
defer c.Close()
destDir, err := ioutil.TempDir("", "buildkit")
require.NoError(t, err)
defer os.RemoveAll(destDir)
err = c.Solve(context.TODO(), nil, client.SolveOpt{
Frontend: "dockerfile.v0",
Exporter: client.ExporterLocal,
ExporterAttrs: map[string]string{
"output": destDir,
},
LocalDirs: map[string]string{
localNameDockerfile: dir,
localNameContext: dir,
},
}, nil)
require.NoError(t, err)
dt, err := ioutil.ReadFile(filepath.Join(destDir, "rootuser"))
require.NoError(t, err)
require.Equal(t, string(dt), "root\n")
dt, err = ioutil.ReadFile(filepath.Join(destDir, "daemonuser"))
require.NoError(t, err)
require.Equal(t, string(dt), "daemon\n")
// test user in exported
target := "example.com/moby/dockerfileuser:test"
err = c.Solve(context.TODO(), nil, client.SolveOpt{
Frontend: "dockerfile.v0",
Exporter: client.ExporterImage,
ExporterAttrs: map[string]string{
"name": target,
},
LocalDirs: map[string]string{
localNameDockerfile: dir,
localNameContext: dir,
},
}, nil)
require.NoError(t, err)
var cdAddress string
if cd, ok := sb.(interface {
ContainerdAddress() string
}); !ok {
return
} else {
cdAddress = cd.ContainerdAddress()
}
client, err := containerd.New(cdAddress)
require.NoError(t, err)
defer client.Close()
ctx := namespaces.WithNamespace(context.Background(), "buildkit")
img, err := client.ImageService().Get(ctx, target)
require.NoError(t, err)
desc, err := img.Config(ctx, client.ContentStore(), platforms.Default())
require.NoError(t, err)
dt, err = content.ReadBlob(ctx, client.ContentStore(), desc.Digest)
require.NoError(t, err)
var ociimg ocispec.Image
err = json.Unmarshal(dt, &ociimg)
require.NoError(t, err)
require.Equal(t, "nobody", ociimg.Config.User)
}
func tmpdir(appliers ...fstest.Applier) (string, error) { func tmpdir(appliers ...fstest.Applier) (string, error) {
tmpdir, err := ioutil.TempDir("", "buildkit-dockerfile") tmpdir, err := ioutil.TempDir("", "buildkit-dockerfile")
if err != nil { if err != nil {