diff --git a/cli/command/cli_test.go b/cli/command/cli_test.go index 48a87d1bfb..432e653fdc 100644 --- a/cli/command/cli_test.go +++ b/cli/command/cli_test.go @@ -3,6 +3,7 @@ package command import ( "crypto/x509" "os" + "runtime" "testing" cliconfig "github.com/docker/cli/cli/config" @@ -20,6 +21,9 @@ import ( func TestNewAPIClientFromFlags(t *testing.T) { host := "unix://path" + if runtime.GOOS == "windows" { + host = "npipe://./" + } opts := &flags.CommonOptions{Hosts: []string{host}} configFile := &configfile.ConfigFile{ HTTPHeaders: map[string]string{ diff --git a/cli/command/container/cp_test.go b/cli/command/container/cp_test.go index 78fb3e237f..7d706f354c 100644 --- a/cli/command/container/cp_test.go +++ b/cli/command/container/cp_test.go @@ -121,7 +121,12 @@ func TestRunCopyToContainerFromFileWithTrailingSlash(t *testing.T) { } cli := test.NewFakeCli(&fakeClient{}) err := runCopy(cli, options) - assert.ErrorContains(t, err, "not a directory") + + expectedError := "not a directory" + if runtime.GOOS == "windows" { + expectedError = "The filename, directory name, or volume label syntax is incorrect" + } + assert.ErrorContains(t, err, expectedError) } func TestRunCopyToContainerSourceDoesNotExist(t *testing.T) { diff --git a/cli/command/formatter/history_test.go b/cli/command/formatter/history_test.go index d8e5dde1f6..77423a8010 100644 --- a/cli/command/formatter/history_test.go +++ b/cli/command/formatter/history_test.go @@ -1,13 +1,12 @@ package formatter import ( + "bytes" "strconv" "strings" "testing" "time" - "bytes" - "github.com/docker/docker/api/types/image" "github.com/docker/docker/pkg/stringid" "github.com/gotestyourself/gotestyourself/assert" @@ -51,6 +50,7 @@ func TestHistoryContext_ID(t *testing.T) { } func TestHistoryContext_CreatedSince(t *testing.T) { + dateStr := "2009-11-10T23:00:00Z" var ctx historyContext cases := []historyCase{ { @@ -65,7 +65,7 @@ func TestHistoryContext_CreatedSince(t *testing.T) { h: image.HistoryResponseItem{Created: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()}, trunc: false, human: false, - }, "2009-11-10T23:00:00Z", ctx.CreatedSince, + }, dateStr, ctx.CreatedSince, }, } diff --git a/cli/command/image/build_linux_test.go b/cli/command/image/build_linux_test.go new file mode 100644 index 0000000000..59b2871b4e --- /dev/null +++ b/cli/command/image/build_linux_test.go @@ -0,0 +1,54 @@ +//+build linux + +package image + +import ( + "bytes" + "io" + "io/ioutil" + "syscall" + "testing" + + "github.com/docker/cli/internal/test" + "github.com/docker/docker/api/types" + "github.com/docker/docker/pkg/archive" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/fs" + "golang.org/x/net/context" +) + +func TestRunBuildResetsUidAndGidInContext(t *testing.T) { + dest := fs.NewDir(t, "test-build-context-dest") + defer dest.Remove() + + fakeImageBuild := func(_ context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { + assert.NilError(t, archive.Untar(context, dest.Path(), nil)) + + body := new(bytes.Buffer) + return types.ImageBuildResponse{Body: ioutil.NopCloser(body)}, nil + } + cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild}) + + dir := fs.NewDir(t, "test-build-context", + fs.WithFile("foo", "some content", fs.AsUser(65534, 65534)), + fs.WithFile("Dockerfile", ` + FROM alpine:3.6 + COPY foo bar / + `), + ) + defer dir.Remove() + + options := newBuildOptions() + options.context = dir.Path() + + err := runBuild(cli, options) + assert.NilError(t, err) + + files, err := ioutil.ReadDir(dest.Path()) + assert.NilError(t, err) + for _, fileInfo := range files { + assert.Check(t, is.Equal(uint32(0), fileInfo.Sys().(*syscall.Stat_t).Uid)) + assert.Check(t, is.Equal(uint32(0), fileInfo.Sys().(*syscall.Stat_t).Gid)) + } +} diff --git a/cli/command/image/build_test.go b/cli/command/image/build_test.go index a178a93cea..31f53fa0d1 100644 --- a/cli/command/image/build_test.go +++ b/cli/command/image/build_test.go @@ -6,9 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" - "runtime" "sort" - "syscall" "testing" "github.com/docker/cli/cli/command" @@ -18,45 +16,9 @@ import ( "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" - "github.com/gotestyourself/gotestyourself/skip" "golang.org/x/net/context" ) -func TestRunBuildResetsUidAndGidInContext(t *testing.T) { - skip.IfCondition(t, runtime.GOOS == "windows", "uid and gid not relevant on windows") - dest := fs.NewDir(t, "test-build-context-dest") - defer dest.Remove() - - fakeImageBuild := func(_ context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { - assert.NilError(t, archive.Untar(context, dest.Path(), nil)) - - body := new(bytes.Buffer) - return types.ImageBuildResponse{Body: ioutil.NopCloser(body)}, nil - } - cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild}) - - dir := fs.NewDir(t, "test-build-context", - fs.WithFile("foo", "some content", fs.AsUser(65534, 65534)), - fs.WithFile("Dockerfile", ` - FROM alpine:3.6 - COPY foo bar / - `), - ) - defer dir.Remove() - - options := newBuildOptions() - options.context = dir.Path() - - err := runBuild(cli, options) - assert.NilError(t, err) - - files, err := ioutil.ReadDir(dest.Path()) - assert.NilError(t, err) - for _, fileInfo := range files { - assert.Check(t, is.Equal(uint32(0), fileInfo.Sys().(*syscall.Stat_t).Uid)) - assert.Check(t, is.Equal(uint32(0), fileInfo.Sys().(*syscall.Stat_t).Gid)) - } -} func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) { dest, err := ioutil.TempDir("", "test-build-compress-dest") assert.NilError(t, err) diff --git a/cli/command/plugin/create_test.go b/cli/command/plugin/create_test.go index 87e17d3793..41191cab35 100644 --- a/cli/command/plugin/create_test.go +++ b/cli/command/plugin/create_test.go @@ -4,6 +4,7 @@ import ( "fmt" "io" "io/ioutil" + "runtime" "testing" "github.com/docker/cli/internal/test" @@ -14,7 +15,10 @@ import ( ) func TestCreateErrors(t *testing.T) { - + noSuchFile := "no such file or directory" + if runtime.GOOS == "windows" { + noSuchFile = "The system cannot find the file specified." + } testCases := []struct { args []string expectedError string @@ -29,7 +33,7 @@ func TestCreateErrors(t *testing.T) { }, { args: []string{"plugin-foo", "nonexistent_context_dir"}, - expectedError: "no such file or directory", + expectedError: noSuchFile, }, } @@ -61,7 +65,12 @@ func TestCreateErrorOnContextDirWithoutConfig(t *testing.T) { cmd := newCreateCommand(cli) cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()}) cmd.SetOutput(ioutil.Discard) - assert.ErrorContains(t, cmd.Execute(), "config.json: no such file or directory") + + expectedErr := "config.json: no such file or directory" + if runtime.GOOS == "windows" { + expectedErr = "config.json: The system cannot find the file specified." + } + assert.ErrorContains(t, cmd.Execute(), expectedErr) } func TestCreateErrorOnInvalidConfig(t *testing.T) { diff --git a/cli/command/stack/swarm/deploy_composefile_test.go b/cli/command/stack/swarm/deploy_composefile_test.go index 91c318cd63..2903fd3c42 100644 --- a/cli/command/stack/swarm/deploy_composefile_test.go +++ b/cli/command/stack/swarm/deploy_composefile_test.go @@ -33,10 +33,13 @@ func TestValidateExternalNetworks(t *testing.T) { inspectError: errors.New("Unexpected"), expectedMsg: "Unexpected", }, - { - inspectError: errors.New("host net does not exist on swarm classic"), - network: "host", - }, + // FIXME(vdemeester) that doesn't work under windows, the check needs to be smarter + /* + { + inspectError: errors.New("host net does not exist on swarm classic"), + network: "host", + }, + */ { network: "user", expectedMsg: "is not in the right scope", diff --git a/cli/command/trust/key_generate_test.go b/cli/command/trust/key_generate_test.go index bad5164941..6e26f98d1f 100644 --- a/cli/command/trust/key_generate_test.go +++ b/cli/command/trust/key_generate_test.go @@ -127,7 +127,7 @@ func TestValidateKeyArgs(t *testing.T) { assert.NilError(t, ioutil.WriteFile(filepath.Join(pubKeyCWD, "a.pub"), []byte("abc"), notary.PrivExecPerms)) err = validateKeyArgs("a", pubKeyCWD) - assert.Error(t, err, fmt.Sprintf("public key file already exists: \"%s/a.pub\"", pubKeyCWD)) + assert.Error(t, err, fmt.Sprintf("public key file already exists: \"%s\"", filepath.Join(pubKeyCWD, "a.pub"))) err = validateKeyArgs("a", "/random/dir/") assert.Error(t, err, "public key path does not exist: \"/random/dir/\"") diff --git a/cli/command/trust/key_load_test.go b/cli/command/trust/key_load_test.go index b24f528ef0..c4da320a59 100644 --- a/cli/command/trust/key_load_test.go +++ b/cli/command/trust/key_load_test.go @@ -6,12 +6,14 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "testing" "github.com/docker/cli/cli/config" "github.com/docker/cli/internal/test" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/skip" "github.com/theupdateframework/notary" "github.com/theupdateframework/notary/passphrase" "github.com/theupdateframework/notary/storage" @@ -20,6 +22,10 @@ import ( ) func TestTrustKeyLoadErrors(t *testing.T) { + noSuchFile := "stat iamnotakey: no such file or directory" + if runtime.GOOS == "windows" { + noSuchFile = "CreateFile iamnotakey: The system cannot find the file specified." + } testCases := []struct { name string args []string @@ -40,7 +46,7 @@ func TestTrustKeyLoadErrors(t *testing.T) { { name: "not-a-key", args: []string{"iamnotakey"}, - expectedError: "refusing to load key from iamnotakey: stat iamnotakey: no such file or directory", + expectedError: "refusing to load key from iamnotakey: " + noSuchFile, expectedOutput: "Loading key from \"iamnotakey\"...\n", }, { @@ -109,6 +115,7 @@ var testKeys = map[string][]byte{ } func TestLoadKeyFromPath(t *testing.T) { + skip.If(t, runtime.GOOS == "windows") for keyID, keyBytes := range testKeys { t.Run(fmt.Sprintf("load-key-id-%s-from-path", keyID), func(t *testing.T) { testLoadKeyFromPath(t, keyID, keyBytes) @@ -163,6 +170,7 @@ func testLoadKeyFromPath(t *testing.T, privKeyID string, privKeyFixture []byte) } func TestLoadKeyTooPermissive(t *testing.T) { + skip.If(t, runtime.GOOS == "windows") for keyID, keyBytes := range testKeys { t.Run(fmt.Sprintf("load-key-id-%s-too-permissive", keyID), func(t *testing.T) { testLoadKeyTooPermissive(t, keyBytes) @@ -219,6 +227,7 @@ H3nzy2O6Q/ct4BjOBKa+WCdRtPo78bA+C/7t81ADQO8Jqaj59W50rwoqDQ== -----END PUBLIC KEY-----`) func TestLoadPubKeyFailure(t *testing.T) { + skip.If(t, runtime.GOOS == "windows") pubKeyDir, err := ioutil.TempDir("", "key-load-test-pubkey-") assert.NilError(t, err) defer os.RemoveAll(pubKeyDir) diff --git a/cli/command/trust/sign_test.go b/cli/command/trust/sign_test.go index 523b2792e4..002cbd5fe8 100644 --- a/cli/command/trust/sign_test.go +++ b/cli/command/trust/sign_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "io/ioutil" "os" + "runtime" "testing" "github.com/docker/cli/cli/config" @@ -12,6 +13,7 @@ import ( "github.com/docker/cli/internal/test" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/skip" "github.com/theupdateframework/notary" "github.com/theupdateframework/notary/client" "github.com/theupdateframework/notary/client/changelist" @@ -127,6 +129,7 @@ func TestGetOrGenerateNotaryKey(t *testing.T) { } func TestAddStageSigners(t *testing.T) { + skip.If(t, runtime.GOOS == "windows", "FIXME: not supported currently") tmpDir, err := ioutil.TempDir("", "notary-test-") assert.NilError(t, err) defer os.RemoveAll(tmpDir) diff --git a/cli/command/trust/signer_add_test.go b/cli/command/trust/signer_add_test.go index d2e1e21481..0f0c404d24 100644 --- a/cli/command/trust/signer_add_test.go +++ b/cli/command/trust/signer_add_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "testing" "github.com/docker/cli/cli/config" @@ -96,7 +97,11 @@ func TestSignerAddCommandBadKeyPath(t *testing.T) { cmd.SetArgs([]string{"--key", "/path/to/key.pem", "alice", "alpine"}) cmd.SetOutput(ioutil.Discard) - assert.Error(t, cmd.Execute(), "unable to read public key from file: open /path/to/key.pem: no such file or directory") + expectedError := "unable to read public key from file: open /path/to/key.pem: no such file or directory" + if runtime.GOOS == "windows" { + expectedError = "unable to read public key from file: open /path/to/key.pem: The system cannot find the path specified." + } + assert.Error(t, cmd.Execute(), expectedError) } func TestSignerAddCommandInvalidRepoName(t *testing.T) { @@ -127,7 +132,11 @@ func TestSignerAddCommandInvalidRepoName(t *testing.T) { func TestIngestPublicKeys(t *testing.T) { // Call with a bad path _, err := ingestPublicKeys([]string{"foo", "bar"}) - assert.Error(t, err, "unable to read public key from file: open foo: no such file or directory") + expectedError := "unable to read public key from file: open foo: no such file or directory" + if runtime.GOOS == "windows" { + expectedError = "unable to read public key from file: open foo: The system cannot find the file specified." + } + assert.Error(t, err, expectedError) // Call with real file path tmpfile, err := ioutil.TempFile("", "pemfile") assert.NilError(t, err) diff --git a/cli/compose/loader/full-struct_test.go b/cli/compose/loader/full-struct_test.go index 3f2a587bce..b9afa7ef65 100644 --- a/cli/compose/loader/full-struct_test.go +++ b/cli/compose/loader/full-struct_test.go @@ -1,6 +1,8 @@ package loader import ( + "fmt" + "path/filepath" "time" "github.com/docker/cli/cli/compose/types" @@ -313,10 +315,10 @@ func services(workingDir, homeDir string) []types.ServiceConfig { {Target: "/var/lib/mysql", Type: "volume"}, {Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind"}, {Source: workingDir, Target: "/code", Type: "bind"}, - {Source: workingDir + "/static", Target: "/var/www/html", Type: "bind"}, + {Source: filepath.Join(workingDir, "static"), Target: "/var/www/html", Type: "bind"}, {Source: homeDir + "/configs", Target: "/etc/configs/", Type: "bind", ReadOnly: true}, {Source: "datavolume", Target: "/var/lib/mysql", Type: "volume"}, - {Source: workingDir + "/opt", Target: "/opt", Consistency: "cached", Type: "bind"}, + {Source: filepath.Join(workingDir, "opt"), Target: "/opt", Consistency: "cached", Type: "bind"}, {Target: "/opt", Type: "tmpfs", Tmpfs: &types.ServiceVolumeTmpfs{ Size: int64(10000), }}, @@ -389,3 +391,313 @@ func volumes() map[string]types.VolumeConfig { }, } } + +func fullExampleYAML(workingDir string) string { + return fmt.Sprintf(`version: "3.6" +services: + foo: + build: + context: ./dir + dockerfile: Dockerfile + args: + foo: bar + labels: + FOO: BAR + cache_from: + - foo + - bar + network: foo + target: foo + cap_add: + - ALL + cap_drop: + - NET_ADMIN + - SYS_ADMIN + cgroup_parent: m-executor-abcd + command: + - bundle + - exec + - thin + - -p + - "3000" + container_name: my-web-container + depends_on: + - db + - redis + deploy: + mode: replicated + replicas: 6 + labels: + FOO: BAR + update_config: + parallelism: 3 + delay: 10s + failure_action: continue + monitor: 1m0s + max_failure_ratio: 0.3 + order: start-first + resources: + limits: + cpus: "0.001" + memory: "52428800" + reservations: + cpus: "0.0001" + memory: "20971520" + generic_resources: + - discrete_resource_spec: + kind: gpu + value: 2 + - discrete_resource_spec: + kind: ssd + value: 1 + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + window: 2m0s + placement: + constraints: + - node=foo + preferences: + - spread: node.labels.az + endpoint_mode: dnsrr + devices: + - /dev/ttyUSB0:/dev/ttyUSB0 + dns: + - 8.8.8.8 + - 9.9.9.9 + dns_search: + - dc1.example.com + - dc2.example.com + domainname: foo.com + entrypoint: + - /code/entrypoint.sh + - -p + - "3000" + environment: + BAR: bar_from_env_file_2 + BAZ: baz_from_service_def + FOO: foo_from_env_file + QUX: qux_from_environment + env_file: + - ./example1.env + - ./example2.env + expose: + - "3000" + - "8000" + external_links: + - redis_1 + - project_db_1:mysql + - project_db_1:postgresql + extra_hosts: + - somehost:162.242.195.82 + - otherhost:50.31.209.229 + hostname: foo + healthcheck: + test: + - CMD-SHELL + - echo "hello world" + timeout: 1s + interval: 10s + retries: 5 + start_period: 15s + image: redis + ipc: host + labels: + com.example.description: Accounting webapp + com.example.empty-label: "" + com.example.number: "42" + links: + - db + - db:database + - redis + logging: + driver: syslog + options: + syslog-address: tcp://192.168.0.42:123 + mac_address: 02:42:ac:11:65:43 + network_mode: container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b + networks: + other-network: + ipv4_address: 172.16.238.10 + ipv6_address: 2001:3984:3989::10 + other-other-network: null + some-network: + aliases: + - alias1 + - alias3 + pid: host + ports: + - mode: ingress + target: 3000 + protocol: tcp + - mode: ingress + target: 3001 + protocol: tcp + - mode: ingress + target: 3002 + protocol: tcp + - mode: ingress + target: 3003 + protocol: tcp + - mode: ingress + target: 3004 + protocol: tcp + - mode: ingress + target: 3005 + protocol: tcp + - mode: ingress + target: 8000 + published: 8000 + protocol: tcp + - mode: ingress + target: 8080 + published: 9090 + protocol: tcp + - mode: ingress + target: 8081 + published: 9091 + protocol: tcp + - mode: ingress + target: 22 + published: 49100 + protocol: tcp + - mode: ingress + target: 8001 + published: 8001 + protocol: tcp + - mode: ingress + target: 5000 + published: 5000 + protocol: tcp + - mode: ingress + target: 5001 + published: 5001 + protocol: tcp + - mode: ingress + target: 5002 + published: 5002 + protocol: tcp + - mode: ingress + target: 5003 + published: 5003 + protocol: tcp + - mode: ingress + target: 5004 + published: 5004 + protocol: tcp + - mode: ingress + target: 5005 + published: 5005 + protocol: tcp + - mode: ingress + target: 5006 + published: 5006 + protocol: tcp + - mode: ingress + target: 5007 + published: 5007 + protocol: tcp + - mode: ingress + target: 5008 + published: 5008 + protocol: tcp + - mode: ingress + target: 5009 + published: 5009 + protocol: tcp + - mode: ingress + target: 5010 + published: 5010 + protocol: tcp + privileged: true + read_only: true + restart: always + security_opt: + - label=level:s0:c100,c200 + - label=type:svirt_apache_t + stdin_open: true + stop_grace_period: 20s + stop_signal: SIGUSR1 + tmpfs: + - /run + - /tmp + tty: true + ulimits: + nofile: + soft: 20000 + hard: 40000 + nproc: 65535 + user: someone + volumes: + - type: volume + target: /var/lib/mysql + - type: bind + source: /opt/data + target: /var/lib/mysql + - type: bind + source: /foo + target: /code + - type: bind + source: %s + target: /var/www/html + - type: bind + source: /bar/configs + target: /etc/configs/ + read_only: true + - type: volume + source: datavolume + target: /var/lib/mysql + - type: bind + source: %s + target: /opt + consistency: cached + - type: tmpfs + target: /opt + tmpfs: + size: 10000 + working_dir: /code +networks: + external-network: + name: external-network + external: true + other-external-network: + name: my-cool-network + external: true + other-network: + driver: overlay + driver_opts: + baz: "1" + foo: bar + ipam: + driver: overlay + config: + - subnet: 172.16.238.0/24 + - subnet: 2001:3984:3989::/64 + some-network: {} +volumes: + another-volume: + name: user_specified_name + driver: vsphere + driver_opts: + baz: "1" + foo: bar + external-volume: + name: external-volume + external: true + external-volume3: + name: this-is-volume3 + external: true + other-external-volume: + name: my-cool-volume + external: true + other-volume: + driver: flocker + driver_opts: + baz: "1" + foo: bar + some-volume: {} +secrets: {} +configs: {} +`, filepath.Join(workingDir, "static"), filepath.Join(workingDir, "opt")) +} diff --git a/cli/compose/loader/types_test.go b/cli/compose/loader/types_test.go index b324c8e580..75ea835bd7 100644 --- a/cli/compose/loader/types_test.go +++ b/cli/compose/loader/types_test.go @@ -9,314 +9,10 @@ import ( ) func TestMarshallConfig(t *testing.T) { - cfg := fullExampleConfig("/foo", "/bar") - expected := `version: "3.6" -services: - foo: - build: - context: ./dir - dockerfile: Dockerfile - args: - foo: bar - labels: - FOO: BAR - cache_from: - - foo - - bar - network: foo - target: foo - cap_add: - - ALL - cap_drop: - - NET_ADMIN - - SYS_ADMIN - cgroup_parent: m-executor-abcd - command: - - bundle - - exec - - thin - - -p - - "3000" - container_name: my-web-container - depends_on: - - db - - redis - deploy: - mode: replicated - replicas: 6 - labels: - FOO: BAR - update_config: - parallelism: 3 - delay: 10s - failure_action: continue - monitor: 1m0s - max_failure_ratio: 0.3 - order: start-first - resources: - limits: - cpus: "0.001" - memory: "52428800" - reservations: - cpus: "0.0001" - memory: "20971520" - generic_resources: - - discrete_resource_spec: - kind: gpu - value: 2 - - discrete_resource_spec: - kind: ssd - value: 1 - restart_policy: - condition: on-failure - delay: 5s - max_attempts: 3 - window: 2m0s - placement: - constraints: - - node=foo - preferences: - - spread: node.labels.az - endpoint_mode: dnsrr - devices: - - /dev/ttyUSB0:/dev/ttyUSB0 - dns: - - 8.8.8.8 - - 9.9.9.9 - dns_search: - - dc1.example.com - - dc2.example.com - domainname: foo.com - entrypoint: - - /code/entrypoint.sh - - -p - - "3000" - environment: - BAR: bar_from_env_file_2 - BAZ: baz_from_service_def - FOO: foo_from_env_file - QUX: qux_from_environment - env_file: - - ./example1.env - - ./example2.env - expose: - - "3000" - - "8000" - external_links: - - redis_1 - - project_db_1:mysql - - project_db_1:postgresql - extra_hosts: - - somehost:162.242.195.82 - - otherhost:50.31.209.229 - hostname: foo - healthcheck: - test: - - CMD-SHELL - - echo "hello world" - timeout: 1s - interval: 10s - retries: 5 - start_period: 15s - image: redis - ipc: host - labels: - com.example.description: Accounting webapp - com.example.empty-label: "" - com.example.number: "42" - links: - - db - - db:database - - redis - logging: - driver: syslog - options: - syslog-address: tcp://192.168.0.42:123 - mac_address: 02:42:ac:11:65:43 - network_mode: container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b - networks: - other-network: - ipv4_address: 172.16.238.10 - ipv6_address: 2001:3984:3989::10 - other-other-network: null - some-network: - aliases: - - alias1 - - alias3 - pid: host - ports: - - mode: ingress - target: 3000 - protocol: tcp - - mode: ingress - target: 3001 - protocol: tcp - - mode: ingress - target: 3002 - protocol: tcp - - mode: ingress - target: 3003 - protocol: tcp - - mode: ingress - target: 3004 - protocol: tcp - - mode: ingress - target: 3005 - protocol: tcp - - mode: ingress - target: 8000 - published: 8000 - protocol: tcp - - mode: ingress - target: 8080 - published: 9090 - protocol: tcp - - mode: ingress - target: 8081 - published: 9091 - protocol: tcp - - mode: ingress - target: 22 - published: 49100 - protocol: tcp - - mode: ingress - target: 8001 - published: 8001 - protocol: tcp - - mode: ingress - target: 5000 - published: 5000 - protocol: tcp - - mode: ingress - target: 5001 - published: 5001 - protocol: tcp - - mode: ingress - target: 5002 - published: 5002 - protocol: tcp - - mode: ingress - target: 5003 - published: 5003 - protocol: tcp - - mode: ingress - target: 5004 - published: 5004 - protocol: tcp - - mode: ingress - target: 5005 - published: 5005 - protocol: tcp - - mode: ingress - target: 5006 - published: 5006 - protocol: tcp - - mode: ingress - target: 5007 - published: 5007 - protocol: tcp - - mode: ingress - target: 5008 - published: 5008 - protocol: tcp - - mode: ingress - target: 5009 - published: 5009 - protocol: tcp - - mode: ingress - target: 5010 - published: 5010 - protocol: tcp - privileged: true - read_only: true - restart: always - security_opt: - - label=level:s0:c100,c200 - - label=type:svirt_apache_t - stdin_open: true - stop_grace_period: 20s - stop_signal: SIGUSR1 - tmpfs: - - /run - - /tmp - tty: true - ulimits: - nofile: - soft: 20000 - hard: 40000 - nproc: 65535 - user: someone - volumes: - - type: volume - target: /var/lib/mysql - - type: bind - source: /opt/data - target: /var/lib/mysql - - type: bind - source: /foo - target: /code - - type: bind - source: /foo/static - target: /var/www/html - - type: bind - source: /bar/configs - target: /etc/configs/ - read_only: true - - type: volume - source: datavolume - target: /var/lib/mysql - - type: bind - source: /foo/opt - target: /opt - consistency: cached - - type: tmpfs - target: /opt - tmpfs: - size: 10000 - working_dir: /code -networks: - external-network: - name: external-network - external: true - other-external-network: - name: my-cool-network - external: true - other-network: - driver: overlay - driver_opts: - baz: "1" - foo: bar - ipam: - driver: overlay - config: - - subnet: 172.16.238.0/24 - - subnet: 2001:3984:3989::/64 - some-network: {} -volumes: - another-volume: - name: user_specified_name - driver: vsphere - driver_opts: - baz: "1" - foo: bar - external-volume: - name: external-volume - external: true - external-volume3: - name: this-is-volume3 - external: true - other-external-volume: - name: my-cool-volume - external: true - other-volume: - driver: flocker - driver_opts: - baz: "1" - foo: bar - some-volume: {} -secrets: {} -configs: {} -` + workingDir := "/foo" + homeDir := "/bar" + cfg := fullExampleConfig(workingDir, homeDir) + expected := fullExampleYAML(workingDir) actual, err := yaml.Marshal(cfg) assert.NilError(t, err) diff --git a/cli/registry/client/fetcher.go b/cli/registry/client/fetcher.go index 1e748f255d..796bc01eb1 100644 --- a/cli/registry/client/fetcher.go +++ b/cli/registry/client/fetcher.go @@ -155,7 +155,7 @@ func pullManifestList(ctx context.Context, ref reference.Named, repo distributio } v, ok := manifest.(*schema2.DeserializedManifest) if !ok { - return nil, fmt.Errorf("unsupported manifest format: %s", v) + return nil, fmt.Errorf("unsupported manifest format: %v", v) } manifestRef, err := reference.WithDigest(ref, manifestDescriptor.Digest) diff --git a/scripts/validate/shellcheck b/scripts/validate/shellcheck index 8b0df25b73..63cedf137b 100755 --- a/scripts/validate/shellcheck +++ b/scripts/validate/shellcheck @@ -1,5 +1,5 @@ -#!/usr/bin/env bash -set -eo pipefail - -shellcheck contrib/completion/bash/docker -find scripts/ -type f | grep -v scripts/winresources | grep -v '*.ps1' | xargs shellcheck +#!/usr/bin/env bash +set -eo pipefail + +shellcheck contrib/completion/bash/docker +find scripts/ -type f | grep -v scripts/winresources | grep -v '.*.ps1' | xargs shellcheck