mirror of
https://github.com/docker/cli.git
synced 2026-09-28 02:06:53 -04:00
api: add configurable MaskedPaths and ReadOnlyPaths to the API
This adds MaskedPaths and ReadOnlyPaths options to HostConfig for containers so that a user can override the default values. When the value sent through the API is nil the default is used. Otherwise the default is overridden. Adds integration tests for MaskedPaths and ReadonlyPaths. Signed-off-by: Jess Frazelle <acidburn@microsoft.com> Upstream-commit: 3694c1e34e40fa2e255a97b5541645cec9c8d1d5 Component: engine
This commit is contained in:
@@ -2,14 +2,21 @@ package container // import "github.com/docker/docker/integration/container"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
ctr "github.com/docker/docker/integration/internal/container"
|
||||
"github.com/docker/docker/internal/test/request"
|
||||
"github.com/docker/docker/oci"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
"github.com/gotestyourself/gotestyourself/poll"
|
||||
"github.com/gotestyourself/gotestyourself/skip"
|
||||
)
|
||||
|
||||
@@ -137,3 +144,160 @@ func TestCreateTmpfsMountsTarget(t *testing.T) {
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
||||
}
|
||||
}
|
||||
func TestCreateWithCustomMaskedPaths(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
|
||||
defer setupTest(t)()
|
||||
client := request.NewAPIClient(t)
|
||||
ctx := context.Background()
|
||||
|
||||
testCases := []struct {
|
||||
maskedPaths []string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
maskedPaths: []string{},
|
||||
expected: []string{},
|
||||
},
|
||||
{
|
||||
maskedPaths: nil,
|
||||
expected: oci.DefaultSpec().Linux.MaskedPaths,
|
||||
},
|
||||
{
|
||||
maskedPaths: []string{"/proc/kcore", "/proc/keys"},
|
||||
expected: []string{"/proc/kcore", "/proc/keys"},
|
||||
},
|
||||
}
|
||||
|
||||
checkInspect := func(t *testing.T, ctx context.Context, name string, expected []string) {
|
||||
_, b, err := client.ContainerInspectWithRaw(ctx, name, false)
|
||||
assert.NilError(t, err)
|
||||
|
||||
var inspectJSON map[string]interface{}
|
||||
err = json.Unmarshal(b, &inspectJSON)
|
||||
assert.NilError(t, err)
|
||||
|
||||
cfg, ok := inspectJSON["HostConfig"].(map[string]interface{})
|
||||
assert.Check(t, is.Equal(true, ok), name)
|
||||
|
||||
maskedPaths, ok := cfg["MaskedPaths"].([]interface{})
|
||||
assert.Check(t, is.Equal(true, ok), name)
|
||||
|
||||
mps := []string{}
|
||||
for _, mp := range maskedPaths {
|
||||
mps = append(mps, mp.(string))
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, expected, mps)
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
name := fmt.Sprintf("create-masked-paths-%d", i)
|
||||
config := container.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"true"},
|
||||
}
|
||||
hc := container.HostConfig{}
|
||||
if tc.maskedPaths != nil {
|
||||
hc.MaskedPaths = tc.maskedPaths
|
||||
}
|
||||
|
||||
// Create the container.
|
||||
c, err := client.ContainerCreate(context.Background(),
|
||||
&config,
|
||||
&hc,
|
||||
&network.NetworkingConfig{},
|
||||
name,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
checkInspect(t, ctx, name, tc.expected)
|
||||
|
||||
// Start the container.
|
||||
err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
poll.WaitOn(t, ctr.IsInState(ctx, client, c.ID, "exited"), poll.WithDelay(100*time.Millisecond))
|
||||
|
||||
checkInspect(t, ctx, name, tc.expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateWithCustomReadonlyPaths(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
|
||||
defer setupTest(t)()
|
||||
client := request.NewAPIClient(t)
|
||||
ctx := context.Background()
|
||||
|
||||
testCases := []struct {
|
||||
doc string
|
||||
readonlyPaths []string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
readonlyPaths: []string{},
|
||||
expected: []string{},
|
||||
},
|
||||
{
|
||||
readonlyPaths: nil,
|
||||
expected: oci.DefaultSpec().Linux.ReadonlyPaths,
|
||||
},
|
||||
{
|
||||
readonlyPaths: []string{"/proc/asound", "/proc/bus"},
|
||||
expected: []string{"/proc/asound", "/proc/bus"},
|
||||
},
|
||||
}
|
||||
|
||||
checkInspect := func(t *testing.T, ctx context.Context, name string, expected []string) {
|
||||
_, b, err := client.ContainerInspectWithRaw(ctx, name, false)
|
||||
assert.NilError(t, err)
|
||||
|
||||
var inspectJSON map[string]interface{}
|
||||
err = json.Unmarshal(b, &inspectJSON)
|
||||
assert.NilError(t, err)
|
||||
|
||||
cfg, ok := inspectJSON["HostConfig"].(map[string]interface{})
|
||||
assert.Check(t, is.Equal(true, ok), name)
|
||||
|
||||
readonlyPaths, ok := cfg["ReadonlyPaths"].([]interface{})
|
||||
assert.Check(t, is.Equal(true, ok), name)
|
||||
|
||||
rops := []string{}
|
||||
for _, rop := range readonlyPaths {
|
||||
rops = append(rops, rop.(string))
|
||||
}
|
||||
assert.DeepEqual(t, expected, rops)
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
name := fmt.Sprintf("create-readonly-paths-%d", i)
|
||||
config := container.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"true"},
|
||||
}
|
||||
hc := container.HostConfig{}
|
||||
if tc.readonlyPaths != nil {
|
||||
hc.ReadonlyPaths = tc.readonlyPaths
|
||||
}
|
||||
|
||||
// Create the container.
|
||||
c, err := client.ContainerCreate(context.Background(),
|
||||
&config,
|
||||
&hc,
|
||||
&network.NetworkingConfig{},
|
||||
name,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
checkInspect(t, ctx, name, tc.expected)
|
||||
|
||||
// Start the container.
|
||||
err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
poll.WaitOn(t, ctr.IsInState(ctx, client, c.ID, "exited"), poll.WithDelay(100*time.Millisecond))
|
||||
|
||||
checkInspect(t, ctx, name, tc.expected)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user