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  }