Skip to content

Commit cdfdfbf

Browse files
rhatdanibuildthecloud
authored andcommitted
Allow specification of Label Name/Value pairs in image json content
Save "LABEL" field in Dockerfile into image content. This will allow a user to save user data into an image, which can later be retrieved using: docker inspect IMAGEID I have copied this from the "Comment" handling in docker images. We want to be able to add Name/Value data to an image to describe the image, and then be able to use other tools to look at this data, to be able to do security checks based on this data. We are thinking about adding version names, Perhaps listing the content of the dockerfile. Descriptions of where the code came from etc. This LABEL field should also be allowed to be specified in the docker import --change LABEL:Name=Value docker commit --change LABEL:Name=Value Docker-DCO-1.1-Signed-off-by: Dan Walsh <dwalsh@redhat.com> (github: rhatdan)
1 parent 6374c12 commit cdfdfbf

File tree

14 files changed

+113
-8
lines changed

14 files changed

+113
-8
lines changed

builder/command/command.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package command
33

44
const (
55
Env = "env"
6+
Label = "label"
67
Maintainer = "maintainer"
78
Add = "add"
89
Copy = "copy"

builder/dispatchers.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,37 @@ func maintainer(b *Builder, args []string, attributes map[string]bool, original
8585
return b.commit("", b.Config.Cmd, fmt.Sprintf("MAINTAINER %s", b.maintainer))
8686
}
8787

88+
// LABEL some json data describing the image
89+
//
90+
// Sets the Label variable foo to bar,
91+
//
92+
func label(b *Builder, args []string, attributes map[string]bool, original string) error {
93+
if len(args) == 0 {
94+
return fmt.Errorf("LABEL is missing arguments")
95+
}
96+
if len(args)%2 != 0 {
97+
// should never get here, but just in case
98+
return fmt.Errorf("Bad input to LABEL, too many args")
99+
}
100+
101+
commitStr := "LABEL"
102+
103+
if b.Config.Labels == nil {
104+
b.Config.Labels = map[string]string{}
105+
}
106+
107+
for j := 0; j < len(args); j++ {
108+
// name ==> args[j]
109+
// value ==> args[j+1]
110+
newVar := args[j] + "=" + args[j+1] + ""
111+
commitStr += " " + newVar
112+
113+
b.Config.Labels[args[j]] = args[j+1]
114+
j++
115+
}
116+
return b.commit("", b.Config.Cmd, commitStr)
117+
}
118+
88119
// ADD foo /path
89120
//
90121
// Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling

builder/evaluator.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ var evaluateTable map[string]func(*Builder, []string, map[string]bool, string) e
6262
func init() {
6363
evaluateTable = map[string]func(*Builder, []string, map[string]bool, string) error{
6464
command.Env: env,
65+
command.Label: label,
6566
command.Maintainer: maintainer,
6667
command.Add: add,
6768
command.Copy: dispatchCopy, // copy() is a go builtin

builder/parser/line_parsers.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ func parseSubCommand(rest string) (*Node, map[string]bool, error) {
4444

4545
// parse environment like statements. Note that this does *not* handle
4646
// variable interpolation, which will be handled in the evaluator.
47-
func parseEnv(rest string) (*Node, map[string]bool, error) {
47+
func parseNameVal(rest string, key string) (*Node, map[string]bool, error) {
4848
// This is kind of tricky because we need to support the old
49-
// variant: ENV name value
50-
// as well as the new one: ENV name=value ...
49+
// variant: KEY name value
50+
// as well as the new one: KEY name=value ...
5151
// The trigger to know which one is being used will be whether we hit
5252
// a space or = first. space ==> old, "=" ==> new
5353

@@ -137,10 +137,10 @@ func parseEnv(rest string) (*Node, map[string]bool, error) {
137137
}
138138

139139
if len(words) == 0 {
140-
return nil, nil, fmt.Errorf("ENV requires at least one argument")
140+
return nil, nil, fmt.Errorf(key + " requires at least one argument")
141141
}
142142

143-
// Old format (ENV name value)
143+
// Old format (KEY name value)
144144
var rootnode *Node
145145

146146
if !strings.Contains(words[0], "=") {
@@ -149,7 +149,7 @@ func parseEnv(rest string) (*Node, map[string]bool, error) {
149149
strs := TOKEN_WHITESPACE.Split(rest, 2)
150150

151151
if len(strs) < 2 {
152-
return nil, nil, fmt.Errorf("ENV must have two arguments")
152+
return nil, nil, fmt.Errorf(key + " must have two arguments")
153153
}
154154

155155
node.Value = strs[0]
@@ -182,6 +182,14 @@ func parseEnv(rest string) (*Node, map[string]bool, error) {
182182
return rootnode, nil, nil
183183
}
184184

185+
func parseEnv(rest string) (*Node, map[string]bool, error) {
186+
return parseNameVal(rest, "ENV")
187+
}
188+
189+
func parseLabel(rest string) (*Node, map[string]bool, error) {
190+
return parseNameVal(rest, "LABEL")
191+
}
192+
185193
// parses a whitespace-delimited set of arguments. The result is effectively a
186194
// linked list of string arguments.
187195
func parseStringsWhitespaceDelimited(rest string) (*Node, map[string]bool, error) {

builder/parser/parser.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func init() {
5050
command.Onbuild: parseSubCommand,
5151
command.Workdir: parseString,
5252
command.Env: parseEnv,
53+
command.Label: parseLabel,
5354
command.Maintainer: parseString,
5455
command.From: parseString,
5556
command.Add: parseMaybeJSONToList,

contrib/syntax/kate/Dockerfile.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<item> CMD </item>
2323
<item> WORKDIR </item>
2424
<item> USER </item>
25+
<item> LABEL </item>
2526
</list>
2627

2728
<contexts>

contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<array>
1313
<dict>
1414
<key>match</key>
15-
<string>^\s*(ONBUILD\s+)?(FROM|MAINTAINER|RUN|EXPOSE|ENV|ADD|VOLUME|USER|WORKDIR|COPY)\s</string>
15+
<string>^\s*(ONBUILD\s+)?(FROM|MAINTAINER|RUN|EXPOSE|ENV|ADD|VOLUME|USER|LABEL|WORKDIR|COPY)\s</string>
1616
<key>captures</key>
1717
<dict>
1818
<key>0</key>

contrib/syntax/vim/syntax/dockerfile.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let b:current_syntax = "dockerfile"
1111

1212
syntax case ignore
1313

14-
syntax match dockerfileKeyword /\v^\s*(ONBUILD\s+)?(ADD|CMD|ENTRYPOINT|ENV|EXPOSE|FROM|MAINTAINER|RUN|USER|VOLUME|WORKDIR|COPY)\s/
14+
syntax match dockerfileKeyword /\v^\s*(ONBUILD\s+)?(ADD|CMD|ENTRYPOINT|ENV|EXPOSE|FROM|MAINTAINER|RUN|USER|LABEL|VOLUME|WORKDIR|COPY)\s/
1515
highlight link dockerfileKeyword Keyword
1616

1717
syntax region dockerfileString start=/\v"/ skip=/\v\\./ end=/\v"/

docs/sources/reference/api/docker_remote_api.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ This endpoint now returns `SystemTime`, `HttpProxy`,`HttpsProxy` and `NoProxy`.
7171

7272
### What's new
7373

74+
**New!**
75+
Build now has support for `LABEL` command which can be used to add user data
76+
to an image. For example you could add data describing the content of an image.
77+
78+
`LABEL "Vendor"="ACME Incorporated"`
79+
80+
**New!**
7481
`POST /containers/(id)/attach` and `POST /exec/(id)/start`
7582

7683
**New!**

docs/sources/reference/api/docker_remote_api_v1.17.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ Create a container
129129
],
130130
"Entrypoint": "",
131131
"Image": "ubuntu",
132+
"Labels": {
133+
"Vendor": "Acme",
134+
"License": "GPL",
135+
"Version": "1.0"
136+
},
132137
"Volumes": {
133138
"/tmp": {}
134139
},
@@ -1169,6 +1174,7 @@ Return low-level information on the image `name`
11691174
"Cmd": ["/bin/bash"],
11701175
"Dns": null,
11711176
"Image": "ubuntu",
1177+
"Labels": null,
11721178
"Volumes": null,
11731179
"VolumesFrom": "",
11741180
"WorkingDir": ""

0 commit comments

Comments
 (0)