Skip to content

Commit

Permalink
Merge the same TOML file writing logic
Browse files Browse the repository at this point in the history
Signed-off-by: Woa <me@wuzy.cn>
  • Loading branch information
ESWZY committed Jul 3, 2023
1 parent 52902b0 commit d78e829
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 69 deletions.
106 changes: 37 additions & 69 deletions internal/build/container_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,92 +207,60 @@ func findMount(info types.ContainerJSON, dst string) (types.MountPoint, error) {
return types.MountPoint{}, fmt.Errorf("no matching mount found for %s", dst)
}

// WriteProjectMetadata
func WriteProjectMetadata(p string, metadata platform.ProjectMetadata, os string) ContainerOperation {
return func(ctrClient DockerClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error {
buf := &bytes.Buffer{}
err := toml.NewEncoder(buf).Encode(metadata)
if err != nil {
return errors.Wrap(err, "marshaling project metadata")
}
func writeToml(ctrClient DockerClient, ctx context.Context, data interface{}, dstPath string, containerID string, os string, stdout, stderr io.Writer) error {
buf := &bytes.Buffer{}
err := toml.NewEncoder(buf).Encode(data)
if err != nil {
return errors.Wrap(err, "marshaling data")
}

tarBuilder := archive.TarBuilder{}
tarBuilder := archive.TarBuilder{}

tarPath := p
if os == "windows" {
tarPath = paths.WindowsToSlash(p)
}
tarPath := dstPath
if os == "windows" {
tarPath = paths.WindowsToSlash(dstPath)
}

tarBuilder.AddFile(tarPath, 0755, archive.NormalizedDateTime, buf.Bytes())
reader := tarBuilder.Reader(archive.DefaultTarWriterFactory())
defer reader.Close()
tarBuilder.AddFile(tarPath, 0755, archive.NormalizedDateTime, buf.Bytes())
reader := tarBuilder.Reader(archive.DefaultTarWriterFactory())
defer reader.Close()

if os == "windows" {
dirName := paths.WindowsDir(p)
return copyDirWindows(ctx, ctrClient, containerID, reader, dirName, stdout, stderr)
}
if os == "windows" {
dirName := paths.WindowsDir(dstPath)
return copyDirWindows(ctx, ctrClient, containerID, reader, dirName, stdout, stderr)
}

return ctrClient.CopyToContainer(ctx, containerID, "/", reader, types.CopyToContainerOptions{})
}

return ctrClient.CopyToContainer(ctx, containerID, "/", reader, types.CopyToContainerOptions{})
// WriteToml writes a `data.toml` for test only.
func WriteToml(dstPath string, data interface{}, os string) ContainerOperation {
return func(ctrClient DockerClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error {
return writeToml(ctrClient, ctx, data, dstPath, containerID, os, stdout, stderr)
}
}

// WriteProjectMetadata writes a `project-metadata.toml` based on the ProjectMetadata provided to the destination path.
func WriteProjectMetadata(dstPath string, metadata platform.ProjectMetadata, os string) ContainerOperation {
return func(ctrClient DockerClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error {
return writeToml(ctrClient, ctx, metadata, dstPath, containerID, os, stdout, stderr)
}
}

// WriteStackToml writes a `stack.toml` based on the StackMetadata provided to the destination path.
func WriteStackToml(dstPath string, stack builder.StackMetadata, os string) ContainerOperation {
return func(ctrClient DockerClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error {
buf := &bytes.Buffer{}
err := toml.NewEncoder(buf).Encode(stack)
if err != nil {
return errors.Wrap(err, "marshaling stack metadata")
}

tarBuilder := archive.TarBuilder{}

tarPath := dstPath
if os == "windows" {
tarPath = paths.WindowsToSlash(dstPath)
}

tarBuilder.AddFile(tarPath, 0755, archive.NormalizedDateTime, buf.Bytes())
reader := tarBuilder.Reader(archive.DefaultTarWriterFactory())
defer reader.Close()

if os == "windows" {
dirName := paths.WindowsDir(dstPath)
return copyDirWindows(ctx, ctrClient, containerID, reader, dirName, stdout, stderr)
}

return ctrClient.CopyToContainer(ctx, containerID, "/", reader, types.CopyToContainerOptions{})
return writeToml(ctrClient, ctx, stack, dstPath, containerID, os, stdout, stderr)
}
}

// WriteRunToml writes a `run.toml` based on the RunConfig provided to the destination path.
func WriteRunToml(dstPath string, runImages []builder.RunImageMetadata, os string) ContainerOperation {
runImageData := builder.RunImages{
Images: runImages,
}
return func(ctrClient DockerClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error {
buf := &bytes.Buffer{}
err := toml.NewEncoder(buf).Encode(builder.RunImages{
Images: runImages,
})
if err != nil {
return errors.Wrap(err, "marshaling run metadata")
}

tarBuilder := archive.TarBuilder{}

tarPath := dstPath
if os == "windows" {
tarPath = paths.WindowsToSlash(dstPath)
}

tarBuilder.AddFile(tarPath, 0755, archive.NormalizedDateTime, buf.Bytes())
reader := tarBuilder.Reader(archive.DefaultTarWriterFactory())
defer reader.Close()

if os == "windows" {
dirName := paths.WindowsDir(dstPath)
return copyDirWindows(ctx, ctrClient, containerID, reader, dirName, stdout, stderr)
}

return ctrClient.CopyToContainer(ctx, containerID, "/", reader, types.CopyToContainerOptions{})
return writeToml(ctrClient, ctx, runImageData, dstPath, containerID, os, stdout, stderr)
}
}

Expand Down
94 changes: 94 additions & 0 deletions internal/build/container_ops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,100 @@ drwxr-xr-x 2 123 456 (.*) some-vol
`)
})
})

when("#WriteToml", func() {
it("writes file", func() {
containerDir := "/layers-vol"
p := "/layers-vol/data.toml"
if osType == "windows" {
containerDir = `c:\layers-vol`
p = `c:\layers-vol\data.toml`
}

ctrCmd := []string{"ls", "-al", "/layers-vol/data.toml"}
if osType == "windows" {
ctrCmd = []string{"cmd", "/c", `dir /q /n c:\layers-vol\data.toml`}
}
ctx := context.Background()
ctr, err := createContainer(ctx, imageName, containerDir, osType, ctrCmd...)
h.AssertNil(t, err)
defer cleanupContainer(ctx, ctr.ID)

writeOp := build.WriteToml(p, platform.ProjectMetadata{
Source: &platform.ProjectSource{
Type: "project",
Version: map[string]interface{}{
"declared": "1.0.2",
},
Metadata: map[string]interface{}{
"url": "https://github.com/buildpacks/pack",
},
},
}, osType)

var outBuf, errBuf bytes.Buffer
err = writeOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf)
h.AssertNil(t, err)

err = container.RunWithHandler(ctx, ctrClient, ctr.ID, container.DefaultHandler(&outBuf, &errBuf))
h.AssertNil(t, err)

h.AssertEq(t, errBuf.String(), "")
if osType == "windows" {
h.AssertContains(t, outBuf.String(), `01/01/1980 12:00 AM 137 ... data.toml`)
} else {
h.AssertContains(t, outBuf.String(), `-rwxr-xr-x 1 root root 137 Jan 1 1980 /layers-vol/data.toml`)
}
})

it("has expected contents", func() {
containerDir := "/layers-vol"
p := "/layers-vol/data.toml"
if osType == "windows" {
containerDir = `c:\layers-vol`
p = `c:\layers-vol\data.toml`
}

ctrCmd := []string{"cat", "/layers-vol/data.toml"}
if osType == "windows" {
ctrCmd = []string{"cmd", "/c", `type c:\layers-vol\data.toml`}
}

ctx := context.Background()
ctr, err := createContainer(ctx, imageName, containerDir, osType, ctrCmd...)
h.AssertNil(t, err)
defer cleanupContainer(ctx, ctr.ID)

writeOp := build.WriteProjectMetadata(p, platform.ProjectMetadata{
Source: &platform.ProjectSource{
Type: "project",
Version: map[string]interface{}{
"declared": "1.0.2",
},
Metadata: map[string]interface{}{
"url": "https://github.com/buildpacks/pack",
},
},
}, osType)

var outBuf, errBuf bytes.Buffer
err = writeOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf)
h.AssertNil(t, err)

err = container.RunWithHandler(ctx, ctrClient, ctr.ID, container.DefaultHandler(&outBuf, &errBuf))
h.AssertEq(t, errBuf.String(), "")
h.AssertNil(t, err)

h.AssertContains(t, outBuf.String(), `[source]
type = "project"
[source.version]
declared = "1.0.2"
[source.metadata]
url = "https://github.com/buildpacks/pack"
`)
})
})

when("#EnsureVolumeAccess", func() {
it("changes owner of volume", func() {
h.SkipIf(t, osType != "windows", "no-op for linux")
Expand Down

0 comments on commit d78e829

Please sign in to comment.