github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/rkt/rkt.go (about) 1 // Copyright 2014 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 "fmt" 19 "io" 20 "os" 21 "path/filepath" 22 "strings" 23 "text/tabwriter" 24 25 "github.com/coreos/rkt/Godeps/_workspace/src/github.com/spf13/cobra" 26 "github.com/coreos/rkt/common" 27 "github.com/coreos/rkt/pkg/keystore" 28 "github.com/coreos/rkt/pkg/multicall" 29 "github.com/coreos/rkt/rkt/config" 30 ) 31 32 const ( 33 cliName = "rkt" 34 cliDescription = "rkt, the application container runner" 35 36 defaultDataDir = "/var/lib/rkt" 37 ) 38 39 type absDir string 40 41 func (d *absDir) String() string { 42 return (string)(*d) 43 } 44 45 func (d *absDir) Set(str string) error { 46 if str == "" { 47 return fmt.Errorf(`"" is not a valid directory`) 48 } 49 50 dir, err := filepath.Abs(str) 51 if err != nil { 52 return err 53 } 54 *d = (absDir)(dir) 55 return nil 56 } 57 58 func (d *absDir) Type() string { 59 return "absolute-directory" 60 } 61 62 var ( 63 tabOut *tabwriter.Writer 64 globalFlags = struct { 65 Dir string 66 SystemConfigDir string 67 LocalConfigDir string 68 Debug bool 69 Help bool 70 InsecureSkipVerify bool 71 TrustKeysFromHttps bool 72 }{ 73 Dir: defaultDataDir, 74 SystemConfigDir: common.DefaultSystemConfigDir, 75 LocalConfigDir: common.DefaultLocalConfigDir, 76 } 77 78 cmdExitCode int 79 ) 80 81 var cmdRkt = &cobra.Command{ 82 Use: "rkt [command]", 83 Short: cliDescription, 84 } 85 86 func init() { 87 cmdRkt.PersistentFlags().BoolVar(&globalFlags.Debug, "debug", false, "print out more debug information to stderr") 88 cmdRkt.PersistentFlags().Var((*absDir)(&globalFlags.Dir), "dir", "rkt data directory") 89 cmdRkt.PersistentFlags().Var((*absDir)(&globalFlags.SystemConfigDir), "system-config", "system configuration directory") 90 cmdRkt.PersistentFlags().Var((*absDir)(&globalFlags.LocalConfigDir), "local-config", "local configuration directory") 91 cmdRkt.PersistentFlags().BoolVar(&globalFlags.InsecureSkipVerify, "insecure-skip-verify", false, "skip all TLS, image or fingerprint verification") 92 cmdRkt.PersistentFlags().BoolVar(&globalFlags.TrustKeysFromHttps, "trust-keys-from-https", true, "automatically trust gpg keys fetched from https") 93 } 94 95 func init() { 96 cobra.EnablePrefixMatching = true 97 } 98 99 func getTabOutWithWriter(writer io.Writer) *tabwriter.Writer { 100 aTabOut := new(tabwriter.Writer) 101 aTabOut.Init(writer, 0, 8, 1, '\t', 0) 102 return aTabOut 103 } 104 105 // runWrapper return a func(cmd *cobra.Command, args []string) that internally 106 // will add command function return code and the reinsertion of the "--" flag 107 // terminator. 108 func runWrapper(cf func(cmd *cobra.Command, args []string) (exit int)) func(cmd *cobra.Command, args []string) { 109 return func(cmd *cobra.Command, args []string) { 110 cmdExitCode = cf(cmd, args) 111 } 112 } 113 114 func main() { 115 // check if rkt is executed with a multicall command 116 multicall.MaybeExec() 117 118 cmdRkt.SetUsageFunc(usageFunc) 119 120 // Make help just show the usage 121 cmdRkt.SetHelpTemplate(`{{.UsageString}}`) 122 123 cmdRkt.Execute() 124 os.Exit(cmdExitCode) 125 } 126 127 func stderr(format string, a ...interface{}) { 128 out := fmt.Sprintf(format, a...) 129 fmt.Fprintln(os.Stderr, strings.TrimSuffix(out, "\n")) 130 } 131 132 func stdout(format string, a ...interface{}) { 133 out := fmt.Sprintf(format, a...) 134 fmt.Fprintln(os.Stdout, strings.TrimSuffix(out, "\n")) 135 } 136 137 // where pod directories are created and locked before moving to prepared 138 func embryoDir() string { 139 return filepath.Join(globalFlags.Dir, "pods", "embryo") 140 } 141 142 // where pod trees reside during (locked) and after failing to complete preparation (unlocked) 143 func prepareDir() string { 144 return filepath.Join(globalFlags.Dir, "pods", "prepare") 145 } 146 147 // where pod trees reside upon successful preparation 148 func preparedDir() string { 149 return filepath.Join(globalFlags.Dir, "pods", "prepared") 150 } 151 152 // where pod trees reside once run 153 func runDir() string { 154 return filepath.Join(globalFlags.Dir, "pods", "run") 155 } 156 157 // where pod trees reside once exited & marked as garbage by a gc pass 158 func exitedGarbageDir() string { 159 return filepath.Join(globalFlags.Dir, "pods", "exited-garbage") 160 } 161 162 // where never-executed pod trees reside once marked as garbage by a gc pass (failed prepares, expired prepareds) 163 func garbageDir() string { 164 return filepath.Join(globalFlags.Dir, "pods", "garbage") 165 } 166 167 func getKeystore() *keystore.Keystore { 168 if globalFlags.InsecureSkipVerify { 169 return nil 170 } 171 config := keystore.NewConfig(globalFlags.SystemConfigDir, globalFlags.LocalConfigDir) 172 return keystore.New(config) 173 } 174 175 func getConfig() (*config.Config, error) { 176 return config.GetConfigFrom(globalFlags.SystemConfigDir, globalFlags.LocalConfigDir) 177 } 178 179 func lockDir() string { 180 return filepath.Join(globalFlags.Dir, "locks") 181 }