Skip to content
This repository was archived by the owner on May 4, 2021. It is now read-only.

Commit f4c2bf0

Browse files
author
Yiran Wang
authored
Make ADD untar tar.gz files (#309)
* Make ADD untar tar files * Refactor tests * Add test
1 parent 354ac02 commit f4c2bf0

File tree

8 files changed

+159
-54
lines changed

8 files changed

+159
-54
lines changed

lib/builder/step/add_copy_step.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ type addCopyStep struct {
5858
toPath string
5959
chown string
6060
preserveOwner bool
61+
isAdd bool
6162
}
6263

6364
// newAddCopyStep returns a BuildStep from given arguments.
6465
func newAddCopyStep(
6566
directive Directive, args, chown, fromStage string,
66-
fromPaths []string, toPath string, commit, preserveOwner bool) (*addCopyStep, error) {
67+
fromPaths []string, toPath string, commit, preserveOwner, isAdd bool) (*addCopyStep, error) {
6768

6869
toPath = strings.Trim(toPath, "\"'")
6970
for i := range fromPaths {
@@ -80,6 +81,7 @@ func newAddCopyStep(
8081
toPath: toPath,
8182
chown: chown,
8283
preserveOwner: preserveOwner,
84+
isAdd: isAdd,
8385
}, nil
8486
}
8587

@@ -136,14 +138,16 @@ func (s *addCopyStep) Execute(ctx *context.BuildContext, modifyFS bool) (err err
136138

137139
internal := s.fromStage != ""
138140
blacklist := append(pathutils.DefaultBlacklist, ctx.ImageStore.RootDir)
139-
copyOp, err := snapshot.NewCopyOperation(
140-
relPaths, sourceRoot, s.workingDir, s.toPath, s.chown, blacklist, internal, s.preserveOwner)
141+
copyOp, err := snapshot.NewCopyOperation(relPaths, sourceRoot, s.workingDir, s.toPath, s.chown,
142+
s.preserveOwner, internal, blacklist, s.isAdd)
141143
if err != nil {
142144
return fmt.Errorf("invalid copy operation: %s", err)
143145
}
144146

145147
ctx.CopyOps = append(ctx.CopyOps, copyOp)
146148
if modifyFS {
149+
// Note: We still want to keep this copyop in the list, just in case there
150+
// is no RUN afterwards, and layer needs to be created from copyops.
147151
return copyOp.Execute()
148152
}
149153
return nil

lib/builder/step/add_copy_step_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,21 @@ func TestContextDirs(t *testing.T) {
2424
require := require.New(t)
2525

2626
srcs := []string{}
27-
ac, err := newAddCopyStep(Copy, "", "", "", srcs, "", false, false)
27+
ac, err := newAddCopyStep(Copy, "", "", "", srcs, "", false, false, false)
2828
require.NoError(err)
2929
stage, paths := ac.ContextDirs()
3030
require.Equal("", stage)
3131
require.Len(paths, 0)
3232

3333
srcs = []string{"src"}
34-
ac, err = newAddCopyStep(Copy, "", "", "", srcs, "", false, false)
34+
ac, err = newAddCopyStep(Copy, "", "", "", srcs, "", false, false, false)
3535
require.NoError(err)
3636
stage, paths = ac.ContextDirs()
3737
require.Equal("", stage)
3838
require.Len(paths, 0)
3939

4040
srcs = []string{"src"}
41-
ac, err = newAddCopyStep(Copy, "", "", "stage", srcs, "", false, false)
41+
ac, err = newAddCopyStep(Copy, "", "", "stage", srcs, "", false, false, false)
4242
require.NoError(err)
4343
stage, paths = ac.ContextDirs()
4444
require.Equal("stage", stage)
@@ -48,7 +48,7 @@ func TestContextDirs(t *testing.T) {
4848
func TestTrimmingPaths(t *testing.T) {
4949
require := require.New(t)
5050

51-
ac, err := newAddCopyStep(Copy, "", "", "", []string{"\"/from/path\""}, "\"/to/path\"", false, false)
51+
ac, err := newAddCopyStep(Copy, "", "", "", []string{"\"/from/path\""}, "\"/to/path\"", false, false, false)
5252
require.NoError(err)
5353

5454
require.Equal("/from/path", ac.fromPaths[0])

lib/builder/step/add_step.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ type AddStep struct {
2323

2424
// NewAddStep creates a new AddStep
2525
func NewAddStep(args, chown string, fromPaths []string, toPath string, commit, preserverOwner bool) (*AddStep, error) {
26-
s, err := newAddCopyStep(Add, args, chown, "", fromPaths, toPath, commit, preserverOwner)
26+
s, err := newAddCopyStep(
27+
Add, args, chown, "", fromPaths, toPath, commit, preserverOwner, true)
2728
if err != nil {
2829
return nil, fmt.Errorf("new add/copy step: %s", err)
2930
}

lib/builder/step/copy_step.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ func NewCopyStep(
2626
args, chown, fromStage string, fromPaths []string, toPath string, commit, preserveOwner bool,
2727
) (*CopyStep, error) {
2828

29-
s, err := newAddCopyStep(Copy, args, chown, fromStage, fromPaths, toPath, commit, preserveOwner)
29+
s, err := newAddCopyStep(
30+
Copy, args, chown, fromStage, fromPaths, toPath, commit, preserveOwner, false)
3031
if err != nil {
3132
return nil, fmt.Errorf("new add/copy step: %s", err)
3233
}

lib/snapshot/copy_op.go

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import (
2222

2323
"github.com/uber/makisu/lib/fileio"
2424
"github.com/uber/makisu/lib/pathutils"
25+
"github.com/uber/makisu/lib/tario"
2526
"github.com/uber/makisu/lib/utils"
2627
)
2728

28-
// CopyOperation defines a copy operation that occurred to generate a layer from.
2929
type CopyOperation struct {
3030
srcRoot string
3131
srcs []string
@@ -34,16 +34,20 @@ type CopyOperation struct {
3434
gid int
3535
preserveOwner bool
3636

37-
blacklist []string
3837
// Indicates if the copy op is used for copying from previous stages.
39-
internal bool
38+
// Blacklist is ignored in that case.
39+
internal bool
40+
blacklist []string
41+
42+
// Set to true if the copy op was created by ADD step.
43+
// Some functionalities are only available to ADD.
44+
fromAdd bool
4045
}
4146

4247
// NewCopyOperation initializes and validates a CopyOperation. Use "internal" to
4348
// specify if the copy op is used for copying from previous stages.
44-
func NewCopyOperation(
45-
srcs []string, srcRoot, workDir, dst, chown string,
46-
blacklist []string, internal, preserveOwner bool) (*CopyOperation, error) {
49+
func NewCopyOperation(srcs []string, srcRoot, workDir, dst, chown string,
50+
preserveOwner, internal bool, blacklist []string, fromAdd bool) (*CopyOperation, error) {
4751

4852
if err := checkCopyParams(srcs, workDir, dst); err != nil {
4953
return nil, fmt.Errorf("check copy param: %s", err)
@@ -70,6 +74,7 @@ func NewCopyOperation(
7074
preserveOwner: preserveOwner,
7175
blacklist: blacklist,
7276
internal: internal,
77+
fromAdd: fromAdd,
7378
}, nil
7479
}
7580

@@ -86,6 +91,32 @@ func (c *CopyOperation) Execute() error {
8691
if err != nil {
8792
return fmt.Errorf("lstat %s: %s", src, err)
8893
}
94+
95+
if strings.HasSuffix(src, ".tar.gz") && c.fromAdd {
96+
// Special feature for ADD - Extract tar.gz into dst directory.
97+
// If dst is an existing directory, untar.
98+
// If dst doesn't exist, create it with root.
99+
// If dst exists and is not a directory, fail.
100+
reader, err := os.Open(src)
101+
if err != nil {
102+
return fmt.Errorf("open tar file: %s", err)
103+
}
104+
defer reader.Close()
105+
106+
if err := os.MkdirAll(c.dst, 0755); err != nil {
107+
return fmt.Errorf("create/validate untar dst: %s", err)
108+
}
109+
110+
gzipReader, err := tario.NewGzipReader(reader)
111+
if err != nil {
112+
return fmt.Errorf("unzip gz %s: %s", src, err)
113+
}
114+
if err := tario.Untar(gzipReader, c.dst); err != nil {
115+
return fmt.Errorf("untar %s to dst %s: %s", src, c.dst, err)
116+
}
117+
return nil
118+
}
119+
89120
var copier fileio.Copier
90121
if c.internal {
91122
copier = fileio.NewInternalCopier()
@@ -115,7 +146,6 @@ func (c *CopyOperation) Execute() error {
115146
return fmt.Errorf("copy file %s to dir %s: %s", src, targetFilePath, err)
116147
}
117148
}
118-
119149
} else {
120150
// File to file
121151
if c.preserveOwner {

0 commit comments

Comments
 (0)