github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/providers/xen/xenclient/client.go (about) 1 package xenclient 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "os/exec" 9 "path/filepath" 10 11 "github.com/sirupsen/logrus" 12 "github.com/emc-advanced-dev/pkg/errors" 13 ) 14 15 const xenConfBase = ` 16 # Guest name 17 name = "%s" 18 19 kernel = "%s" 20 extra = "(hd0)/boot/grub/menu.lst" 21 22 # Initial memory allocation (MB) 23 memory = %d 24 25 # Number of VCPUS 26 vcpus = 1 27 28 # Network devices 29 # A list of 'vifspec' entries as described in 30 # docs/misc/xl-network-configuration.markdown 31 vif = [ 'bridge=%s' ] 32 33 # Disk Devices 34 # A list of 'diskspec' entries as described in 35 # docs/misc/xl-disk-configuration.txt 36 disk = [ '%s,raw,%s,rw'%s ] 37 38 on_poweroff = "preserve" 39 on_reboot = "preserve" 40 on_crash = "preserve" 41 ` 42 43 type XenClient struct { 44 KernelPath string 45 XenBridge string 46 } 47 48 type CreateVmParams struct { 49 Name string 50 Memory int 51 BootImage string 52 BootDeviceName string 53 VmDir string 54 DataVolumes []VolumeConfig 55 } 56 57 type VolumeConfig struct { 58 ImagePath string 59 DeviceName string 60 } 61 62 func (c *XenClient) CreateVm(params CreateVmParams) error { 63 volumes := "" 64 for _, vol := range params.DataVolumes { 65 volumes = fmt.Sprintf("%s, '%s,raw,%s,rw'", volumes, vol.ImagePath, vol.DeviceName) 66 } 67 xenConf := fmt.Sprintf(xenConfBase, params.Name, c.KernelPath, params.Memory, c.XenBridge, params.BootImage, params.BootDeviceName, volumes) 68 confFile := filepath.Join(params.VmDir, "xen.conf") 69 if err := ioutil.WriteFile(confFile, []byte(xenConf), 0644); err != nil { 70 return errors.New("writing xen conf file for vm", err) 71 } 72 73 logrus.Debugf("using xen config:\n%s", xenConf) 74 75 if _, err := xl("create", confFile); err != nil { 76 return errors.New("creating domain", err) 77 } 78 return nil 79 } 80 81 func (c *XenClient) DestroyVm(name string) error { 82 if _, err := xl("destroy", name); err != nil { 83 return errors.New("destroying domain", err) 84 } 85 return nil 86 } 87 88 func (c *XenClient) ListVms() (domList, error) { 89 res, err := xl("list", "-l") 90 if err != nil { 91 return nil, errors.New("getting xl list", err) 92 } 93 var domList domList 94 if err := json.Unmarshal(res, &domList); err != nil { 95 return nil, errors.New("parsing "+string(res)+" as domain list", err) 96 } 97 return domList, nil 98 } 99 100 func xl(args ...string) ([]byte, error) { 101 cmd := exec.Command("xl", args...) 102 errBuf := &bytes.Buffer{} 103 cmd.Stderr = errBuf 104 out, err := cmd.Output() 105 if err != nil { 106 return out, errors.New(errBuf.String(), err) 107 } 108 return out, nil 109 } 110 111 type domList []struct { 112 Config struct { 113 OnCrash string `json:"on_crash"` 114 OnWatchdog string `json:"on_watchdog"` 115 OnReboot string `json:"on_reboot"` 116 OnPoweroff string `json:"on_poweroff"` 117 CInfo struct { 118 DriverDomain string `json:"driver_domain"` 119 Pvh string `json:"pvh"` 120 RunHotplugScripts string `json:"run_hotplug_scripts"` 121 Poolid int `json:"poolid"` 122 Type string `json:"type"` 123 Hap string `json:"hap"` 124 Oos string `json:"oos"` 125 Ssidref int `json:"ssidref"` 126 Name string `json:"name"` 127 UUID string `json:"uuid"` 128 Xsdata struct { 129 } `json:"xsdata"` 130 Platformdata struct { 131 } `json:"platformdata"` 132 } `json:"c_info"` 133 BInfo struct { 134 U struct { 135 E820Host string `json:"e820_host"` 136 Ramdisk interface{} `json:"ramdisk"` 137 Cmdline string `json:"cmdline"` 138 BootloaderArgs []interface{} `json:"bootloader_args"` 139 Bootloader interface{} `json:"bootloader"` 140 SlackMemkb int `json:"slack_memkb"` 141 Kernel string `json:"kernel"` 142 } `json:"u"` 143 EventChannels int `json:"event_channels"` 144 ClaimMode string `json:"claim_mode"` 145 Iomem []interface{} `json:"iomem"` 146 Irqs []interface{} `json:"irqs"` 147 Ioports []interface{} `json:"ioports"` 148 SchedParams struct { 149 Extratime int `json:"extratime"` 150 Latency int `json:"latency"` 151 Slice int `json:"slice"` 152 Period int `json:"period"` 153 Cap int `json:"cap"` 154 Weight int `json:"weight"` 155 Sched string `json:"sched"` 156 } `json:"sched_params"` 157 ExtraHvm []interface{} `json:"extra_hvm"` 158 ExtraPv []interface{} `json:"extra_pv"` 159 Extra []interface{} `json:"extra"` 160 DeviceModelSsidref int `json:"device_model_ssidref"` 161 DeviceModel interface{} `json:"device_model"` 162 DeviceModelStubdomain string `json:"device_model_stubdomain"` 163 DeviceModelVersion string `json:"device_model_version"` 164 TargetMemkb int `json:"target_memkb"` 165 MaxMemkb int `json:"max_memkb"` 166 TscMode string `json:"tsc_mode"` 167 NumaPlacement string `json:"numa_placement"` 168 Nodemap []interface{} `json:"nodemap"` 169 Cpumap []interface{} `json:"cpumap"` 170 AvailVcpus []int `json:"avail_vcpus"` 171 MaxVcpus int `json:"max_vcpus"` 172 VideoMemkb int `json:"video_memkb"` 173 ShadowMemkb int `json:"shadow_memkb"` 174 RtcTimeoffset int `json:"rtc_timeoffset"` 175 ExecSsidref int `json:"exec_ssidref"` 176 Localtime string `json:"localtime"` 177 DisableMigrate string `json:"disable_migrate"` 178 Cpuid []interface{} `json:"cpuid"` 179 BlkdevStart interface{} `json:"blkdev_start"` 180 } `json:"b_info"` 181 Disks []struct { 182 IsCdrom int `json:"is_cdrom"` 183 Readwrite int `json:"readwrite"` 184 BackendDomid int `json:"backend_domid"` 185 BackendDomname interface{} `json:"backend_domname"` 186 PdevPath string `json:"pdev_path"` 187 Vdev string `json:"vdev"` 188 Backend string `json:"backend"` 189 Format string `json:"format"` 190 Script interface{} `json:"script"` 191 Removable int `json:"removable"` 192 } `json:"disks"` 193 Nics []struct { 194 Gatewaydev interface{} `json:"gatewaydev"` 195 RateIntervalUsecs int `json:"rate_interval_usecs"` 196 RateBytesPerInterval int `json:"rate_bytes_per_interval"` 197 Nictype string `json:"nictype"` 198 Script interface{} `json:"script"` 199 Ifname interface{} `json:"ifname"` 200 BackendDomid int `json:"backend_domid"` 201 BackendDomname interface{} `json:"backend_domname"` 202 Devid int `json:"devid"` 203 Mtu int `json:"mtu"` 204 Model interface{} `json:"model"` 205 Mac string `json:"mac"` 206 IP interface{} `json:"ip"` 207 Bridge string `json:"bridge"` 208 } `json:"nics"` 209 Pcidevs []interface{} `json:"pcidevs"` 210 Vfbs []interface{} `json:"vfbs"` 211 Vkbs []interface{} `json:"vkbs"` 212 Vtpms []interface{} `json:"vtpms"` 213 } `json:"config"` 214 Domid int `json:"domid"` 215 }