func (d *Dispatcher) reconfigureApplianceSpec(vm *vm.VirtualMachine, conf *config.VirtualContainerHostConfigSpec, settings *data.InstallerData) (*types.VirtualMachineConfigSpec, error) { defer trace.End(trace.Begin("")) var devices object.VirtualDeviceList var err error spec := &types.VirtualMachineConfigSpec{ Name: conf.Name, GuestId: "other3xLinux64Guest", Files: &types.VirtualMachineFileInfo{VmPathName: fmt.Sprintf("[%s]", conf.ImageStores[0].Host)}, } if devices, err = d.configIso(conf, vm, settings); err != nil { return nil, err } deviceChange, err := devices.ConfigSpec(types.VirtualDeviceConfigSpecOperationAdd) if err != nil { log.Errorf("Failed to create config spec for appliance: %s", err) return nil, err } spec.DeviceChange = deviceChange cfg := make(map[string]string) extraconfig.Encode(extraconfig.MapSink(cfg), conf) spec.ExtraConfig = append(spec.ExtraConfig, vmomi.OptionValueFromMap(cfg)...) return spec, nil }
func (h *Handle) Commit(ctx context.Context, sess *session.Session, waitTime *int32) error { cfg := make(map[string]string) // Set timestamps based on target state switch h.TargetState() { case StateRunning: for _, sc := range h.ExecConfig.Sessions { sc.StartTime = time.Now().UTC().Unix() sc.Started = "" sc.ExitStatus = 0 } case StateStopped: for _, sc := range h.ExecConfig.Sessions { sc.StopTime = time.Now().UTC().Unix() } } extraconfig.Encode(extraconfig.MapSink(cfg), h.ExecConfig) s := h.Spec.Spec() s.ExtraConfig = append(s.ExtraConfig, vmomi.OptionValueFromMap(cfg)...) if err := Commit(ctx, sess, h, waitTime); err != nil { return err } removeHandle(h.key) return nil }
func (d *Dispatcher) createApplianceSpec(conf *config.VirtualContainerHostConfigSpec, vConf *data.InstallerData) (*types.VirtualMachineConfigSpec, error) { defer trace.End(trace.Begin("")) var devices object.VirtualDeviceList var err error cfg, err := d.encodeConfig(conf) if err != nil { return nil, err } spec := &spec.VirtualMachineConfigSpec{ VirtualMachineConfigSpec: &types.VirtualMachineConfigSpec{ Name: conf.Name, GuestId: "other3xLinux64Guest", Files: &types.VirtualMachineFileInfo{VmPathName: fmt.Sprintf("[%s]", conf.ImageStores[0].Host)}, NumCPUs: int32(vConf.ApplianceSize.CPU.Limit), MemoryMB: vConf.ApplianceSize.Memory.Limit, // Encode the config both here and after the VMs created so that it can be identified as a VCH appliance as soon as // creation is complete. ExtraConfig: vmomi.OptionValueFromMap(cfg), }, } if devices, err = d.addIDEController(devices); err != nil { return nil, err } if devices, err = d.addParaVirtualSCSIController(devices); err != nil { return nil, err } if devices, err = d.addNetworkDevices(conf, spec, devices); err != nil { return nil, err } deviceChange, err := devices.ConfigSpec(types.VirtualDeviceConfigSpecOperationAdd) if err != nil { return nil, err } spec.DeviceChange = deviceChange return spec.VirtualMachineConfigSpec, nil }
func (d *Dispatcher) reconfigVCH(conf *config.VirtualContainerHostConfigSpec, isoFile string) error { defer trace.End(trace.Begin(isoFile)) spec := &types.VirtualMachineConfigSpec{} deviceChange, err := d.switchISO(isoFile) if err != nil { return err } spec.DeviceChange = deviceChange if conf != nil { cfg, cerr := d.encodeConfig(conf) if cerr != nil { return cerr } spec.ExtraConfig = append(spec.ExtraConfig, vmomi.OptionValueFromMap(cfg)...) } if spec.DeviceChange == nil && spec.ExtraConfig == nil { // nothing need to do log.Debugf("Nothing changed, no need to reconfigure appliance") return nil } // reconfig log.Infof("Setting VM configuration") info, err := d.appliance.WaitForResult(d.ctx, func(ctx context.Context) (tasks.Task, error) { return d.appliance.Reconfigure(ctx, *spec) }) if err != nil { log.Errorf("Error while reconfiguring appliance: %s", err) return err } if info.State != types.TaskInfoStateSuccess { log.Errorf("Reconfiguring appliance reported: %s", info.Error.LocalizedMessage) return err } return nil }
func (h *Handle) Commit(ctx context.Context, sess *session.Session, waitTime *int32) error { if h.committed { return nil // already committed } // make sure there is a spec h.SetSpec(nil) cfg := make(map[string]string) extraconfig.Encode(extraconfig.MapSink(cfg), h.ExecConfig) s := h.Spec.Spec() s.ExtraConfig = append(s.ExtraConfig, vmomi.OptionValueFromMap(cfg)...) if err := h.Container.Commit(ctx, sess, h, waitTime); err != nil { return err } h.committed = true removeHandle(h.key) return nil }
// NewVirtualMachineConfigSpec returns a VirtualMachineConfigSpec func NewVirtualMachineConfigSpec(ctx context.Context, session *session.Session, config *VirtualMachineConfigSpecConfig) (*VirtualMachineConfigSpec, error) { defer trace.End(trace.Begin(config.ID)) log.Debugf("Adding metadata to the configspec: %+v", config.Metadata) // TEMPORARY // set VM name to prettyname-ID, to make it readable a little bit // if prettyname-ID is longer than max vm name length, truncate pretty name, instead of UUID, to make it unique nameMaxLen := maxVMNameLength - len(config.ID) prettyName := config.Name if len(prettyName) > nameMaxLen-1 { prettyName = prettyName[:nameMaxLen-1] } fullName := fmt.Sprintf("%s-%s", prettyName, config.ID) config.VMFullName = fullName VMPathName := config.VMPathName if !session.IsVSAN(ctx) { // VMFS requires the full path to vmx or everything but the datastore is ignored VMPathName = fmt.Sprintf("%s/%s/%s.vmx", config.VMPathName, config.VMFullName, config.ID) } s := &types.VirtualMachineConfigSpec{ Name: fullName, Uuid: config.BiosUUID, Files: &types.VirtualMachineFileInfo{ VmPathName: VMPathName, }, NumCPUs: config.NumCPUs, CpuHotAddEnabled: &config.VMForkEnabled, // this disables vNUMA when true MemoryMB: config.MemoryMB, MemoryHotAddEnabled: &config.VMForkEnabled, ExtraConfig: []types.BaseOptionValue{ // lets us see the UUID for the containerfs disk (hidden from daemon) &types.OptionValue{Key: "disk.EnableUUID", Value: "true"}, // needed to avoid the questions that occur when attaching multiple disks with the same uuid (bugzilla 1362918) &types.OptionValue{Key: "answer.msg.disk.duplicateUUID", Value: "Yes"}, // needed to avoid the question that occur when opening a file backed serial port &types.OptionValue{Key: "answer.msg.serial.file.open", Value: "Append"}, &types.OptionValue{Key: "sched.mem.lpage.maxSharedPages", Value: "256"}, // seems to be needed to avoid children hanging shortly after fork &types.OptionValue{Key: "vmotion.checkpointSVGAPrimarySize", Value: "4194304"}, // trying this out - if it works then we need to determine if we can rely on serial0 being the correct index. &types.OptionValue{Key: "serial0.hardwareFlowControl", Value: "TRUE"}, // https://enatai-jira.eng.vmware.com/browse/BON-257 // Hotadd memory above 3 GB not working &types.OptionValue{Key: "memory.noHotAddOver4GB", Value: "FALSE"}, &types.OptionValue{Key: "memory.maxGrow", Value: "512"}, // http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2030189 &types.OptionValue{Key: "tools.remindInstall", Value: "FALSE"}, &types.OptionValue{Key: "tools.upgrade.policy", Value: "manual"}, }, } // encode the config as optionvalues cfg := map[string]string{} extraconfig.Encode(extraconfig.MapSink(cfg), config.Metadata) metaCfg := vmomi.OptionValueFromMap(cfg) // merge it with the sec s.ExtraConfig = append(s.ExtraConfig, metaCfg...) vmcs := &VirtualMachineConfigSpec{ Session: session, VirtualMachineConfigSpec: s, config: config, } log.Debugf("Virtual machine config spec created: %+v", vmcs) return vmcs, nil }