github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/rkt/install.go (about) 1 // Copyright 2015 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "crypto/sha1" 19 "fmt" 20 "io" 21 "os" 22 "path/filepath" 23 24 "github.com/coreos/rkt/Godeps/_workspace/src/github.com/spf13/cobra" 25 "github.com/coreos/rkt/common" 26 "github.com/coreos/rkt/store" 27 ) 28 29 const casDbPerm = os.FileMode(0660) 30 31 var ( 32 cmdInstall = &cobra.Command{ 33 Use: "install", 34 Short: "Set up rkt data directories with correct permissions", 35 Run: runWrapper(runInstall), 36 } 37 38 // dirs relative to globalFlags.Dir 39 dirs = map[string]os.FileMode{ 40 ".": os.FileMode(0750 | os.ModeSetgid), 41 "tmp": os.FileMode(0750 | os.ModeSetgid), 42 43 // Cas directories. 44 // Make sure 'rkt' group can read/write some of the 'cas' 45 // directories so that users in the group can fetch images 46 "cas": os.FileMode(0770 | os.ModeSetgid), 47 "cas/db": os.FileMode(0770 | os.ModeSetgid), 48 "cas/imagelocks": os.FileMode(0770 | os.ModeSetgid), 49 "cas/imageManifest": os.FileMode(0770 | os.ModeSetgid), 50 "cas/blob": os.FileMode(0770 | os.ModeSetgid), 51 "cas/tmp": os.FileMode(0770 | os.ModeSetgid), 52 "cas/tree": os.FileMode(0700 | os.ModeSetgid), 53 "cas/treestorelocks": os.FileMode(0700 | os.ModeSetgid), 54 "locks": os.FileMode(0750 | os.ModeSetgid), 55 56 // Pods directories. 57 "pods": os.FileMode(0750 | os.ModeSetgid), 58 "pods/embryo": os.FileMode(0750 | os.ModeSetgid), 59 "pods/prepare": os.FileMode(0750 | os.ModeSetgid), 60 "pods/prepared": os.FileMode(0750 | os.ModeSetgid), 61 "pods/run": os.FileMode(0750 | os.ModeSetgid), 62 "pods/exited-garbage": os.FileMode(0750 | os.ModeSetgid), 63 "pods/garbage": os.FileMode(0750 | os.ModeSetgid), 64 } 65 ) 66 67 func init() { 68 cmdRkt.AddCommand(cmdInstall) 69 } 70 71 func createFileWithPermissions(path string, uid int, gid int, perm os.FileMode) error { 72 _, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666) 73 if err != nil { 74 if !os.IsExist(err) { 75 return err 76 } 77 // file exists 78 } 79 80 return setPermissions(path, uid, gid, perm) 81 } 82 83 func setPermissions(path string, uid int, gid int, perm os.FileMode) error { 84 if err := os.Chown(path, uid, gid); err != nil { 85 return fmt.Errorf("error setting %q directory group: %v", path, err) 86 } 87 88 if err := os.Chmod(path, perm); err != nil { 89 return fmt.Errorf("error setting %q directory permissions: %v", path, err) 90 } 91 92 return nil 93 } 94 95 func createDirStructure(gid int) error { 96 for dir, perm := range dirs { 97 path := filepath.Join(globalFlags.Dir, dir) 98 99 if err := os.MkdirAll(path, perm); err != nil { 100 return fmt.Errorf("error creating %q directory: %v", path, err) 101 } 102 103 if err := setPermissions(path, 0, gid, perm); err != nil { 104 return err 105 } 106 } 107 108 return nil 109 } 110 111 func setCasDbFilesPermissions(casDbPath string, gid int, perm os.FileMode) error { 112 casDbWalker := func(path string, info os.FileInfo, err error) error { 113 if err != nil { 114 return err 115 } 116 if info.Mode().IsRegular() { 117 if err := setPermissions(path, 0, gid, perm); err != nil { 118 return err 119 } 120 } 121 122 return nil 123 } 124 125 if err := filepath.Walk(casDbPath, casDbWalker); err != nil { 126 return err 127 } 128 129 return nil 130 } 131 132 func createDbFiles(casDbPath string, gid int, perm os.FileMode) error { 133 dbPath := filepath.Join(casDbPath, store.DbFilename) 134 if err := createFileWithPermissions(dbPath, 0, gid, perm); err != nil { 135 return fmt.Errorf("error creating %s: %v", dbPath, err) 136 } 137 138 // ql database uses a Write-Ahead Logging (WAL) file whose name is 139 // generated from the sha1 hash of the database name 140 h := sha1.New() 141 io.WriteString(h, store.DbFilename) 142 walFilename := fmt.Sprintf(".%x", h.Sum(nil)) 143 walFilePath := filepath.Join(casDbPath, walFilename) 144 if err := createFileWithPermissions(walFilePath, 0, gid, perm); err != nil { 145 return fmt.Errorf("error creating %s: %v", walFilename, err) 146 } 147 148 return nil 149 } 150 151 func runInstall(cmd *cobra.Command, args []string) (exit int) { 152 gid, err := common.LookupGid(common.RktGroup) 153 if err != nil { 154 stderr("install: error looking up rkt gid: %v", err) 155 return 1 156 } 157 158 if err := createDirStructure(gid); err != nil { 159 stderr("install: error creating rkt directory structure: %v", err) 160 return 1 161 } 162 163 casDbPath := filepath.Join(globalFlags.Dir, "cas", "db") 164 if err := setCasDbFilesPermissions(casDbPath, gid, casDbPerm); err != nil { 165 stderr("install: error setting cas db permissions: %v", err) 166 return 1 167 } 168 169 if err := createDbFiles(casDbPath, gid, casDbPerm); err != nil { 170 stderr("install: error creating db files: %v", err) 171 return 1 172 } 173 stderr("rkt directory structure successfully created.") 174 175 return 0 176 }