github.com/demonoid81/containerd@v1.3.4/rootfs/init_linux.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 rootfs 18 19 import ( 20 "os" 21 "path/filepath" 22 "syscall" 23 ) 24 25 const ( 26 defaultInitializer = "linux-init" 27 ) 28 29 func init() { 30 initializers[defaultInitializer] = initFS 31 } 32 33 func createDirectory(name string, uid, gid int) initializerFunc { 34 return func(root string) error { 35 dname := filepath.Join(root, name) 36 st, err := os.Stat(dname) 37 if err != nil && !os.IsNotExist(err) { 38 return err 39 } else if err == nil { 40 if st.IsDir() { 41 stat := st.Sys().(*syscall.Stat_t) 42 if int(stat.Gid) == gid && int(stat.Uid) == uid { 43 return nil 44 } 45 } else { 46 if err := os.Remove(dname); err != nil { 47 return err 48 } 49 if err := os.Mkdir(dname, 0755); err != nil { 50 return err 51 } 52 } 53 } else { 54 if err := os.Mkdir(dname, 0755); err != nil { 55 return err 56 } 57 } 58 59 return os.Chown(dname, uid, gid) 60 } 61 } 62 63 func touchFile(name string, uid, gid int) initializerFunc { 64 return func(root string) error { 65 fname := filepath.Join(root, name) 66 67 st, err := os.Stat(fname) 68 if err != nil && !os.IsNotExist(err) { 69 return err 70 } else if err == nil { 71 stat := st.Sys().(*syscall.Stat_t) 72 if int(stat.Gid) == gid && int(stat.Uid) == uid { 73 return nil 74 } 75 return os.Chown(fname, uid, gid) 76 } 77 78 f, err := os.OpenFile(fname, os.O_CREATE, 0644) 79 if err != nil { 80 return err 81 } 82 defer f.Close() 83 84 return f.Chown(uid, gid) 85 } 86 } 87 88 func symlink(oldname, newname string) initializerFunc { 89 return func(root string) error { 90 linkName := filepath.Join(root, newname) 91 if _, err := os.Stat(linkName); err != nil && !os.IsNotExist(err) { 92 return err 93 } else if err == nil { 94 return nil 95 } 96 return os.Symlink(oldname, linkName) 97 } 98 } 99 100 func initFS(root string) error { 101 st, err := os.Stat(root) 102 if err != nil { 103 return err 104 } 105 stat := st.Sys().(*syscall.Stat_t) 106 uid := int(stat.Uid) 107 gid := int(stat.Gid) 108 109 initFuncs := []initializerFunc{ 110 createDirectory("/dev", uid, gid), 111 createDirectory("/dev/pts", uid, gid), 112 createDirectory("/dev/shm", uid, gid), 113 touchFile("/dev/console", uid, gid), 114 createDirectory("/proc", uid, gid), 115 createDirectory("/sys", uid, gid), 116 createDirectory("/etc", uid, gid), 117 touchFile("/etc/resolv.conf", uid, gid), 118 touchFile("/etc/hosts", uid, gid), 119 touchFile("/etc/hostname", uid, gid), 120 symlink("/proc/mounts", "/etc/mtab"), 121 } 122 123 for _, fn := range initFuncs { 124 if err := fn(root); err != nil { 125 return err 126 } 127 } 128 129 return nil 130 }