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  }