Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)
| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,15 +0,0 @@ |
| 1 |
-package builder |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "github.com/docker/docker/runconfig" |
|
| 5 |
-) |
|
| 6 |
- |
|
| 7 |
-// Create a new builder. See |
|
| 8 |
-func NewBuilder(opts *BuildOpts) *BuildFile {
|
|
| 9 |
- return &BuildFile{
|
|
| 10 |
- Dockerfile: nil, |
|
| 11 |
- Config: &runconfig.Config{},
|
|
| 12 |
- Options: opts, |
|
| 13 |
- TmpContainers: map[string]struct{}{},
|
|
| 14 |
- } |
|
| 15 |
-} |
| ... | ... |
@@ -18,7 +18,7 @@ import ( |
| 18 | 18 |
) |
| 19 | 19 |
|
| 20 | 20 |
// dispatch with no layer / parsing. This is effectively not a command. |
| 21 |
-func nullDispatch(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 21 |
+func nullDispatch(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 22 | 22 |
return nil |
| 23 | 23 |
} |
| 24 | 24 |
|
| ... | ... |
@@ -27,7 +27,7 @@ func nullDispatch(b *BuildFile, args []string, attributes map[string]bool) error |
| 27 | 27 |
// Sets the environment variable foo to bar, also makes interpolation |
| 28 | 28 |
// in the dockerfile available from the next statement on via ${foo}.
|
| 29 | 29 |
// |
| 30 |
-func env(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 30 |
+func env(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 31 | 31 |
if len(args) != 2 {
|
| 32 | 32 |
return fmt.Errorf("ENV accepts two arguments")
|
| 33 | 33 |
} |
| ... | ... |
@@ -48,7 +48,7 @@ func env(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 48 | 48 |
// MAINTAINER some text <maybe@an.email.address> |
| 49 | 49 |
// |
| 50 | 50 |
// Sets the maintainer metadata. |
| 51 |
-func maintainer(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 51 |
+func maintainer(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 52 | 52 |
if len(args) != 1 {
|
| 53 | 53 |
return fmt.Errorf("MAINTAINER requires only one argument")
|
| 54 | 54 |
} |
| ... | ... |
@@ -62,7 +62,7 @@ func maintainer(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 62 | 62 |
// Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling |
| 63 | 63 |
// exist here. If you do not wish to have this automatic handling, use COPY. |
| 64 | 64 |
// |
| 65 |
-func add(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 65 |
+func add(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 66 | 66 |
if len(args) != 2 {
|
| 67 | 67 |
return fmt.Errorf("ADD requires two arguments")
|
| 68 | 68 |
} |
| ... | ... |
@@ -74,7 +74,7 @@ func add(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 74 | 74 |
// |
| 75 | 75 |
// Same as 'ADD' but without the tar and remote url handling. |
| 76 | 76 |
// |
| 77 |
-func dispatchCopy(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 77 |
+func dispatchCopy(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 78 | 78 |
if len(args) != 2 {
|
| 79 | 79 |
return fmt.Errorf("COPY requires two arguments")
|
| 80 | 80 |
} |
| ... | ... |
@@ -86,16 +86,16 @@ func dispatchCopy(b *BuildFile, args []string, attributes map[string]bool) error |
| 86 | 86 |
// |
| 87 | 87 |
// This sets the image the dockerfile will build on top of. |
| 88 | 88 |
// |
| 89 |
-func from(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 89 |
+func from(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 90 | 90 |
if len(args) != 1 {
|
| 91 | 91 |
return fmt.Errorf("FROM requires one argument")
|
| 92 | 92 |
} |
| 93 | 93 |
|
| 94 | 94 |
name := args[0] |
| 95 | 95 |
|
| 96 |
- image, err := b.Options.Daemon.Repositories().LookupImage(name) |
|
| 96 |
+ image, err := b.Daemon.Repositories().LookupImage(name) |
|
| 97 | 97 |
if err != nil {
|
| 98 |
- if b.Options.Daemon.Graph().IsNotExist(err) {
|
|
| 98 |
+ if b.Daemon.Graph().IsNotExist(err) {
|
|
| 99 | 99 |
image, err = b.pullImage(name) |
| 100 | 100 |
} |
| 101 | 101 |
|
| ... | ... |
@@ -118,7 +118,7 @@ func from(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 118 | 118 |
// special cases. search for 'OnBuild' in internals.go for additional special |
| 119 | 119 |
// cases. |
| 120 | 120 |
// |
| 121 |
-func onbuild(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 121 |
+func onbuild(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 122 | 122 |
triggerInstruction := strings.ToUpper(strings.TrimSpace(args[0])) |
| 123 | 123 |
switch triggerInstruction {
|
| 124 | 124 |
case "ONBUILD": |
| ... | ... |
@@ -137,7 +137,7 @@ func onbuild(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 137 | 137 |
// |
| 138 | 138 |
// Set the working directory for future RUN/CMD/etc statements. |
| 139 | 139 |
// |
| 140 |
-func workdir(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 140 |
+func workdir(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 141 | 141 |
if len(args) != 1 {
|
| 142 | 142 |
return fmt.Errorf("WORKDIR requires exactly one argument")
|
| 143 | 143 |
} |
| ... | ... |
@@ -165,7 +165,7 @@ func workdir(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 165 | 165 |
// RUN echo hi # sh -c echo hi |
| 166 | 166 |
// RUN [ "echo", "hi" ] # echo hi |
| 167 | 167 |
// |
| 168 |
-func run(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 168 |
+func run(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 169 | 169 |
args = handleJsonArgs(args, attributes) |
| 170 | 170 |
|
| 171 | 171 |
if b.image == "" {
|
| ... | ... |
@@ -220,7 +220,7 @@ func run(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 220 | 220 |
// Set the default command to run in the container (which may be empty). |
| 221 | 221 |
// Argument handling is the same as RUN. |
| 222 | 222 |
// |
| 223 |
-func cmd(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 223 |
+func cmd(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 224 | 224 |
b.Config.Cmd = handleJsonArgs(args, attributes) |
| 225 | 225 |
|
| 226 | 226 |
if err := b.commit("", b.Config.Cmd, fmt.Sprintf("CMD %v", cmd)); err != nil {
|
| ... | ... |
@@ -239,7 +239,7 @@ func cmd(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 239 | 239 |
// Handles command processing similar to CMD and RUN, only b.Config.Entrypoint |
| 240 | 240 |
// is initialized at NewBuilder time instead of through argument parsing. |
| 241 | 241 |
// |
| 242 |
-func entrypoint(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 242 |
+func entrypoint(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 243 | 243 |
b.Config.Entrypoint = handleJsonArgs(args, attributes) |
| 244 | 244 |
|
| 245 | 245 |
// if there is no cmd in current Dockerfile - cleanup cmd |
| ... | ... |
@@ -258,7 +258,7 @@ func entrypoint(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 258 | 258 |
// Expose ports for links and port mappings. This all ends up in |
| 259 | 259 |
// b.Config.ExposedPorts for runconfig. |
| 260 | 260 |
// |
| 261 |
-func expose(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 261 |
+func expose(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 262 | 262 |
portsTab := args |
| 263 | 263 |
|
| 264 | 264 |
if b.Config.ExposedPorts == nil {
|
| ... | ... |
@@ -285,7 +285,7 @@ func expose(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 285 | 285 |
// Set the user to 'foo' for future commands and when running the |
| 286 | 286 |
// ENTRYPOINT/CMD at container run time. |
| 287 | 287 |
// |
| 288 |
-func user(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 288 |
+func user(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 289 | 289 |
if len(args) != 1 {
|
| 290 | 290 |
return fmt.Errorf("USER requires exactly one argument")
|
| 291 | 291 |
} |
| ... | ... |
@@ -299,7 +299,7 @@ func user(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 299 | 299 |
// Expose the volume /foo for use. Will also accept the JSON form, but either |
| 300 | 300 |
// way requires exactly one argument. |
| 301 | 301 |
// |
| 302 |
-func volume(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 302 |
+func volume(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 303 | 303 |
if len(args) != 1 {
|
| 304 | 304 |
return fmt.Errorf("Volume cannot be empty")
|
| 305 | 305 |
} |
| ... | ... |
@@ -319,6 +319,6 @@ func volume(b *BuildFile, args []string, attributes map[string]bool) error {
|
| 319 | 319 |
} |
| 320 | 320 |
|
| 321 | 321 |
// INSERT is no longer accepted, but we still parse it. |
| 322 |
-func insert(b *BuildFile, args []string, attributes map[string]bool) error {
|
|
| 322 |
+func insert(b *Builder, args []string, attributes map[string]bool) error {
|
|
| 323 | 323 |
return fmt.Errorf("INSERT has been deprecated. Please use ADD instead")
|
| 324 | 324 |
} |
| ... | ... |
@@ -20,11 +20,9 @@ |
| 20 | 20 |
package builder |
| 21 | 21 |
|
| 22 | 22 |
import ( |
| 23 |
- "bytes" |
|
| 24 | 23 |
"errors" |
| 25 | 24 |
"fmt" |
| 26 | 25 |
"io" |
| 27 |
- "io/ioutil" |
|
| 28 | 26 |
"os" |
| 29 | 27 |
"path" |
| 30 | 28 |
"strings" |
| ... | ... |
@@ -42,10 +40,10 @@ var ( |
| 42 | 42 |
ErrDockerfileEmpty = errors.New("Dockerfile cannot be empty")
|
| 43 | 43 |
) |
| 44 | 44 |
|
| 45 |
-var evaluateTable map[string]func(*BuildFile, []string, map[string]bool) error |
|
| 45 |
+var evaluateTable map[string]func(*Builder, []string, map[string]bool) error |
|
| 46 | 46 |
|
| 47 | 47 |
func init() {
|
| 48 |
- evaluateTable = map[string]func(*BuildFile, []string, map[string]bool) error{
|
|
| 48 |
+ evaluateTable = map[string]func(*Builder, []string, map[string]bool) error{
|
|
| 49 | 49 |
"env": env, |
| 50 | 50 |
"maintainer": maintainer, |
| 51 | 51 |
"add": add, |
| ... | ... |
@@ -66,23 +64,7 @@ func init() {
|
| 66 | 66 |
|
| 67 | 67 |
// internal struct, used to maintain configuration of the Dockerfile's |
| 68 | 68 |
// processing as it evaluates the parsing result. |
| 69 |
-type BuildFile struct {
|
|
| 70 |
- Dockerfile *parser.Node // the syntax tree of the dockerfile |
|
| 71 |
- Config *runconfig.Config // runconfig for cmd, run, entrypoint etc. |
|
| 72 |
- Options *BuildOpts // see below |
|
| 73 |
- |
|
| 74 |
- // both of these are controlled by the Remove and ForceRemove options in BuildOpts |
|
| 75 |
- TmpContainers map[string]struct{} // a map of containers used for removes
|
|
| 76 |
- |
|
| 77 |
- image string // image name for commit processing |
|
| 78 |
- maintainer string // maintainer name. could probably be removed. |
|
| 79 |
- cmdSet bool // indicates is CMD was set in current Dockerfile |
|
| 80 |
- context *tarsum.TarSum // the context is a tarball that is uploaded by the client |
|
| 81 |
- contextPath string // the path of the temporary directory the local context is unpacked to (server side) |
|
| 82 |
- |
|
| 83 |
-} |
|
| 84 |
- |
|
| 85 |
-type BuildOpts struct {
|
|
| 69 |
+type Builder struct {
|
|
| 86 | 70 |
Daemon *daemon.Daemon |
| 87 | 71 |
Engine *engine.Engine |
| 88 | 72 |
|
| ... | ... |
@@ -104,6 +86,19 @@ type BuildOpts struct {
|
| 104 | 104 |
// Deprecated, original writer used for ImagePull. To be removed. |
| 105 | 105 |
OutOld io.Writer |
| 106 | 106 |
StreamFormatter *utils.StreamFormatter |
| 107 |
+ |
|
| 108 |
+ Config *runconfig.Config // runconfig for cmd, run, entrypoint etc. |
|
| 109 |
+ |
|
| 110 |
+ // both of these are controlled by the Remove and ForceRemove options in BuildOpts |
|
| 111 |
+ TmpContainers map[string]struct{} // a map of containers used for removes
|
|
| 112 |
+ |
|
| 113 |
+ dockerfile *parser.Node // the syntax tree of the dockerfile |
|
| 114 |
+ image string // image name for commit processing |
|
| 115 |
+ maintainer string // maintainer name. could probably be removed. |
|
| 116 |
+ cmdSet bool // indicates is CMD was set in current Dockerfile |
|
| 117 |
+ context *tarsum.TarSum // the context is a tarball that is uploaded by the client |
|
| 118 |
+ contextPath string // the path of the temporary directory the local context is unpacked to (server side) |
|
| 119 |
+ |
|
| 107 | 120 |
} |
| 108 | 121 |
|
| 109 | 122 |
// Run the builder with the context. This is the lynchpin of this package. This |
| ... | ... |
@@ -118,38 +113,48 @@ type BuildOpts struct {
|
| 118 | 118 |
// processing. |
| 119 | 119 |
// * Print a happy message and return the image ID. |
| 120 | 120 |
// |
| 121 |
-func (b *BuildFile) Run(context io.Reader) (string, error) {
|
|
| 121 |
+func (b *Builder) Run(context io.Reader) (string, error) {
|
|
| 122 | 122 |
if err := b.readContext(context); err != nil {
|
| 123 | 123 |
return "", err |
| 124 | 124 |
} |
| 125 | 125 |
|
| 126 | 126 |
filename := path.Join(b.contextPath, "Dockerfile") |
| 127 |
- if _, err := os.Stat(filename); os.IsNotExist(err) {
|
|
| 127 |
+ |
|
| 128 |
+ fi, err := os.Stat(filename) |
|
| 129 |
+ if os.IsNotExist(err) {
|
|
| 128 | 130 |
return "", fmt.Errorf("Cannot build a directory without a Dockerfile")
|
| 129 | 131 |
} |
| 130 |
- fileBytes, err := ioutil.ReadFile(filename) |
|
| 132 |
+ if fi.Size() == 0 {
|
|
| 133 |
+ return "", ErrDockerfileEmpty |
|
| 134 |
+ } |
|
| 135 |
+ |
|
| 136 |
+ f, err := os.Open(filename) |
|
| 131 | 137 |
if err != nil {
|
| 132 | 138 |
return "", err |
| 133 | 139 |
} |
| 134 |
- if len(fileBytes) == 0 {
|
|
| 135 |
- return "", ErrDockerfileEmpty |
|
| 136 |
- } |
|
| 137 |
- ast, err := parser.Parse(bytes.NewReader(fileBytes)) |
|
| 140 |
+ |
|
| 141 |
+ defer f.Close() |
|
| 142 |
+ |
|
| 143 |
+ ast, err := parser.Parse(f) |
|
| 138 | 144 |
if err != nil {
|
| 139 | 145 |
return "", err |
| 140 | 146 |
} |
| 141 | 147 |
|
| 142 |
- b.Dockerfile = ast |
|
| 148 |
+ b.dockerfile = ast |
|
| 149 |
+ |
|
| 150 |
+ // some initializations that would not have been supplied by the caller. |
|
| 151 |
+ b.Config = &runconfig.Config{}
|
|
| 152 |
+ b.TmpContainers = map[string]struct{}{}
|
|
| 143 | 153 |
|
| 144 |
- for i, n := range b.Dockerfile.Children {
|
|
| 154 |
+ for i, n := range b.dockerfile.Children {
|
|
| 145 | 155 |
if err := b.dispatch(i, n); err != nil {
|
| 146 |
- if b.Options.ForceRemove {
|
|
| 156 |
+ if b.ForceRemove {
|
|
| 147 | 157 |
b.clearTmp() |
| 148 | 158 |
} |
| 149 | 159 |
return "", err |
| 150 | 160 |
} |
| 151 |
- fmt.Fprintf(b.Options.OutStream, " ---> %s\n", utils.TruncateID(b.image)) |
|
| 152 |
- if b.Options.Remove {
|
|
| 161 |
+ fmt.Fprintf(b.OutStream, " ---> %s\n", utils.TruncateID(b.image)) |
|
| 162 |
+ if b.Remove {
|
|
| 153 | 163 |
b.clearTmp() |
| 154 | 164 |
} |
| 155 | 165 |
} |
| ... | ... |
@@ -158,7 +163,7 @@ func (b *BuildFile) Run(context io.Reader) (string, error) {
|
| 158 | 158 |
return "", fmt.Errorf("No image was generated. Is your Dockerfile empty?\n")
|
| 159 | 159 |
} |
| 160 | 160 |
|
| 161 |
- fmt.Fprintf(b.Options.OutStream, "Successfully built %s\n", utils.TruncateID(b.image)) |
|
| 161 |
+ fmt.Fprintf(b.OutStream, "Successfully built %s\n", utils.TruncateID(b.image)) |
|
| 162 | 162 |
return b.image, nil |
| 163 | 163 |
} |
| 164 | 164 |
|
| ... | ... |
@@ -168,7 +173,7 @@ func (b *BuildFile) Run(context io.Reader) (string, error) {
|
| 168 | 168 |
// Child[Node, Node, Node] where Child is from parser.Node.Children and each |
| 169 | 169 |
// node comes from parser.Node.Next. This forms a "line" with a statement and |
| 170 | 170 |
// arguments and we process them in this normalized form by hitting |
| 171 |
-// evaluateTable with the leaf nodes of the command and the BuildFile object. |
|
| 171 |
+// evaluateTable with the leaf nodes of the command and the Builder object. |
|
| 172 | 172 |
// |
| 173 | 173 |
// ONBUILD is a special case; in this case the parser will emit: |
| 174 | 174 |
// Child[Node, Child[Node, Node...]] where the first node is the literal |
| ... | ... |
@@ -176,14 +181,13 @@ func (b *BuildFile) Run(context io.Reader) (string, error) {
|
| 176 | 176 |
// such as `RUN` in ONBUILD RUN foo. There is special case logic in here to |
| 177 | 177 |
// deal with that, at least until it becomes more of a general concern with new |
| 178 | 178 |
// features. |
| 179 |
-func (b *BuildFile) dispatch(stepN int, ast *parser.Node) error {
|
|
| 179 |
+func (b *Builder) dispatch(stepN int, ast *parser.Node) error {
|
|
| 180 | 180 |
cmd := ast.Value |
| 181 | 181 |
attrs := ast.Attributes |
| 182 | 182 |
strs := []string{}
|
| 183 | 183 |
msg := fmt.Sprintf("Step %d : %s", stepN, strings.ToUpper(cmd))
|
| 184 | 184 |
|
| 185 | 185 |
if cmd == "onbuild" {
|
| 186 |
- fmt.Fprintf(b.Options.OutStream, "%#v\n", ast.Next.Children[0].Value) |
|
| 187 | 186 |
ast = ast.Next.Children[0] |
| 188 | 187 |
strs = append(strs, b.replaceEnv(ast.Value)) |
| 189 | 188 |
msg += " " + ast.Value |
| ... | ... |
@@ -195,7 +199,7 @@ func (b *BuildFile) dispatch(stepN int, ast *parser.Node) error {
|
| 195 | 195 |
msg += " " + ast.Value |
| 196 | 196 |
} |
| 197 | 197 |
|
| 198 |
- fmt.Fprintf(b.Options.OutStream, "%s\n", msg) |
|
| 198 |
+ fmt.Fprintln(b.OutStream, msg) |
|
| 199 | 199 |
|
| 200 | 200 |
// XXX yes, we skip any cmds that are not valid; the parser should have |
| 201 | 201 |
// picked these out already. |
| ... | ... |
@@ -203,7 +207,7 @@ func (b *BuildFile) dispatch(stepN int, ast *parser.Node) error {
|
| 203 | 203 |
return f(b, strs, attrs) |
| 204 | 204 |
} |
| 205 | 205 |
|
| 206 |
- fmt.Fprintf(b.Options.ErrStream, "# Skipping unknown instruction %s\n", strings.ToUpper(cmd)) |
|
| 206 |
+ fmt.Fprintf(b.ErrStream, "# Skipping unknown instruction %s\n", strings.ToUpper(cmd)) |
|
| 207 | 207 |
|
| 208 | 208 |
return nil |
| 209 | 209 |
} |
| ... | ... |
@@ -30,7 +30,7 @@ import ( |
| 30 | 30 |
"github.com/docker/docker/utils" |
| 31 | 31 |
) |
| 32 | 32 |
|
| 33 |
-func (b *BuildFile) readContext(context io.Reader) error {
|
|
| 33 |
+func (b *Builder) readContext(context io.Reader) error {
|
|
| 34 | 34 |
tmpdirPath, err := ioutil.TempDir("", "docker-build")
|
| 35 | 35 |
if err != nil {
|
| 36 | 36 |
return err |
| ... | ... |
@@ -50,7 +50,7 @@ func (b *BuildFile) readContext(context io.Reader) error {
|
| 50 | 50 |
return nil |
| 51 | 51 |
} |
| 52 | 52 |
|
| 53 |
-func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
|
|
| 53 |
+func (b *Builder) commit(id string, autoCmd []string, comment string) error {
|
|
| 54 | 54 |
if b.image == "" {
|
| 55 | 55 |
return fmt.Errorf("Please provide a source image with `from` prior to commit")
|
| 56 | 56 |
} |
| ... | ... |
@@ -68,15 +68,15 @@ func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
|
| 68 | 68 |
return nil |
| 69 | 69 |
} |
| 70 | 70 |
|
| 71 |
- container, warnings, err := b.Options.Daemon.Create(b.Config, "") |
|
| 71 |
+ container, warnings, err := b.Daemon.Create(b.Config, "") |
|
| 72 | 72 |
if err != nil {
|
| 73 | 73 |
return err |
| 74 | 74 |
} |
| 75 | 75 |
for _, warning := range warnings {
|
| 76 |
- fmt.Fprintf(b.Options.OutStream, " ---> [Warning] %s\n", warning) |
|
| 76 |
+ fmt.Fprintf(b.OutStream, " ---> [Warning] %s\n", warning) |
|
| 77 | 77 |
} |
| 78 | 78 |
b.TmpContainers[container.ID] = struct{}{}
|
| 79 |
- fmt.Fprintf(b.Options.OutStream, " ---> Running in %s\n", utils.TruncateID(container.ID)) |
|
| 79 |
+ fmt.Fprintf(b.OutStream, " ---> Running in %s\n", utils.TruncateID(container.ID)) |
|
| 80 | 80 |
id = container.ID |
| 81 | 81 |
|
| 82 | 82 |
if err := container.Mount(); err != nil {
|
| ... | ... |
@@ -84,7 +84,7 @@ func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
|
| 84 | 84 |
} |
| 85 | 85 |
defer container.Unmount() |
| 86 | 86 |
} |
| 87 |
- container := b.Options.Daemon.Get(id) |
|
| 87 |
+ container := b.Daemon.Get(id) |
|
| 88 | 88 |
if container == nil {
|
| 89 | 89 |
return fmt.Errorf("An error occured while creating the container")
|
| 90 | 90 |
} |
| ... | ... |
@@ -93,7 +93,7 @@ func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
|
| 93 | 93 |
autoConfig := *b.Config |
| 94 | 94 |
autoConfig.Cmd = autoCmd |
| 95 | 95 |
// Commit the container |
| 96 |
- image, err := b.Options.Daemon.Commit(container, "", "", "", b.maintainer, true, &autoConfig) |
|
| 96 |
+ image, err := b.Daemon.Commit(container, "", "", "", b.maintainer, true, &autoConfig) |
|
| 97 | 97 |
if err != nil {
|
| 98 | 98 |
return err |
| 99 | 99 |
} |
| ... | ... |
@@ -101,7 +101,7 @@ func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
|
| 101 | 101 |
return nil |
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 |
-func (b *BuildFile) runContextCommand(args []string, allowRemote bool, allowDecompression bool, cmdName string) error {
|
|
| 104 |
+func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecompression bool, cmdName string) error {
|
|
| 105 | 105 |
if b.context == nil {
|
| 106 | 106 |
return fmt.Errorf("No context given. Impossible to use %s", cmdName)
|
| 107 | 107 |
} |
| ... | ... |
@@ -200,7 +200,7 @@ func (b *BuildFile) runContextCommand(args []string, allowRemote bool, allowDeco |
| 200 | 200 |
} |
| 201 | 201 |
|
| 202 | 202 |
// Hash path and check the cache |
| 203 |
- if b.Options.UtilizeCache {
|
|
| 203 |
+ if b.UtilizeCache {
|
|
| 204 | 204 |
var ( |
| 205 | 205 |
hash string |
| 206 | 206 |
sums = b.context.GetSums() |
| ... | ... |
@@ -244,7 +244,7 @@ func (b *BuildFile) runContextCommand(args []string, allowRemote bool, allowDeco |
| 244 | 244 |
} |
| 245 | 245 |
|
| 246 | 246 |
// Create the container |
| 247 |
- container, _, err := b.Options.Daemon.Create(b.Config, "") |
|
| 247 |
+ container, _, err := b.Daemon.Create(b.Config, "") |
|
| 248 | 248 |
if err != nil {
|
| 249 | 249 |
return err |
| 250 | 250 |
} |
| ... | ... |
@@ -268,27 +268,27 @@ func (b *BuildFile) runContextCommand(args []string, allowRemote bool, allowDeco |
| 268 | 268 |
return nil |
| 269 | 269 |
} |
| 270 | 270 |
|
| 271 |
-func (b *BuildFile) pullImage(name string) (*imagepkg.Image, error) {
|
|
| 271 |
+func (b *Builder) pullImage(name string) (*imagepkg.Image, error) {
|
|
| 272 | 272 |
remote, tag := parsers.ParseRepositoryTag(name) |
| 273 |
- pullRegistryAuth := b.Options.AuthConfig |
|
| 274 |
- if len(b.Options.AuthConfigFile.Configs) > 0 {
|
|
| 273 |
+ pullRegistryAuth := b.AuthConfig |
|
| 274 |
+ if len(b.AuthConfigFile.Configs) > 0 {
|
|
| 275 | 275 |
// The request came with a full auth config file, we prefer to use that |
| 276 | 276 |
endpoint, _, err := registry.ResolveRepositoryName(remote) |
| 277 | 277 |
if err != nil {
|
| 278 | 278 |
return nil, err |
| 279 | 279 |
} |
| 280 |
- resolvedAuth := b.Options.AuthConfigFile.ResolveAuthConfig(endpoint) |
|
| 280 |
+ resolvedAuth := b.AuthConfigFile.ResolveAuthConfig(endpoint) |
|
| 281 | 281 |
pullRegistryAuth = &resolvedAuth |
| 282 | 282 |
} |
| 283 |
- job := b.Options.Engine.Job("pull", remote, tag)
|
|
| 284 |
- job.SetenvBool("json", b.Options.StreamFormatter.Json())
|
|
| 283 |
+ job := b.Engine.Job("pull", remote, tag)
|
|
| 284 |
+ job.SetenvBool("json", b.StreamFormatter.Json())
|
|
| 285 | 285 |
job.SetenvBool("parallel", true)
|
| 286 | 286 |
job.SetenvJson("authConfig", pullRegistryAuth)
|
| 287 |
- job.Stdout.Add(b.Options.OutOld) |
|
| 287 |
+ job.Stdout.Add(b.OutOld) |
|
| 288 | 288 |
if err := job.Run(); err != nil {
|
| 289 | 289 |
return nil, err |
| 290 | 290 |
} |
| 291 |
- image, err := b.Options.Daemon.Repositories().LookupImage(name) |
|
| 291 |
+ image, err := b.Daemon.Repositories().LookupImage(name) |
|
| 292 | 292 |
if err != nil {
|
| 293 | 293 |
return nil, err |
| 294 | 294 |
} |
| ... | ... |
@@ -296,7 +296,7 @@ func (b *BuildFile) pullImage(name string) (*imagepkg.Image, error) {
|
| 296 | 296 |
return image, nil |
| 297 | 297 |
} |
| 298 | 298 |
|
| 299 |
-func (b *BuildFile) processImageFrom(img *imagepkg.Image) error {
|
|
| 299 |
+func (b *Builder) processImageFrom(img *imagepkg.Image) error {
|
|
| 300 | 300 |
b.image = img.ID |
| 301 | 301 |
|
| 302 | 302 |
if img.Config != nil {
|
| ... | ... |
@@ -309,7 +309,7 @@ func (b *BuildFile) processImageFrom(img *imagepkg.Image) error {
|
| 309 | 309 |
|
| 310 | 310 |
// Process ONBUILD triggers if they exist |
| 311 | 311 |
if nTriggers := len(b.Config.OnBuild); nTriggers != 0 {
|
| 312 |
- fmt.Fprintf(b.Options.ErrStream, "# Executing %d build triggers\n", nTriggers) |
|
| 312 |
+ fmt.Fprintf(b.ErrStream, "# Executing %d build triggers\n", nTriggers) |
|
| 313 | 313 |
} |
| 314 | 314 |
|
| 315 | 315 |
// Copy the ONBUILD triggers, and remove them from the config, since the config will be commited. |
| ... | ... |
@@ -330,7 +330,8 @@ func (b *BuildFile) processImageFrom(img *imagepkg.Image) error {
|
| 330 | 330 |
} |
| 331 | 331 |
|
| 332 | 332 |
// FIXME we have to run the evaluator manually here. This does not belong |
| 333 |
- // in this function. |
|
| 333 |
+ // in this function. Once removed, the init() in evaluator.go should no |
|
| 334 |
+ // longer be necessary. |
|
| 334 | 335 |
|
| 335 | 336 |
if f, ok := evaluateTable[strings.ToLower(stepInstruction)]; ok {
|
| 336 | 337 |
if err := f(b, splitStep[1:], nil); err != nil {
|
| ... | ... |
@@ -344,17 +345,17 @@ func (b *BuildFile) processImageFrom(img *imagepkg.Image) error {
|
| 344 | 344 |
return nil |
| 345 | 345 |
} |
| 346 | 346 |
|
| 347 |
-// probeCache checks to see if image-caching is enabled (`b.Options.UtilizeCache`) |
|
| 347 |
+// probeCache checks to see if image-caching is enabled (`b.UtilizeCache`) |
|
| 348 | 348 |
// and if so attempts to look up the current `b.image` and `b.Config` pair |
| 349 |
-// in the current server `b.Options.Daemon`. If an image is found, probeCache returns |
|
| 349 |
+// in the current server `b.Daemon`. If an image is found, probeCache returns |
|
| 350 | 350 |
// `(true, nil)`. If no image is found, it returns `(false, nil)`. If there |
| 351 | 351 |
// is any error, it returns `(false, err)`. |
| 352 |
-func (b *BuildFile) probeCache() (bool, error) {
|
|
| 353 |
- if b.Options.UtilizeCache {
|
|
| 354 |
- if cache, err := b.Options.Daemon.ImageGetCached(b.image, b.Config); err != nil {
|
|
| 352 |
+func (b *Builder) probeCache() (bool, error) {
|
|
| 353 |
+ if b.UtilizeCache {
|
|
| 354 |
+ if cache, err := b.Daemon.ImageGetCached(b.image, b.Config); err != nil {
|
|
| 355 | 355 |
return false, err |
| 356 | 356 |
} else if cache != nil {
|
| 357 |
- fmt.Fprintf(b.Options.OutStream, " ---> Using cache\n") |
|
| 357 |
+ fmt.Fprintf(b.OutStream, " ---> Using cache\n") |
|
| 358 | 358 |
log.Debugf("[BUILDER] Use cached version")
|
| 359 | 359 |
b.image = cache.ID |
| 360 | 360 |
return true, nil |
| ... | ... |
@@ -365,19 +366,20 @@ func (b *BuildFile) probeCache() (bool, error) {
|
| 365 | 365 |
return false, nil |
| 366 | 366 |
} |
| 367 | 367 |
|
| 368 |
-func (b *BuildFile) create() (*daemon.Container, error) {
|
|
| 368 |
+func (b *Builder) create() (*daemon.Container, error) {
|
|
| 369 | 369 |
if b.image == "" {
|
| 370 | 370 |
return nil, fmt.Errorf("Please provide a source image with `from` prior to run")
|
| 371 | 371 |
} |
| 372 | 372 |
b.Config.Image = b.image |
| 373 | 373 |
|
| 374 | 374 |
// Create the container |
| 375 |
- c, _, err := b.Options.Daemon.Create(b.Config, "") |
|
| 375 |
+ c, _, err := b.Daemon.Create(b.Config, "") |
|
| 376 | 376 |
if err != nil {
|
| 377 | 377 |
return nil, err |
| 378 | 378 |
} |
| 379 |
+ |
|
| 379 | 380 |
b.TmpContainers[c.ID] = struct{}{}
|
| 380 |
- fmt.Fprintf(b.Options.OutStream, " ---> Running in %s\n", utils.TruncateID(c.ID)) |
|
| 381 |
+ fmt.Fprintf(b.OutStream, " ---> Running in %s\n", utils.TruncateID(c.ID)) |
|
| 381 | 382 |
|
| 382 | 383 |
// override the entry point that may have been picked up from the base image |
| 383 | 384 |
c.Path = b.Config.Cmd[0] |
| ... | ... |
@@ -386,16 +388,16 @@ func (b *BuildFile) create() (*daemon.Container, error) {
|
| 386 | 386 |
return c, nil |
| 387 | 387 |
} |
| 388 | 388 |
|
| 389 |
-func (b *BuildFile) run(c *daemon.Container) error {
|
|
| 389 |
+func (b *Builder) run(c *daemon.Container) error {
|
|
| 390 | 390 |
var errCh chan error |
| 391 |
- if b.Options.Verbose {
|
|
| 391 |
+ if b.Verbose {
|
|
| 392 | 392 |
errCh = utils.Go(func() error {
|
| 393 | 393 |
// FIXME: call the 'attach' job so that daemon.Attach can be made private |
| 394 | 394 |
// |
| 395 | 395 |
// FIXME (LK4D4): Also, maybe makes sense to call "logs" job, it is like attach |
| 396 | 396 |
// but without hijacking for stdin. Also, with attach there can be race |
| 397 | 397 |
// condition because of some output already was printed before it. |
| 398 |
- return <-b.Options.Daemon.Attach(c, nil, nil, b.Options.OutStream, b.Options.ErrStream) |
|
| 398 |
+ return <-b.Daemon.Attach(c, nil, nil, b.OutStream, b.ErrStream) |
|
| 399 | 399 |
}) |
| 400 | 400 |
} |
| 401 | 401 |
|
| ... | ... |
@@ -422,7 +424,7 @@ func (b *BuildFile) run(c *daemon.Container) error {
|
| 422 | 422 |
return nil |
| 423 | 423 |
} |
| 424 | 424 |
|
| 425 |
-func (b *BuildFile) checkPathForAddition(orig string) error {
|
|
| 425 |
+func (b *Builder) checkPathForAddition(orig string) error {
|
|
| 426 | 426 |
origPath := path.Join(b.contextPath, orig) |
| 427 | 427 |
origPath, err := filepath.EvalSymlinks(origPath) |
| 428 | 428 |
if err != nil {
|
| ... | ... |
@@ -443,7 +445,7 @@ func (b *BuildFile) checkPathForAddition(orig string) error {
|
| 443 | 443 |
return nil |
| 444 | 444 |
} |
| 445 | 445 |
|
| 446 |
-func (b *BuildFile) addContext(container *daemon.Container, orig, dest string, decompress bool) error {
|
|
| 446 |
+func (b *Builder) addContext(container *daemon.Container, orig, dest string, decompress bool) error {
|
|
| 447 | 447 |
var ( |
| 448 | 448 |
err error |
| 449 | 449 |
destExists = true |
| ... | ... |
@@ -548,14 +550,14 @@ func fixPermissions(destination string, uid, gid int) error {
|
| 548 | 548 |
}) |
| 549 | 549 |
} |
| 550 | 550 |
|
| 551 |
-func (b *BuildFile) clearTmp() {
|
|
| 551 |
+func (b *Builder) clearTmp() {
|
|
| 552 | 552 |
for c := range b.TmpContainers {
|
| 553 |
- tmp := b.Options.Daemon.Get(c) |
|
| 554 |
- if err := b.Options.Daemon.Destroy(tmp); err != nil {
|
|
| 555 |
- fmt.Fprintf(b.Options.OutStream, "Error removing intermediate container %s: %s\n", utils.TruncateID(c), err.Error()) |
|
| 553 |
+ tmp := b.Daemon.Get(c) |
|
| 554 |
+ if err := b.Daemon.Destroy(tmp); err != nil {
|
|
| 555 |
+ fmt.Fprintf(b.OutStream, "Error removing intermediate container %s: %s\n", utils.TruncateID(c), err.Error()) |
|
| 556 | 556 |
} else {
|
| 557 | 557 |
delete(b.TmpContainers, c) |
| 558 |
- fmt.Fprintf(b.Options.OutStream, "Removing intermediate container %s\n", utils.TruncateID(c)) |
|
| 558 |
+ fmt.Fprintf(b.OutStream, "Removing intermediate container %s\n", utils.TruncateID(c)) |
|
| 559 | 559 |
} |
| 560 | 560 |
} |
| 561 | 561 |
} |
| ... | ... |
@@ -85,7 +85,7 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) engine.Status {
|
| 85 | 85 |
|
| 86 | 86 |
sf := utils.NewStreamFormatter(job.GetenvBool("json"))
|
| 87 | 87 |
|
| 88 |
- opts := &BuildOpts{
|
|
| 88 |
+ builder := &Builder{
|
|
| 89 | 89 |
Daemon: b.Daemon, |
| 90 | 90 |
Engine: b.Engine, |
| 91 | 91 |
OutStream: &utils.StdoutFormater{
|
| ... | ... |
@@ -106,7 +106,7 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) engine.Status {
|
| 106 | 106 |
AuthConfigFile: configFile, |
| 107 | 107 |
} |
| 108 | 108 |
|
| 109 |
- id, err := NewBuilder(opts).Run(context) |
|
| 109 |
+ id, err := builder.Run(context) |
|
| 110 | 110 |
if err != nil {
|
| 111 | 111 |
return job.Error(err) |
| 112 | 112 |
} |
| ... | ... |
@@ -10,7 +10,7 @@ var ( |
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 | 12 |
// handle environment replacement. Used in dispatcher. |
| 13 |
-func (b *BuildFile) replaceEnv(str string) string {
|
|
| 13 |
+func (b *Builder) replaceEnv(str string) string {
|
|
| 14 | 14 |
for _, match := range TOKEN_ENV_INTERPOLATION.FindAllString(str, -1) {
|
| 15 | 15 |
match = match[strings.Index(match, "$"):] |
| 16 | 16 |
matchKey := strings.Trim(match, "${}")
|