github.com/openshift/installer@v1.4.17/pkg/destroy/ovirt/destroyer.go (about) 1 package ovirt 2 3 import ( 4 "fmt" 5 "strings" 6 "sync" 7 "time" 8 9 "github.com/ovirt/go-ovirt" 10 "github.com/sirupsen/logrus" 11 12 "github.com/openshift/installer/pkg/asset/installconfig/ovirt" 13 "github.com/openshift/installer/pkg/destroy/providers" 14 "github.com/openshift/installer/pkg/types" 15 ) 16 17 // ClusterUninstaller holds the various options for the cluster we want to delete. 18 type ClusterUninstaller struct { 19 Metadata types.ClusterMetadata 20 Logger logrus.FieldLogger 21 } 22 23 // Run is the entrypoint to start the uninstall process. 24 func (uninstaller *ClusterUninstaller) Run() (*types.ClusterQuota, error) { 25 con, err := ovirt.NewConnection() 26 if err != nil { 27 return nil, fmt.Errorf("failed to initialize connection to ovirt-engine's %s", err) 28 } 29 defer con.Close() 30 31 // Tags 32 tagVMs := uninstaller.Metadata.InfraID 33 tagVMbootstrap := uninstaller.Metadata.InfraID + "-bootstrap" 34 tags := [2]string{tagVMs, tagVMbootstrap} 35 36 for _, tag := range tags { 37 if err := uninstaller.removeVMs(con, tag); err != nil { 38 uninstaller.Logger.Errorf("failed to remove VMs: %s", err) 39 } 40 if err := uninstaller.removeTag(con, tag); err != nil { 41 uninstaller.Logger.Errorf("failed to remove tag: %s", err) 42 } 43 } 44 if err := uninstaller.removeTemplate(con); err != nil { 45 uninstaller.Logger.Errorf("Failed to remove template: %s", err) 46 } 47 if err := uninstaller.removeAffinityGroups(con); err != nil { 48 uninstaller.Logger.Errorf("Failed to removing Affinity Groups: %s", err) 49 } 50 51 return nil, nil 52 } 53 54 func (uninstaller *ClusterUninstaller) removeVMs(con *ovirtsdk.Connection, tag string) error { 55 // - find all vms by tag name=infraID 56 vmsService := con.SystemService().VmsService() 57 searchTerm := fmt.Sprintf("tag=%s", tag) 58 uninstaller.Logger.Debugf("Searching VMs by %s", searchTerm) 59 vmsResponse, err := vmsService.List().Search(searchTerm).Send() 60 if err != nil { 61 return err 62 } 63 // - stop + delete VMS 64 vms := vmsResponse.MustVms().Slice() 65 uninstaller.Logger.Debugf("Found %d VMs", len(vms)) 66 wg := sync.WaitGroup{} 67 wg.Add(len(vms)) 68 for _, vm := range vms { 69 go func(vm *ovirtsdk.Vm) { 70 uninstaller.stopVM(vmsService, vm) 71 uninstaller.removeVM(vmsService, vm) 72 wg.Done() 73 }(vm) 74 } 75 wg.Wait() 76 return nil 77 } 78 79 func (uninstaller *ClusterUninstaller) removeTag(con *ovirtsdk.Connection, tag string) error { 80 // finally remove the tag 81 tagsService := con.SystemService().TagsService() 82 tagsServiceListResponse, err := tagsService.List().Send() 83 if err != nil { 84 return err 85 } 86 if tagsServiceListResponse != nil { 87 for _, t := range tagsServiceListResponse.MustTags().Slice() { 88 if t.MustName() == tag { 89 uninstaller.Logger.Infof("Removing tag %s", t.MustName()) 90 _, err := tagsService.TagService(t.MustId()).Remove().Send() 91 if err != nil { 92 return err 93 } 94 } 95 } 96 } 97 return nil 98 } 99 100 func (uninstaller *ClusterUninstaller) stopVM(vmsService *ovirtsdk.VmsService, vm *ovirtsdk.Vm) { 101 vmService := vmsService.VmService(vm.MustId()) 102 // this is a teardown, stopping instead of shutting down. 103 _, err := vmService.Stop().Send() 104 if err == nil { 105 uninstaller.Logger.Infof("Stopping VM %s", vm.MustName()) 106 } else { 107 uninstaller.Logger.Errorf("Failed to stop VM %s: %s", vm.MustName(), err) 108 } 109 waitForDownDuration := time.Minute * 10 110 err = vmService.Connection().WaitForVM(vm.MustId(), ovirtsdk.VMSTATUS_DOWN, waitForDownDuration) 111 if err == nil { 112 uninstaller.Logger.Infof("VM %s powered off", vm.MustName()) 113 } else { 114 uninstaller.Logger.Warnf("Waited %d for VM %s to power off: %s", waitForDownDuration, vm.MustName(), err) 115 } 116 } 117 118 func (uninstaller *ClusterUninstaller) removeVM(vmsService *ovirtsdk.VmsService, vm *ovirtsdk.Vm) { 119 vmService := vmsService.VmService(vm.MustId()) 120 _, err := vmService.Remove().Send() 121 if err == nil { 122 uninstaller.Logger.Infof("Removing VM %s", vm.MustName()) 123 } else { 124 uninstaller.Logger.Errorf("Failed to remove VM %s: %s", vm.MustName(), err) 125 } 126 } 127 128 func (uninstaller *ClusterUninstaller) removeTemplate(con *ovirtsdk.Connection) error { 129 if uninstaller.Metadata.Ovirt.RemoveTemplate { 130 search, err := con.SystemService().TemplatesService(). 131 List().Search(fmt.Sprintf("name=%s-rhcos", uninstaller.Metadata.InfraID)).Send() 132 if err != nil { 133 return fmt.Errorf("couldn't find a template with name %s", uninstaller.Metadata.InfraID) 134 } 135 if result, ok := search.Templates(); ok { 136 // the results can potentially return a list of template 137 // because the search uses wildcards 138 for _, tmp := range result.Slice() { 139 uninstaller.Logger.Infof("Removing Template %s", tmp.MustName()) 140 service := con.SystemService().TemplatesService().TemplateService(tmp.MustId()) 141 _, err := service.Remove().Send() 142 if err != nil { 143 return err 144 } 145 } 146 } 147 } 148 return nil 149 } 150 151 func (uninstaller *ClusterUninstaller) removeAffinityGroups(con *ovirtsdk.Connection) error { 152 cID := uninstaller.Metadata.Ovirt.ClusterID 153 affinityGroupService := con.SystemService().ClustersService().ClusterService(cID).AffinityGroupsService() 154 res, err := affinityGroupService.List().Send() 155 if err != nil { 156 return err 157 } 158 for _, ag := range res.MustGroups().Slice() { 159 if strings.HasPrefix(ag.MustName(), fmt.Sprintf("%s-", uninstaller.Metadata.InfraID)) { 160 uninstaller.Logger.Infof("Removing AffinityGroup %s", ag.MustName()) 161 _, err := affinityGroupService.GroupService(ag.MustId()).Remove().Send() 162 if err != nil { 163 uninstaller.Logger.Errorf("failed to remove AffinityGroup: %s", err) 164 } 165 } 166 } 167 return nil 168 } 169 170 // New returns oVirt Uninstaller from ClusterMetadata. 171 func New(logger logrus.FieldLogger, metadata *types.ClusterMetadata) (providers.Destroyer, error) { 172 return &ClusterUninstaller{ 173 Metadata: *metadata, 174 Logger: logger, 175 }, nil 176 }