github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/openstack/upgrade.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package openstack 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/juju/errors" 11 "github.com/juju/version" 12 "gopkg.in/goose.v1/nova" 13 ) 14 15 // RunUpgradeStepsFor implements provider.Upgradable 16 func (e *Environ) RunUpgradeStepsFor(ver version.Number) error { 17 switch ver { 18 case version.Number{Major: 1, Minor: 26}: 19 if err := addUUIDToSecurityGroupNames(e); err != nil { 20 return errors.Annotate(err, "upgrading security group names in upgrade step for version 1.26") 21 } 22 if err := addUUIDToMachineNames(e); err != nil { 23 return errors.Annotate(err, "upgrading security machine names in upgrade step for version 1.26") 24 } 25 } 26 return nil 27 } 28 29 func replaceNameWithID(oldName, envName, eUUID string) (string, bool, error) { 30 prefix := "juju-" + envName 31 if !strings.HasPrefix(oldName, prefix) { 32 return "", false, nil 33 } 34 // This might be an env with a name that shares prefix with our current one. 35 if len(prefix) < len(oldName) && !strings.HasPrefix(oldName, prefix+"-") { 36 return "", false, nil 37 } 38 newPrefix := "juju-" + eUUID 39 return strings.Replace(oldName, prefix, newPrefix, -1), true, nil 40 } 41 42 func addUUIDToSecurityGroupNames(e *Environ) error { 43 nova := e.nova() 44 groups, err := nova.ListSecurityGroups() 45 if err != nil { 46 return errors.Annotate(err, "upgrading instance names") 47 } 48 cfg := e.Config() 49 eName := cfg.Name() 50 eUUID := cfg.UUID() 51 for _, group := range groups { 52 newName, ok, err := replaceNameWithID(group.Name, eName, eUUID) 53 if err != nil { 54 return errors.Annotate(err, "generating the new security group name") 55 } 56 if !ok { 57 continue 58 } 59 // Name should have uuid instead of name 60 _, err = nova.UpdateSecurityGroup(group.Id, newName, group.Description) 61 if err != nil { 62 return errors.Annotatef(err, "upgrading security group name from %q to %q", group.Name, newName) 63 } 64 65 } 66 return nil 67 } 68 69 // oldMachinesFilter returns a nova.Filter matching all machines in the environment 70 // that use the old name schema (juju-EnvironmentName-number). 71 func oldMachinesFilter(e *Environ) *nova.Filter { 72 filter := nova.NewFilter() 73 filter.Set(nova.FilterServer, fmt.Sprintf("juju-%s-machine-\\d*", e.Config().Name())) 74 return filter 75 } 76 77 func addUUIDToMachineNames(e *Environ) error { 78 nova := e.nova() 79 servers, err := nova.ListServers(oldMachinesFilter(e)) 80 if err != nil { 81 return errors.Annotate(err, "upgrading server names") 82 } 83 cfg := e.Config() 84 eName := cfg.Name() 85 eUUID := cfg.UUID() 86 for _, server := range servers { 87 newName, ok, err := replaceNameWithID(server.Name, eName, eUUID) 88 if err != nil { 89 return errors.Annotate(err, "generating the new server name") 90 } 91 if !ok { 92 continue 93 } 94 // Name should have uuid instead of name 95 _, err = nova.UpdateServerName(server.Id, newName) 96 if err != nil { 97 return errors.Annotatef(err, "upgrading machine name from %q to %q", server.Name, newName) 98 } 99 100 } 101 return nil 102 }