github.com/mfpierre/corectl@v0.5.6/ps.go (about) 1 // Copyright 2015 - António Meireles <antonio.meireles@reformi.st> 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 16 package main 17 18 import ( 19 "encoding/json" 20 "fmt" 21 "io/ioutil" 22 "log" 23 "os" 24 "path/filepath" 25 "strconv" 26 "text/tabwriter" 27 "time" 28 29 "github.com/spf13/cobra" 30 ) 31 32 var ( 33 psCmd = &cobra.Command{ 34 Use: "ps", 35 Aliases: []string{"status"}, 36 Short: "Lists running CoreOS instances", 37 PreRunE: defaultPreRunE, 38 RunE: psCommand, 39 } 40 queryCmd = &cobra.Command{ 41 Use: "query [VMids]", 42 Aliases: []string{"q"}, 43 Short: "Display information about the running CoreOS instances", 44 PreRunE: func(cmd *cobra.Command, args []string) (err error) { 45 engine.rawArgs.BindPFlags(cmd.Flags()) 46 if engine.rawArgs.GetBool("ip") && len(args) != 1 { 47 err = fmt.Errorf(" -i, --ip is only allowed when there's one " + 48 "and only one argument (a VM's name or UUID).") 49 } 50 return err 51 }, 52 RunE: queryCommand, 53 } 54 ) 55 56 func queryCommand(cmd *cobra.Command, args []string) (err error) { 57 var ( 58 pp []byte 59 running, selected []VMInfo 60 vm VMInfo 61 tabP = func(selected []VMInfo) { 62 w := new(tabwriter.Writer) 63 w.Init(os.Stdout, 5, 0, 1, ' ', 0) 64 fmt.Fprintf(w, "name\tchannel/version\tip\tcpu(s)\tram\tuuid\tpid"+ 65 "\tuptime\tvols\n") 66 for _, vm = range selected { 67 fmt.Fprintf(w, "%v\t%v/%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", 68 vm.Name, vm.Channel, vm.Version, vm.PublicIP, vm.Cpus, 69 vm.Memory, vm.UUID, vm.Pid, time.Now().Sub(vm.CreatedAt), 70 len(vm.Storage.HardDrives)) 71 } 72 w.Flush() 73 } 74 ) 75 if running, err = allRunningInstances(); err != nil { 76 return 77 } 78 if len(args) == 0 { 79 if engine.rawArgs.GetBool("json") { 80 if pp, err = json.MarshalIndent(running, "", " "); err == nil { 81 fmt.Println(string(pp)) 82 } 83 return 84 } 85 if engine.rawArgs.GetBool("all") { 86 tabP(running) 87 return 88 } 89 for _, vm := range running { 90 fmt.Println(vm.Name) 91 } 92 return 93 } 94 if len(args) == 1 && engine.rawArgs.GetBool("ip") { 95 if vm, err = vmInfo(args[0]); err != nil { 96 return 97 } 98 fmt.Println(vm.PublicIP) 99 return 100 } 101 for _, target := range args { 102 if vm, err = vmInfo(target); err != nil { 103 return 104 } 105 selected = append(selected, vm) 106 } 107 if engine.rawArgs.GetBool("json") { 108 if pp, err = json.MarshalIndent(selected, "", " "); err == nil { 109 fmt.Println(string(pp)) 110 } 111 return 112 } 113 if engine.rawArgs.GetBool("all") { 114 tabP(selected) 115 return 116 } 117 for _, vm := range selected { 118 fmt.Println(vm.Name) 119 } 120 return 121 } 122 123 func psCommand(cmd *cobra.Command, args []string) (err error) { 124 var ( 125 pp []byte 126 running []VMInfo 127 ) 128 129 if running, err = allRunningInstances(); err != nil { 130 return 131 } 132 if engine.rawArgs.GetBool("json") { 133 if pp, err = json.MarshalIndent(running, "", " "); err == nil { 134 fmt.Println(string(pp)) 135 } 136 return 137 } 138 totalV, totalM, totalC := len(running), 0, 0 139 for _, vm := range running { 140 totalC, totalM = totalC+vm.Cpus, totalM+vm.Memory 141 } 142 log.Printf("found %v running VMs, summing %v vCPUs and %vMB in use.\n", 143 totalV, totalC, totalM) 144 for _, vm := range running { 145 vm.pp(engine.rawArgs.GetBool("all")) 146 } 147 return 148 } 149 150 func allRunningInstances() (alive []VMInfo, err error) { 151 var ls []os.FileInfo 152 153 if ls, err = ioutil.ReadDir(engine.runDir); err != nil { 154 return 155 } 156 for _, d := range ls { 157 if r, e := runningConfig(d.Name()); e == nil { 158 alive = append(alive, r) 159 } 160 } 161 return 162 } 163 164 func (vm *VMInfo) pp(extended bool) { 165 fmt.Printf("- %v, %v/%v, PID %v (detached=%v), up %v\n", 166 vm.Name, vm.Channel, vm.Version, vm.Pid, vm.Detached, 167 time.Now().Sub(vm.CreatedAt)) 168 fmt.Printf(" - %v vCPU(s), %v RAM\n", vm.Cpus, vm.Memory) 169 if vm.CloudConfig != "" { 170 fmt.Printf(" - cloud-config: %v\n", vm.CloudConfig) 171 } 172 fmt.Println(" - Network Interfaces:") 173 fmt.Printf(" - eth0 (public interface) %v\n", vm.PublicIP) 174 if len(vm.Ethernet) > 1 { 175 fmt.Printf(" - eth1 (private interface/%v on host)\n", vm.Ethernet[1].Path) 176 } 177 vm.Storage.pp(vm.Root) 178 if extended { 179 fmt.Printf(" - UUID: %v\n", vm.UUID) 180 if vm.SSHkey != "" { 181 fmt.Printf(" - ssh key: %v\n", vm.SSHkey) 182 } 183 if vm.Extra != "" { 184 fmt.Printf(" - custom args to xhyve: %v\n", vm.Extra) 185 } 186 } 187 } 188 189 func (volumes *storageAssets) pp(root int) { 190 if len(volumes.CDDrives)+len(volumes.HardDrives) > 0 { 191 fmt.Println(" - Volumes:") 192 for a, b := range volumes.CDDrives { 193 fmt.Printf(" - /dev/cdrom%v (%s)\n", a, b.Path) 194 } 195 for a, b := range volumes.HardDrives { 196 i, _ := strconv.Atoi(a) 197 if i != root { 198 fmt.Printf(" - /dev/vd%v (%s)\n", string(i+'a'), b.Path) 199 } else { 200 fmt.Printf(" - /,/dev/vd%v (%s)\n", string(i+'a'), b.Path) 201 } 202 } 203 } 204 } 205 206 func runningConfig(uuid string) (vm VMInfo, err error) { 207 var buf []byte 208 if buf, err = 209 ioutil.ReadFile(filepath.Join(engine.runDir, 210 uuid, "/config")); err != nil { 211 return 212 } 213 json.Unmarshal(buf, &vm) 214 if !vm.isActive() { 215 return vm, fmt.Errorf("dead") 216 } 217 return 218 } 219 220 func init() { 221 psCmd.Flags().BoolP("all", "a", false, 222 "shows extended information about running CoreOS instances") 223 psCmd.Flags().BoolP("json", "j", false, 224 "outputs in JSON for easy 3rd party integration") 225 RootCmd.AddCommand(psCmd) 226 227 queryCmd.Flags().BoolP("json", "j", false, 228 "outputs in JSON for easy 3rd party integration") 229 queryCmd.Flags().BoolP("all", "a", false, 230 "display extended information about a running CoreOS instance") 231 queryCmd.Flags().BoolP("ip", "i", false, 232 "displays given instance IP address") 233 RootCmd.AddCommand(queryCmd) 234 }