github.com/containerd/Containerd@v1.4.13/runtime/v2/bundle_linux_test.go (about) 1 /* 2 Copyright The containerd Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package v2 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "io/ioutil" 24 "os" 25 "path/filepath" 26 "strconv" 27 "syscall" 28 "testing" 29 30 "github.com/containerd/containerd/namespaces" 31 "github.com/containerd/containerd/oci" 32 "github.com/containerd/containerd/pkg/testutil" 33 "github.com/opencontainers/runtime-spec/specs-go" 34 ) 35 36 func TestNewBundle(t *testing.T) { 37 testutil.RequiresRoot(t) 38 tests := []struct { 39 userns bool 40 }{{ 41 userns: false, 42 }, { 43 userns: true, 44 }} 45 const usernsGID = 4200 46 47 for i, tc := range tests { 48 t.Run(strconv.Itoa(i), func(t *testing.T) { 49 dir, err := ioutil.TempDir("", "test-new-bundle") 50 if err != nil { 51 t.Fatal("failed to create test directory", err) 52 } 53 defer os.RemoveAll(dir) 54 work := filepath.Join(dir, "work") 55 state := filepath.Join(dir, "state") 56 id := fmt.Sprintf("new-bundle-%d", i) 57 spec := oci.Spec{} 58 if tc.userns { 59 spec.Linux = &specs.Linux{ 60 GIDMappings: []specs.LinuxIDMapping{{ContainerID: 0, HostID: usernsGID}}, 61 } 62 } 63 specBytes, err := json.Marshal(&spec) 64 if err != nil { 65 t.Fatal("failed to marshal spec", err) 66 } 67 68 ctx := namespaces.WithNamespace(context.TODO(), namespaces.Default) 69 b, err := NewBundle(ctx, work, state, id, specBytes) 70 if err != nil { 71 t.Fatal("NewBundle should succeed", err) 72 } 73 if b == nil { 74 t.Fatal("bundle should not be nil") 75 } 76 77 fi, err := os.Stat(b.Path) 78 if err != nil { 79 t.Error("should be able to stat bundle path", err) 80 } 81 if tc.userns { 82 if fi.Mode() != os.ModeDir|0710 { 83 t.Error("bundle path should be a directory with perm 0710") 84 } 85 } else { 86 if fi.Mode() != os.ModeDir|0700 { 87 t.Error("bundle path should be a directory with perm 0700") 88 } 89 } 90 stat, ok := fi.Sys().(*syscall.Stat_t) 91 if !ok { 92 t.Fatal("should assert to *syscall.Stat_t") 93 } 94 expectedGID := uint32(0) 95 if tc.userns { 96 expectedGID = usernsGID 97 } 98 if expectedGID != stat.Gid { 99 t.Error("gid should match", expectedGID, stat.Gid) 100 } 101 }) 102 } 103 } 104 105 func TestRemappedGID(t *testing.T) { 106 tests := []struct { 107 spec oci.Spec 108 gid uint32 109 }{{ 110 // empty spec 111 spec: oci.Spec{}, 112 gid: 0, 113 }, { 114 // empty Linux section 115 spec: oci.Spec{ 116 Linux: &specs.Linux{}, 117 }, 118 gid: 0, 119 }, { 120 // empty ID mappings 121 spec: oci.Spec{ 122 Linux: &specs.Linux{ 123 GIDMappings: make([]specs.LinuxIDMapping, 0), 124 }, 125 }, 126 gid: 0, 127 }, { 128 // valid ID mapping 129 spec: oci.Spec{ 130 Linux: &specs.Linux{ 131 GIDMappings: []specs.LinuxIDMapping{{ 132 ContainerID: 0, 133 HostID: 1000, 134 }}, 135 }, 136 }, 137 gid: 1000, 138 }, { 139 // missing ID mapping 140 spec: oci.Spec{ 141 Linux: &specs.Linux{ 142 GIDMappings: []specs.LinuxIDMapping{{ 143 ContainerID: 100, 144 HostID: 1000, 145 }}, 146 }, 147 }, 148 gid: 0, 149 }} 150 151 for i, tc := range tests { 152 t.Run(strconv.Itoa(i), func(t *testing.T) { 153 s, err := json.Marshal(tc.spec) 154 if err != nil { 155 t.Fatal("failed to marshal spec", err) 156 } 157 gid, err := remappedGID(s) 158 if err != nil { 159 t.Error("should unmarshal successfully", err) 160 } 161 if tc.gid != gid { 162 t.Error("expected GID to match", tc.gid, gid) 163 } 164 }) 165 } 166 }