mirror of https://github.com/docker/docs.git
Merge pull request #1310 from pwnall/image_affinity
Swarm filters support in image building
This commit is contained in:
commit
da1f854462
|
@ -118,7 +118,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/samalba/dockerclient",
|
"ImportPath": "github.com/samalba/dockerclient",
|
||||||
"Rev": "9ca0fce3c63569ee27457cd8bcf1f4f08e6d9459"
|
"Rev": "a3241e22d7230854778614ebca9c7f869776c5f0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/samuel/go-zookeeper/zk",
|
"ImportPath": "github.com/samuel/go-zookeeper/zk",
|
||||||
|
|
|
@ -760,6 +760,13 @@ func (client *DockerClient) BuildImage(image *BuildImage) (io.ReadCloser, error)
|
||||||
v.Set("cpusetcpus", image.CpuSetCpus)
|
v.Set("cpusetcpus", image.CpuSetCpus)
|
||||||
v.Set("cpusetmems", image.CpuSetMems)
|
v.Set("cpusetmems", image.CpuSetMems)
|
||||||
v.Set("cgroupparent", image.CgroupParent)
|
v.Set("cgroupparent", image.CgroupParent)
|
||||||
|
if image.BuildArgs != nil {
|
||||||
|
buildArgsJSON, err := json.Marshal(image.BuildArgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
v.Set("buildargs", string(buildArgsJSON))
|
||||||
|
}
|
||||||
|
|
||||||
headers := make(map[string]string)
|
headers := make(map[string]string)
|
||||||
if image.Config != nil {
|
if image.Config != nil {
|
||||||
|
|
|
@ -450,6 +450,7 @@ type BuildImage struct {
|
||||||
CpuSetCpus string
|
CpuSetCpus string
|
||||||
CpuSetMems string
|
CpuSetMems string
|
||||||
CgroupParent string
|
CgroupParent string
|
||||||
|
BuildArgs map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
|
|
|
@ -928,6 +928,12 @@ func postBuild(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
CpuSetMems: r.Form.Get("cpusetmems"),
|
CpuSetMems: r.Form.Get("cpusetmems"),
|
||||||
CgroupParent: r.Form.Get("cgroupparent"),
|
CgroupParent: r.Form.Get("cgroupparent"),
|
||||||
Context: r.Body,
|
Context: r.Body,
|
||||||
|
BuildArgs: make(map[string]string),
|
||||||
|
}
|
||||||
|
|
||||||
|
buildArgsJSON := r.Form.Get("buildargs")
|
||||||
|
if buildArgsJSON != "" {
|
||||||
|
json.Unmarshal([]byte(buildArgsJSON), &buildImage.BuildArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
authEncoded := r.Header.Get("X-Registry-Auth")
|
authEncoded := r.Header.Get("X-Registry-Auth")
|
||||||
|
|
|
@ -771,10 +771,12 @@ func (c *Cluster) BuildImage(buildImage *dockerclient.BuildImage, out io.Writer)
|
||||||
c.scheduler.Lock()
|
c.scheduler.Lock()
|
||||||
|
|
||||||
// get an engine
|
// get an engine
|
||||||
config := &cluster.ContainerConfig{dockerclient.ContainerConfig{
|
config := cluster.BuildContainerConfig(dockerclient.ContainerConfig{
|
||||||
CpuShares: buildImage.CpuShares,
|
CpuShares: buildImage.CpuShares,
|
||||||
Memory: buildImage.Memory,
|
Memory: buildImage.Memory,
|
||||||
}}
|
Env: convertMapToKVStrings(buildImage.BuildArgs),
|
||||||
|
})
|
||||||
|
buildImage.BuildArgs = convertKVStringsToMap(config.Env)
|
||||||
nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config)
|
nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config)
|
||||||
c.scheduler.Unlock()
|
c.scheduler.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package swarm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// convertKVStringsToMap converts ["key=value"] to {"key":"value"}
|
||||||
|
func convertKVStringsToMap(values []string) map[string]string {
|
||||||
|
result := make(map[string]string, len(values))
|
||||||
|
for _, value := range values {
|
||||||
|
kv := strings.SplitN(value, "=", 2)
|
||||||
|
if len(kv) == 1 {
|
||||||
|
result[kv[0]] = ""
|
||||||
|
} else {
|
||||||
|
result[kv[0]] = kv[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertMapToKVStrings converts {"key": "value"} to ["key=value"]
|
||||||
|
func convertMapToKVStrings(values map[string]string) []string {
|
||||||
|
result := make([]string, len(values))
|
||||||
|
i := 0
|
||||||
|
for key, value := range values {
|
||||||
|
result[i] = key + "=" + value
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package swarm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConvertKVStringsToMap(t *testing.T) {
|
||||||
|
result := convertKVStringsToMap([]string{"HELLO=WORLD", "a=b=c=d", "e"})
|
||||||
|
expected := map[string]string{"HELLO": "WORLD", "a": "b=c=d", "e": ""}
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertMapToKVStrings(t *testing.T) {
|
||||||
|
result := convertMapToKVStrings(map[string]string{"HELLO": "WORLD", "a": "b=c=d", "e": ""})
|
||||||
|
sort.Strings(result)
|
||||||
|
expected := []string{"HELLO=WORLD", "a=b=c=d", "e="}
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
}
|
|
@ -21,3 +21,15 @@ function teardown() {
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
[ "${#lines[@]}" -eq 1 ]
|
[ "${#lines[@]}" -eq 1 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "docker build with arg" {
|
||||||
|
start_docker_with_busybox 2
|
||||||
|
swarm_manage
|
||||||
|
|
||||||
|
run docker_swarm build -t test_args --build-arg="greeting=Hello Args" $TESTDATA/build_with_args
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run docker_swarm run --rm test_args
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "$output" == "Hello Args" ]]
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load helpers
|
||||||
|
|
||||||
|
function teardown() {
|
||||||
|
swarm_manage_cleanup
|
||||||
|
stop_docker
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "build with impossible node constraint" {
|
||||||
|
start_docker 2
|
||||||
|
swarm_manage
|
||||||
|
|
||||||
|
run docker_swarm images -q
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ "${#lines[@]}" -eq 0 ]
|
||||||
|
|
||||||
|
run docker_swarm build --build-arg="constraint:node==node-9" $TESTDATA/build
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
[[ "$output" == *"Error response from daemon: unable to find a node that satisfies node==node-9"* ]]
|
||||||
|
|
||||||
|
run docker_swarm images -q
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ "${#lines[@]}" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "build with node constraint and buildarg" {
|
||||||
|
start_docker_with_busybox 2
|
||||||
|
swarm_manage
|
||||||
|
|
||||||
|
run docker_swarm build -t test_args --build-arg="greeting=Hello Args" --build-arg="constraint:node==node-1" $TESTDATA/build_with_args
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run docker_swarm run --name c1 test_args
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "$output" == "Hello Args" ]]
|
||||||
|
|
||||||
|
run docker_swarm inspect c1
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "${output}" == *'"Name": "node-1"'* ]]
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
FROM busybox:latest
|
||||||
|
ARG greeting=hello
|
||||||
|
ENV GREETING=$greeting
|
||||||
|
CMD ["/bin/sh", "-c", "echo -n \"$GREETING\""]
|
Loading…
Reference in New Issue