// listVMPaths returns an array of datastore paths for VMs assocaited with the // VCH - this includes containerVMs and the appliance func listVMPaths(ctx context.Context, s *session.Session) ([]url.URL, error) { defer trace.End(trace.Begin("")) var err error var children []*vm.VirtualMachine if len(vchConfig.ComputeResources) == 0 { return nil, errors.New("compute resources is empty") } ref := vchConfig.ComputeResources[0] rp := compute.NewResourcePool(ctx, s, ref) if children, err = rp.GetChildrenVMs(ctx, s); err != nil { return nil, err } log.Infof("Found %d candidate VMs in resource pool %s for log collection", len(children), ref.String()) directories := []url.URL{} for _, child := range children { path, err := child.DSPath(ctx) if err != nil { log.Errorf("Unable to get datastore path for child VM %s: %s", child.Reference(), err) // we need to get as many logs as possible continue } log.Debugf("Adding VM for log collection: %s", path.String()) directories = append(directories, path) } log.Infof("Collecting logs from %d VMs", len(directories)) return directories, nil }
func (d *Dispatcher) destroyResourcePoolIfEmpty(conf *config.VirtualContainerHostConfigSpec) error { defer trace.End(trace.Begin("")) log.Infof("Removing Resource Pool %q", conf.Name) rpRef := conf.ComputeResources[len(conf.ComputeResources)-1] rp := compute.NewResourcePool(d.ctx, d.session, rpRef) var vms []*vm.VirtualMachine var err error if vms, err = rp.GetChildrenVMs(d.ctx, d.session); err != nil { err = errors.Errorf("Unable to get children vm of resource pool %q: %s", rp.Name(), err) return err } if len(vms) != 0 { err = errors.Errorf("Resource pool is not empty: %q", rp.Name()) return err } if _, err := tasks.WaitForResult(d.ctx, func(ctx context.Context) (tasks.ResultWaiter, error) { return rp.Destroy(ctx) }); err != nil { return err } return nil }
func (d *Dispatcher) DeleteVCHInstances(vmm *vm.VirtualMachine, conf *config.VirtualContainerHostConfigSpec) error { defer trace.End(trace.Begin("")) log.Infof("Removing VMs") var errs []string var err error var children []*vm.VirtualMachine rpRef := conf.ComputeResources[len(conf.ComputeResources)-1] ref, err := d.session.Finder.ObjectReference(d.ctx, rpRef) if err != nil { err = errors.Errorf("Failed to get VCH resource pool %q: %s", rpRef, err) return err } switch ref.(type) { case *object.VirtualApp: case *object.ResourcePool: // ok default: log.Errorf("Failed to find virtual app or resource pool %q: %s", rpRef, err) return err } rp := compute.NewResourcePool(d.ctx, d.session, ref.Reference()) if children, err = rp.GetChildrenVMs(d.ctx, d.session); err != nil { return err } ds, err := d.session.Finder.Datastore(d.ctx, conf.ImageStores[0].Host) if err != nil { err = errors.Errorf("Failed to find image datastore %q", conf.ImageStores[0].Host) return err } d.session.Datastore = ds for _, child := range children { name, err := child.Name(d.ctx) if err != nil { errs = append(errs, err.Error()) continue } //Leave VCH appliance there until everything else is removed, cause it has VCH configuration. Then user could retry delete in case of any failure. if name == conf.Name { continue } if err = d.deleteVM(child, d.force); err != nil { errs = append(errs, err.Error()) } } if len(errs) > 0 { log.Debugf("Error deleting container VMs %s", errs) return errors.New(strings.Join(errs, "\n")) } return nil }
func (d *Dispatcher) NewVCHFromComputePath(computePath string, name string, v *validate.Validator) (*vm.VirtualMachine, error) { defer trace.End(trace.Begin(fmt.Sprintf("path %q, name %q", computePath, name))) var err error parent, err := v.ResourcePoolHelper(d.ctx, computePath) if err != nil { return nil, err } d.vchPoolPath = path.Join(parent.InventoryPath, name) var vchPool *object.ResourcePool if d.isVC { vapp, err := d.findVirtualApp(d.vchPoolPath) if err != nil { log.Errorf("Failed to get VCH virtual app %q: %s", d.vchPoolPath, err) return nil, err } if vapp != nil { vchPool = vapp.ResourcePool } } if vchPool == nil { vchPool, err = d.session.Finder.ResourcePool(d.ctx, d.vchPoolPath) if err != nil { log.Errorf("Failed to get VCH resource pool %q: %s", d.vchPoolPath, err) return nil, err } } rp := compute.NewResourcePool(d.ctx, d.session, vchPool.Reference()) var vmm *vm.VirtualMachine if vmm, err = rp.GetChildVM(d.ctx, d.session, name); err != nil { log.Errorf("Failed to get VCH VM: %s", err) return nil, err } if vmm == nil { err = errors.Errorf("Didn't find VM %q in resource pool %q", name, rp.Name()) log.Error(err) return nil, err } vmm.InventoryPath = path.Join(d.vchPoolPath, name) // check if it's VCH var ok bool if ok, err = d.isVCH(vmm); err != nil { log.Error(err) return nil, err } if !ok { err = errors.Errorf("Not a VCH") log.Error(err) return nil, err } return vmm, nil }
func (d *Dispatcher) checkExistence(conf *config.VirtualContainerHostConfigSpec, settings *data.InstallerData) error { defer trace.End(trace.Begin("")) var err error d.vchPoolPath = path.Join(settings.ResourcePoolPath, conf.Name) var orp *object.ResourcePool var vapp *object.VirtualApp if d.isVC { vapp, err = d.findVirtualApp(d.vchPoolPath) if err != nil { return err } if vapp != nil { orp = vapp.ResourcePool } } if orp == nil { if orp, err = d.findResourcePool(d.vchPoolPath); err != nil { return err } } if orp == nil { return nil } rp := compute.NewResourcePool(d.ctx, d.session, orp.Reference()) vm, err := rp.GetChildVM(d.ctx, d.session, conf.Name) if err != nil { return err } if vm == nil { if vapp != nil { err = errors.Errorf("virtual app %q is found, but is not VCH, please choose different name", d.vchPoolPath) log.Error(err) return err } return nil } log.Debugf("Appliance is found") if ok, verr := d.isVCH(vm); !ok { verr = errors.Errorf("VM %q is found, but is not VCH appliance, please choose different name", conf.Name) return verr } err = errors.Errorf("Appliance %q exists, to install with same name, please delete it first.", conf.Name) return err }
func (d *Dispatcher) NewVCHFromComputePath(computePath string, name string) (*vm.VirtualMachine, error) { defer trace.End(trace.Begin(fmt.Sprintf("path %s, name %s", computePath, name))) var err error v := &validate.Validator{ Session: d.session, Context: d.ctx, } parent, err := v.ResourcePoolHelper(d.ctx, computePath) if err != nil { return nil, err } vchPath := fmt.Sprintf("%s/%s", parent.InventoryPath, name) vchPool, err := v.ResourcePoolHelper(d.ctx, vchPath) if err != nil { log.Errorf("Failed to get VCH resource pool %s: %s", vchPath, err) return nil, err } rp := compute.NewResourcePool(d.ctx, d.session, vchPool.Reference()) var vmm *vm.VirtualMachine if vmm, err = rp.GetChildVM(d.ctx, d.session, name); err != nil { log.Errorf("Failed to get VCH VM, %s", err) return nil, err } // check if it's VCH var ok bool if ok, err = d.isVCH(vmm); err != nil { log.Errorf("%s", err) return nil, err } if !ok { err = errors.Errorf("Not a VCH") log.Errorf("%s", err) return nil, err } return vmm, nil }
// getVCHs will check vm with same name under this resource pool, to see if that's VCH vm, and it will also check children vApp, to see if that's a VCH. // eventually return all fond VCH VMs func (d *Dispatcher) getChildVCHs(pool *object.ResourcePool, searchVapp bool) ([]*vm.VirtualMachine, error) { defer trace.End(trace.Begin(pool.InventoryPath)) // check if pool itself contains VCH vm. var vchs []*vm.VirtualMachine poolName := pool.Name() computeResource := compute.NewResourcePool(d.ctx, d.session, pool.Reference()) vmm, err := computeResource.GetChildVM(d.ctx, d.session, poolName) if err != nil { return nil, errors.Errorf("Failed to query children VM in resource pool %q: %s", pool.InventoryPath, err) } if vmm != nil { vmm.InventoryPath = path.Join(pool.InventoryPath, poolName) if ok, _ := d.isVCH(vmm); ok { log.Debugf("%q is VCH", vmm.InventoryPath) vchs = append(vchs, vmm) } } if !searchVapp { return vchs, nil } vappPath := path.Join(pool.InventoryPath, "*") vapps, err := d.session.Finder.VirtualAppList(d.ctx, vappPath) if err != nil { if _, ok := err.(*find.NotFoundError); ok { return vchs, nil } log.Debugf("Failed to query vapp %q: %s", vappPath, err) } for _, vapp := range vapps { childVCHs, err := d.getChildVCHs(vapp.ResourcePool, false) if err != nil { return nil, err } vchs = append(vchs, childVCHs...) } return vchs, nil }
// Get the current log header LineEnd of the hostd/vpxd logs. // With this we avoid collecting log file data that existed prior to install. func (d *Dispatcher) InitDiagnosticLogs(conf *config.VirtualContainerHostConfigSpec) { defer trace.End(trace.Begin("")) if d.isVC { diagnosticLogs[d.session.ServiceContent.About.InstanceUuid] = &diagnosticLog{"vpxd:vpxd.log", "vpxd.log", 0, nil, true} } var err error if d.session.Datastore == nil { if d.session.Datastore, err = d.session.Finder.DatastoreOrDefault(d.ctx, conf.ImageStores[0].Host); err != nil { log.Errorf("Failure finding image store from VCH config (%s): %s", conf.ImageStores[0].Host, err.Error()) return } log.Debugf("Found ds: %s", conf.ImageStores[0].Host) } // find the host(s) attached to given storage if d.session.Cluster == nil { if len(conf.ComputeResources) > 0 { rp := compute.NewResourcePool(d.ctx, d.session, conf.ComputeResources[0]) if d.session.Cluster, err = rp.GetCluster(d.ctx); err != nil { log.Errorf("Unable to get cluster for given resource pool %s: %s", conf.ComputeResources[0], err) return } } else { log.Errorf("Compute resource is empty") return } } hosts, err := d.session.Datastore.AttachedClusterHosts(d.ctx, d.session.Cluster) if err != nil { log.Errorf("Unable to get the list of hosts attached to given storage: %s", err) return } if d.session.Host == nil { // vCenter w/ auto DRS. // Set collect=false here as we do not want to collect all hosts logs, // just the hostd log where the VM is placed. for _, host := range hosts { diagnosticLogs[host.Reference().Value] = &diagnosticLog{"hostd", "hostd.log", 0, host, false} } } else { // vCenter w/ manual DRS or standalone ESXi var host *object.HostSystem if d.isVC { host = d.session.Host } diagnosticLogs[d.session.Host.Reference().Value] = &diagnosticLog{"hostd", "hostd.log", 0, host, true} } m := diagnostic.NewDiagnosticManager(d.session) for k, l := range diagnosticLogs { // get LineEnd without any LineText h, err := m.BrowseLog(d.ctx, l.host, l.key, math.MaxInt32, 0) if err != nil { log.Warnf("Disabling %s %s collection (%s)", k, l.name, err) diagnosticLogs[k] = nil continue } l.start = h.LineEnd } }
// listVMPaths returns an array of datastore paths for VMs associated with the // VCH - this includes containerVMs and the appliance func listVMPaths(ctx context.Context, s *session.Session) ([]logfile, error) { defer trace.End(trace.Begin("")) var err error var children []*vm.VirtualMachine if len(vchConfig.ComputeResources) == 0 { return nil, errors.New("compute resources is empty") } ref := vchConfig.ComputeResources[0] rp := compute.NewResourcePool(ctx, s, ref) if children, err = rp.GetChildrenVMs(ctx, s); err != nil { return nil, err } self, err := guest.GetSelf(ctx, s) if err != nil { log.Errorf("Unable to get handle to self for log filtering") } log.Infof("Found %d candidate VMs in resource pool %s for log collection", len(children), ref.String()) logfiles := []logfile{} for _, child := range children { path, err := child.DSPath(ctx) if err != nil { log.Errorf("Unable to get datastore path for child VM %s: %s", child.Reference(), err) // we need to get as many logs as possible continue } logname, err := child.Name(ctx) if err != nil { log.Errorf("Unable to get the vm name for %s: %s", child.Reference(), err) continue } if self != nil && child.Reference().String() == self.Reference().String() { // FIXME: until #2630 is addressed, and we confirm this filters secrets from appliance vmware.log as well, // we're skipping direct collection of those logs. log.Info("Skipping collection for appliance VM (moref match)") continue } // backup check if we were unable to initialize self for some reason if self == nil && logname == vchConfig.Name { log.Info("Skipping collection for appliance VM (string match)") continue } log.Debugf("Adding VM for log collection: %s", path.String()) log := logfile{ URL: path, VMName: logname, } logfiles = append(logfiles, log) } log.Infof("Collecting logs from %d VMs", len(logfiles)) log.Infof("Found VM paths are : %#v", logfiles) return logfiles, nil }