Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 1535bda

Browse files
authored
Merge pull request #512 from CpuID/cpuid_build_options
Extra options for "build" sections in YAML
2 parents a86fb3c + 249c5d2 commit 1535bda

File tree

4 files changed

+125
-9
lines changed

4 files changed

+125
-9
lines changed

config/schema.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,11 @@ var servicesSchemaDataV2 = `{
219219
"properties": {
220220
"context": {"type": "string"},
221221
"dockerfile": {"type": "string"},
222-
"args": {"$ref": "#/definitions/list_or_dict"}
222+
"args": {"$ref": "#/definitions/list_or_dict"},
223+
"cache_from": {"$ref": "#/definitions/list_of_strings"},
224+
"labels": {"$ref": "#/definitions/list_or_dict"},
225+
"network": {"type": "string"},
226+
"target": {"type": "string"}
223227
},
224228
"additionalProperties": false
225229
}

docker/builder/builder.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ type DaemonBuilder struct {
4343
Pull bool
4444
BuildArgs map[string]*string
4545
CacheFrom []string
46+
Labels map[string]*string
47+
Network string
48+
Target string
4649
LoggerFactory logger.Factory
4750
}
4851

@@ -88,6 +91,12 @@ func (d *DaemonBuilder) Build(ctx context.Context, imageName string) error {
8891
outFd, isTerminalOut = term.GetFdInfo(w)
8992
}
9093

94+
// Convert map[string]*string to map[string]string
95+
labels := make(map[string]string)
96+
for lk, lv := range d.Labels {
97+
labels[lk] = *lv
98+
}
99+
91100
response, err := d.Client.ImageBuild(ctx, body, types.ImageBuildOptions{
92101
Tags: []string{imageName},
93102
NoCache: d.NoCache,
@@ -98,6 +107,9 @@ func (d *DaemonBuilder) Build(ctx context.Context, imageName string) error {
98107
AuthConfigs: d.AuthConfigs,
99108
BuildArgs: d.BuildArgs,
100109
CacheFrom: d.CacheFrom,
110+
Labels: labels,
111+
NetworkMode: d.Network,
112+
Target: d.Target,
101113
})
102114
if err != nil {
103115
return err

yaml/build.go

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ type Build struct {
1313
Context string
1414
Dockerfile string
1515
Args map[string]*string
16+
CacheFrom []*string
17+
Labels map[string]*string
18+
// TODO: ShmSize (can be a string or int?) for v3.5
19+
Target string
20+
// Note: as of Sep 2018 this is undocumented but supported by docker-compose
21+
Network string
1622
}
1723

1824
// MarshalYAML implements the Marshaller interface.
@@ -27,6 +33,18 @@ func (b Build) MarshalYAML() (interface{}, error) {
2733
if len(b.Args) > 0 {
2834
m["args"] = b.Args
2935
}
36+
if len(b.CacheFrom) > 0 {
37+
m["cache_from"] = b.CacheFrom
38+
}
39+
if len(b.Labels) > 0 {
40+
m["labels"] = b.Labels
41+
}
42+
if b.Target != "" {
43+
m["target"] = b.Target
44+
}
45+
if b.Network != "" {
46+
m["network"] = b.Network
47+
}
3048
return m, nil
3149
}
3250

@@ -52,6 +70,22 @@ func (b *Build) UnmarshalYAML(unmarshal func(interface{}) error) error {
5270
return err
5371
}
5472
b.Args = args
73+
case "cache_from":
74+
cacheFrom, err := handleBuildCacheFrom(mapValue)
75+
if err != nil {
76+
return err
77+
}
78+
b.CacheFrom = cacheFrom
79+
case "labels":
80+
labels, err := handleBuildLabels(mapValue)
81+
if err != nil {
82+
return err
83+
}
84+
b.Labels = labels
85+
case "target":
86+
b.Target = mapValue.(string)
87+
case "network":
88+
b.Network = mapValue.(string)
5589
default:
5690
// Ignore unknown keys
5791
continue
@@ -67,15 +101,44 @@ func handleBuildArgs(value interface{}) (map[string]*string, error) {
67101
var args map[string]*string
68102
switch v := value.(type) {
69103
case map[interface{}]interface{}:
70-
return handleBuildArgMap(v)
104+
return handleBuildOptionMap(v)
71105
case []interface{}:
72-
return handleBuildArgSlice(v)
106+
return handleBuildArgsSlice(v)
73107
default:
74108
return args, fmt.Errorf("Failed to unmarshal Build args: %#v", value)
75109
}
76110
}
77111

78-
func handleBuildArgSlice(s []interface{}) (map[string]*string, error) {
112+
func handleBuildCacheFrom(value interface{}) ([]*string, error) {
113+
var cacheFrom []*string
114+
switch v := value.(type) {
115+
case []interface{}:
116+
return handleBuildCacheFromSlice(v)
117+
default:
118+
return cacheFrom, fmt.Errorf("Failed to unmarshal Build cache_from: %#v", value)
119+
}
120+
}
121+
122+
func handleBuildLabels(value interface{}) (map[string]*string, error) {
123+
var labels map[string]*string
124+
switch v := value.(type) {
125+
case map[interface{}]interface{}:
126+
return handleBuildOptionMap(v)
127+
default:
128+
return labels, fmt.Errorf("Failed to unmarshal Build labels: %#v", value)
129+
}
130+
}
131+
132+
func handleBuildCacheFromSlice(s []interface{}) ([]*string, error) {
133+
var args = []*string{}
134+
for _, arg := range s {
135+
strArg := arg.(string)
136+
args = append(args, &strArg)
137+
}
138+
return args, nil
139+
}
140+
141+
func handleBuildArgsSlice(s []interface{}) (map[string]*string, error) {
79142
var args = map[string]*string{}
80143
for _, arg := range s {
81144
// check if a value is provided
@@ -93,7 +156,8 @@ func handleBuildArgSlice(s []interface{}) (map[string]*string, error) {
93156
return args, nil
94157
}
95158

96-
func handleBuildArgMap(m map[interface{}]interface{}) (map[string]*string, error) {
159+
// Used for args and labels
160+
func handleBuildOptionMap(m map[interface{}]interface{}) (map[string]*string, error) {
97161
args := map[string]*string{}
98162
for mapKey, mapValue := range m {
99163
var argValue string

yaml/build_test.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import (
88
)
99

1010
var (
11-
buildno = "1"
12-
user = "vincent"
13-
empty = "\x00"
11+
buildno = "1"
12+
user = "vincent"
13+
empty = "\x00"
14+
testCacheFrom = "someotherimage:latest"
15+
target = "intermediateimage"
16+
network = "buildnetwork"
1417
)
1518

1619
func TestMarshalBuild(t *testing.T) {
@@ -46,12 +49,28 @@ dockerfile: alternate
4649
"buildno": &buildno,
4750
"user": &user,
4851
},
52+
CacheFrom: []*string{
53+
&testCacheFrom,
54+
},
55+
Labels: map[string]*string{
56+
"buildno": &buildno,
57+
"user": &user,
58+
},
59+
Target: target,
60+
Network: network,
4961
},
5062
expected: `args:
5163
buildno: "1"
5264
user: vincent
65+
cache_from:
66+
- someotherimage:latest
5367
context: .
5468
dockerfile: alternate
69+
labels:
70+
buildno: "1"
71+
user: vincent
72+
network: buildnetwork
73+
target: intermediateimage
5574
`,
5675
},
5776
}
@@ -92,14 +111,31 @@ dockerfile: alternate`,
92111
dockerfile: alternate
93112
args:
94113
buildno: 1
95-
user: vincent`,
114+
user: vincent
115+
cache_from:
116+
- someotherimage:latest
117+
labels:
118+
buildno: "1"
119+
user: vincent
120+
target: intermediateimage
121+
network: buildnetwork
122+
`,
96123
expected: &Build{
97124
Context: ".",
98125
Dockerfile: "alternate",
99126
Args: map[string]*string{
100127
"buildno": &buildno,
101128
"user": &user,
102129
},
130+
CacheFrom: []*string{
131+
&testCacheFrom,
132+
},
133+
Labels: map[string]*string{
134+
"buildno": &buildno,
135+
"user": &user,
136+
},
137+
Target: target,
138+
Network: network,
103139
},
104140
},
105141
{

0 commit comments

Comments
 (0)