github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/vsphere/upgrades.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package vsphere 5 6 import ( 7 "path" 8 9 "github.com/juju/errors" 10 "github.com/vmware/govmomi/vim25/types" 11 12 "github.com/juju/juju/environs" 13 "github.com/juju/juju/environs/context" 14 "github.com/juju/juju/environs/tags" 15 ) 16 17 // UpgradeOperations is part of the upgrades.OperationSource interface. 18 func (env *environ) UpgradeOperations(ctx context.ProviderCallContext, args environs.UpgradeOperationsParams) []environs.UpgradeOperation { 19 return []environs.UpgradeOperation{{ 20 providerVersion1, 21 []environs.UpgradeStep{ 22 extraConfigUpgradeStep{env, args.ControllerUUID}, 23 modelFoldersUpgradeStep{env, args.ControllerUUID}, 24 }, 25 }} 26 } 27 28 // extraConfigUpgradeStep moves top-level VMs into a model-specific 29 // VM folder. 30 type extraConfigUpgradeStep struct { 31 env *environ 32 controllerUUID string 33 } 34 35 // Description is part of the environs.UpgradeStep interface. 36 func (extraConfigUpgradeStep) Description() string { 37 return "Update ExtraConfig properties with standard Juju tags" 38 } 39 40 // Run is part of the environs.UpgradeStep interface. 41 func (step extraConfigUpgradeStep) Run(ctx context.ProviderCallContext) error { 42 const ( 43 legacyControllerTag = "juju_controller_uuid_key" 44 legacyIsControllerTag = "juju_is_controller_key" 45 ) 46 return step.env.withSession(ctx, func(env *sessionEnviron) error { 47 vms, err := env.client.VirtualMachines(env.ctx, env.namespace.Prefix()+"*") 48 if err != nil || len(vms) == 0 { 49 HandleCredentialError(err, ctx) 50 return err 51 } 52 for _, vm := range vms { 53 update := false 54 isController := false 55 for _, opt := range vm.Config.ExtraConfig { 56 value := opt.GetOptionValue() 57 switch value.Key { 58 case legacyControllerTag: 59 update = true 60 case legacyIsControllerTag: 61 isController = true 62 } 63 } 64 if !update { 65 continue 66 } 67 metadata := map[string]string{ 68 tags.JujuController: step.controllerUUID, 69 tags.JujuModel: env.Config().UUID(), 70 } 71 if isController { 72 metadata[tags.JujuIsController] = "true" 73 } 74 if err := env.client.UpdateVirtualMachineExtraConfig( 75 env.ctx, vm, metadata, 76 ); err != nil { 77 HandleCredentialError(err, ctx) 78 return errors.Annotatef(err, "updating VM %s", vm.Name) 79 } 80 } 81 return nil 82 }) 83 } 84 85 // modelFoldersUpgradeStep moves top-level VMs into a model-specific 86 // VM folder. 87 type modelFoldersUpgradeStep struct { 88 env *environ 89 controllerUUID string 90 } 91 92 // Description is part of the environs.UpgradeStep interface. 93 func (modelFoldersUpgradeStep) Description() string { 94 return "Move VMs into controller/model folders" 95 } 96 97 // Run is part of the environs.UpgradeStep interface. 98 func (step modelFoldersUpgradeStep) Run(ctx context.ProviderCallContext) error { 99 return step.env.withSession(ctx, func(env *sessionEnviron) error { 100 // We must create the folder even if there are no VMs in the model. 101 modelFolderPath := path.Join( 102 controllerFolderName(step.controllerUUID), 103 env.modelFolderName(), 104 ) 105 if _, err := env.client.EnsureVMFolder(env.ctx, modelFolderPath); err != nil { 106 HandleCredentialError(err, ctx) 107 return errors.Annotate(err, "creating model folder") 108 } 109 110 // List all instances at the top level with the model UUID, 111 // and move them into the folder. 112 vms, err := env.client.VirtualMachines(env.ctx, env.namespace.Prefix()+"*") 113 if err != nil || len(vms) == 0 { 114 HandleCredentialError(err, ctx) 115 return err 116 } 117 refs := make([]types.ManagedObjectReference, len(vms)) 118 for i, vm := range vms { 119 logger.Debugf("moving VM %q into %q", vm.Name, modelFolderPath) 120 refs[i] = vm.Reference() 121 } 122 if err := env.client.MoveVMsInto(env.ctx, modelFolderPath, refs...); err != nil { 123 HandleCredentialError(err, ctx) 124 return errors.Annotate(err, "moving VMs into model folder") 125 } 126 return nil 127 }) 128 }