diff --git a/.changelog/23599.txt b/.changelog/23599.txt new file mode 100644 index 000000000..210bb159c --- /dev/null +++ b/.changelog/23599.txt @@ -0,0 +1,3 @@ +```release-note:bug +windows: Fix bug with containers capabilities on Docker CE +``` diff --git a/drivers/docker/driver.go b/drivers/docker/driver.go index ea59e5b3a..534ee1b62 100644 --- a/drivers/docker/driver.go +++ b/drivers/docker/driver.go @@ -1109,9 +1109,20 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T } hostConfig.Privileged = driverConfig.Privileged + // get docker client info (we need to know the runtime to adjust + // OS-specific capabilities) + client, err := d.getDockerClient() + if err != nil { + return c, err + } + ver, err := client.Version() + if err != nil { + return c, err + } + // set add/drop capabilities if hostConfig.CapAdd, hostConfig.CapDrop, err = capabilities.Delta( - capabilities.DockerDefaults(), d.config.AllowCaps, driverConfig.CapAdd, driverConfig.CapDrop, + capabilities.DockerDefaults(ver), d.config.AllowCaps, driverConfig.CapAdd, driverConfig.CapDrop, ); err != nil { return c, err } diff --git a/drivers/docker/driver_test.go b/drivers/docker/driver_test.go index 7359656f6..6a4868697 100644 --- a/drivers/docker/driver_test.go +++ b/drivers/docker/driver_test.go @@ -24,7 +24,6 @@ import ( "github.com/hashicorp/nomad/client/lib/numalib" "github.com/hashicorp/nomad/client/taskenv" "github.com/hashicorp/nomad/client/testutil" - "github.com/hashicorp/nomad/drivers/shared/capabilities" "github.com/hashicorp/nomad/helper/pluginutils/hclspecutils" "github.com/hashicorp/nomad/helper/pluginutils/hclutils" "github.com/hashicorp/nomad/helper/pluginutils/loader" @@ -197,13 +196,6 @@ func dockerDriverHarness(t *testing.T, cfg map[string]interface{}) *dtestutil.Dr } } - // If on windows, "allow" (don't attempt to drop) linux capabilities. - // https://github.com/hashicorp/nomad/issues/15181 - // TODO: this should instead get fixed properly in capabilities package. - if _, ok := cfg["allow_caps"]; !ok && runtime.GOOS == "windows" { - cfg["allow_caps"] = capabilities.DockerDefaults().Slice(false) - } - plugLoader, err := loader.NewPluginLoader(&loader.PluginLoaderConfig{ Logger: logger, PluginDir: "./plugins", diff --git a/drivers/docker/driver_windows.go b/drivers/docker/driver_windows.go index 8c2ab3175..8ac5aa7b2 100644 --- a/drivers/docker/driver_windows.go +++ b/drivers/docker/driver_windows.go @@ -16,10 +16,6 @@ func getPortBinding(ip string, port string) docker.PortBinding { return docker.PortBinding{HostIP: "", HostPort: port} } -func tweakCapabilities(basics, adds, drops []string) ([]string, error) { - return nil, nil -} - var containerAdminErrMsg = "running container as ContainerAdmin is unsafe; change the container user, set task configuration to privileged or enable windows_allow_insecure_container_admin to disable this check" func validateImageUser(user, taskUser string, taskDriverConfig *TaskConfig, driverConfig *DriverConfig) error { diff --git a/drivers/shared/capabilities/defaults.go b/drivers/shared/capabilities/defaults.go index 31fd3869d..bca4cc6ca 100644 --- a/drivers/shared/capabilities/defaults.go +++ b/drivers/shared/capabilities/defaults.go @@ -29,17 +29,6 @@ func NomadDefaults() *Set { return New(extractLiteral.FindAllString(HCLSpecLiteral, -1)) } -// DockerDefaults is a list of Linux capabilities enabled by Docker by default -// and is used to compute the set of capabilities to add/drop given docker driver -// configuration. -// -// https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities -func DockerDefaults() *Set { - defaults := NomadDefaults() - defaults.Add("NET_RAW") - return defaults -} - // Supported returns the set of capabilities supported by the operating system. // // This set will expand over time as new capabilities are introduced to the kernel diff --git a/drivers/shared/capabilities/defaults_default.go b/drivers/shared/capabilities/defaults_default.go new file mode 100644 index 000000000..8ff94454f --- /dev/null +++ b/drivers/shared/capabilities/defaults_default.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build !windows + +package capabilities + +import docker "github.com/fsouza/go-dockerclient" + +// DockerDefaults is a list of Linux capabilities enabled by Docker by default +// and is used to compute the set of capabilities to add/drop given docker driver +// configuration. +// +// https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities +func DockerDefaults(info *docker.Env) *Set { + defaults := NomadDefaults() + defaults.Add("NET_RAW") + return defaults +} diff --git a/drivers/shared/capabilities/defaults_test.go b/drivers/shared/capabilities/defaults_test.go index 40b0ee8fb..4f461b583 100644 --- a/drivers/shared/capabilities/defaults_test.go +++ b/drivers/shared/capabilities/defaults_test.go @@ -26,7 +26,7 @@ func TestSet_NomadDefaults(t *testing.T) { func TestSet_DockerDefaults(t *testing.T) { ci.Parallel(t) - result := DockerDefaults() + result := DockerDefaults(nil) require.Len(t, result.Slice(false), 14) require.Contains(t, result.String(), "net_raw") } @@ -280,7 +280,7 @@ func TestCaps_Delta(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - add, drop, err := Delta(DockerDefaults(), tc.allowCaps, tc.capAdd, tc.capDrop) + add, drop, err := Delta(DockerDefaults(nil), tc.allowCaps, tc.capAdd, tc.capDrop) if !tc.skip { require.Equal(t, tc.err, err) require.Equal(t, tc.expAdd, add) diff --git a/drivers/shared/capabilities/defaults_windows.go b/drivers/shared/capabilities/defaults_windows.go new file mode 100644 index 000000000..56a97e22e --- /dev/null +++ b/drivers/shared/capabilities/defaults_windows.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build windows + +package capabilities + +import ( + "strings" + + docker "github.com/fsouza/go-dockerclient" +) + +// DockerDefaults is a list of Windows capabilities enabled by Docker by default +// and is used to compute the set of capabilities to add/drop given docker driver +// configuration. +// +// Doing this on windows is somewhat tricky, because capabilities differ by +// runtime, so we have to perform some extra checks. +func DockerDefaults(ver *docker.Env) *Set { + defaults := NomadDefaults() + + // Docker CE doesn't include NET_RAW on Windows, Mirantis (aka Docker EE) does + var platform string + if ver != nil { + platform = ver.Get("Platform") + } + if strings.Contains(platform, "Mirantis") { + defaults.Add("NET_RAW") + } + + return defaults +}