github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/cmd/root.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "runtime" 9 "sort" 10 11 "github.com/sirupsen/logrus" 12 "github.com/spf13/cobra" 13 "gopkg.in/yaml.v2" 14 15 "github.com/solo-io/unik/pkg/config" 16 "github.com/solo-io/unik/pkg/types" 17 ) 18 19 var clientConfigFile, hubConfigFile, host string 20 var port int 21 22 var RootCmd = &cobra.Command{ 23 Use: "unik", 24 Short: "The unikernel compilation, deployment, and management tool", 25 Long: `Unik is a tool for compiling application source code 26 into bootable disk images. Unik also runs and manages unikernel 27 instances across infrastructures. 28 29 Create a client configuration file with 'unik target' 30 31 You may set a custom client configuration file 32 with the global flag --client-config=<path>`, 33 } 34 35 func getHomeDir() string { 36 if runtime.GOOS == "windows" { 37 return os.Getenv("USERPROFILE") 38 } else { 39 return os.Getenv("HOME") 40 } 41 } 42 43 func init() { 44 RootCmd.PersistentFlags().StringVar(&clientConfigFile, "client-config", getHomeDir()+"/.unik/client-config.yaml", "client config file") 45 RootCmd.PersistentFlags().StringVar(&hubConfigFile, "hub-config", getHomeDir()+"/.unik/hub-config.yaml", "hub config file") 46 RootCmd.PersistentFlags().StringVar(&host, "host", "", "<string, optional>: host/ip address of the host running the unik daemon") 47 targetCmd.Flags().IntVar(&port, "port", 3000, "<int, optional>: port the daemon is running on (default: 3000)") 48 } 49 50 var clientConfig config.ClientConfig 51 52 func readClientConfig() error { 53 data, err := ioutil.ReadFile(clientConfigFile) 54 if err != nil { 55 logrus.WithError(err).Errorf("failed to read client configuration file at " + clientConfigFile + ` 56 Try setting your config with 'unik target --host HOST_URL'`) 57 return err 58 } 59 data = bytes.Replace(data, []byte("\n"), []byte{}, -1) 60 if err := yaml.Unmarshal(data, &clientConfig); err != nil { 61 logrus.WithError(err).Errorf("failed to parse client configuration yaml at " + clientConfigFile + ` 62 Please ensure config file contains valid yaml.'\n 63 Try setting your config with 'unik target --host HOST_URL'`) 64 return err 65 } 66 return nil 67 } 68 69 type imageSlice []*types.Image 70 71 func (p imageSlice) Len() int { return len(p) } 72 func (p imageSlice) Less(i, j int) bool { return p[i].Name < p[j].Name } 73 func (p imageSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 74 75 // Sort is a convenience method. 76 func (p imageSlice) Sort() { sort.Sort(p) } 77 78 func printImages(images ...*types.Image) { 79 sortedImages := make(imageSlice, len(images)) 80 for i, image := range images { 81 sortedImages[i] = image 82 } 83 sortedImages.Sort() 84 fmt.Printf("%-20s %-20s %-15s %-30s %-6s %-20s\n", "NAME", "ID", "INFRASTRUCTURE", "CREATED", "SIZE(MB)", "MOUNTPOINTS") 85 for _, image := range sortedImages { 86 printImage(image) 87 } 88 } 89 90 func printImage(image *types.Image) { 91 for i, deviceMapping := range image.RunSpec.DeviceMappings { 92 //ignore root device mount point 93 if deviceMapping.MountPoint == "/" { 94 image.RunSpec.DeviceMappings = append(image.RunSpec.DeviceMappings[:i], image.RunSpec.DeviceMappings[i+1:]...) 95 } 96 } 97 if len(image.RunSpec.DeviceMappings) == 0 { 98 fmt.Printf("%-20.20s %-20.20s %-15.15s %-30.30s %-8.0d \n", image.Name, image.Id, image.Infrastructure, image.Created.String(), image.SizeMb) 99 } else if len(image.RunSpec.DeviceMappings) > 0 { 100 fmt.Printf("%-20.20s %-20.20s %-15.15s %-30.30s %-8.0d %-20.20s\n", image.Name, image.Id, image.Infrastructure, image.Created.String(), image.SizeMb, image.RunSpec.DeviceMappings[0].MountPoint) 101 if len(image.RunSpec.DeviceMappings) > 1 { 102 for i := 1; i < len(image.RunSpec.DeviceMappings); i++ { 103 fmt.Printf("%102s\n", image.RunSpec.DeviceMappings[i].MountPoint) 104 } 105 } 106 } 107 } 108 109 type userImageSlice []*types.UserImage 110 111 func (p userImageSlice) Len() int { return len(p) } 112 func (p userImageSlice) Less(i, j int) bool { return p[i].Name < p[j].Name } 113 func (p userImageSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 114 115 // Sort is a convenience method. 116 func (p userImageSlice) Sort() { sort.Sort(p) } 117 118 func printUserImages(images ...*types.UserImage) { 119 sortedImages := make(userImageSlice, len(images)) 120 for i, image := range images { 121 sortedImages[i] = image 122 } 123 sortedImages.Sort() 124 fmt.Printf("%-20s %-20s %-15s %-30s %-6s %-20s\n", "NAME", "OWNER", "INFRASTRUCTURE", "CREATED", "SIZE(MB)", "MOUNTPOINTS") 125 for _, image := range sortedImages { 126 printUserImage(image) 127 } 128 } 129 130 func printUserImage(image *types.UserImage) { 131 for i, deviceMapping := range image.RunSpec.DeviceMappings { 132 //ignore root device mount point 133 if deviceMapping.MountPoint == "/" { 134 image.RunSpec.DeviceMappings = append(image.RunSpec.DeviceMappings[:i], image.RunSpec.DeviceMappings[i+1:]...) 135 } 136 } 137 if len(image.RunSpec.DeviceMappings) == 0 { 138 fmt.Printf("%-20.20s %-20.20s %-15.15s %-30.30s %-8.0d \n", image.Name, image.Owner, image.Infrastructure, image.Created.String(), image.SizeMb) 139 } else if len(image.RunSpec.DeviceMappings) > 0 { 140 fmt.Printf("%-20.20s %-20.20s %-15.15s %-30.30s %-8.0d %-20.20s\n", image.Name, image.Owner, image.Infrastructure, image.Created.String(), image.SizeMb, image.RunSpec.DeviceMappings[0].MountPoint) 141 if len(image.RunSpec.DeviceMappings) > 1 { 142 for i := 1; i < len(image.RunSpec.DeviceMappings); i++ { 143 fmt.Printf("%102s\n", image.RunSpec.DeviceMappings[i].MountPoint) 144 } 145 } 146 } 147 } 148 149 type instanceSlice []*types.Instance 150 151 func (p instanceSlice) Len() int { return len(p) } 152 func (p instanceSlice) Less(i, j int) bool { return p[i].Name < p[j].Name } 153 func (p instanceSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 154 155 // Sort is a convenience method. 156 func (p instanceSlice) Sort() { sort.Sort(p) } 157 158 func printInstances(instances ...*types.Instance) { 159 sortedInstances := make(instanceSlice, len(instances)) 160 for i, instance := range instances { 161 sortedInstances[i] = instance 162 } 163 sortedInstances.Sort() 164 fmt.Printf("%-15s %-20s %-14s %-30s %-20s %-15s %-12s\n", 165 "NAME", "ID", "INFRASTRUCTURE", "CREATED", "IMAGE", "IPADDRESS", "STATE") 166 for _, instance := range sortedInstances { 167 printInstance(instance) 168 } 169 } 170 171 func printInstance(instance *types.Instance) { 172 fmt.Printf("%-15.15s %-20.20s %-14.14s %-30.30s %-20.20v %-15.15s %-12.12s\n", 173 instance.Name, instance.Id, instance.Infrastructure, instance.Created.String(), instance.ImageId, instance.IpAddress, instance.State) 174 } 175 176 func printVolumes(volume ...*types.Volume) { 177 fmt.Printf("%-15.15s %-15.15s %-14.14s %-30.30s %-20.20v %-12.12s\n", 178 "NAME", "ID", "INFRASTRUCTURE", "CREATED", "ATTACHED-INSTANCE", "SIZE(MB)") 179 for _, volume := range volume { 180 printVolume(volume) 181 } 182 } 183 184 func printVolume(volume *types.Volume) { 185 fmt.Printf("%-15.15s %-15.15s %-14.14s %-30.30s %-20.20v %-12.12d\n", 186 volume.Name, volume.Id, volume.Infrastructure, volume.Created.String(), volume.Attachment, volume.SizeMb) 187 }