Merge lp:~jameinel/juju-core/openstack-filter-1257481 into lp:juju-core/1.16

Proposed by John A Meinel
Status: Merged
Approved by: John A Meinel
Approved revision: no longer in the source branch.
Merged at revision: 1998
Proposed branch: lp:~jameinel/juju-core/openstack-filter-1257481
Merge into: lp:juju-core/1.16
Diff against target: 69 lines (+43/-1)
3 files modified
provider/openstack/export_test.go (+4/-0)
provider/openstack/local_test.go (+38/-0)
provider/openstack/provider.go (+1/-1)
To merge this branch: bzr merge lp:~jameinel/juju-core/openstack-filter-1257481
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+198218@code.launchpad.net

Commit message

provider/openstack/provider: safer matching

bug #1257481 is because of how we are matching machines, if you have 2
environments with similar names (one is a prefix of the other) then
you can have 'juju destroy-environment short-name' actually kill all
the instances of 'short-name-but-longer'.

However, we do put a little bit more data into how we name machines,
so we can make it harder to trigger that by accident.

The actual change is small and directly tested against HP and
Canonistack. I don't add a test because the actual test we would need
is to create 2 environments, and assert that AllInstances doesn't see
the instances in a similarly named environment.

I tried 2 regexes 'juju-ENV-machine-\d+' didn't work when testing
against canonistack, so I went with 'juju-ENV-machine-\d*'. That
should be pretty restrictive. Even if you name one environment 'ENV'
and another environment 'ENV-machine' the \d will prevent them from
matching (because the actual machines will be
juju-ENV-machine-machine-0).

I think this is as safe as we can be with a name-based approach, even
though we've discussed moving into a 'record the nodes only in state
and only delete ones recorded there', this is a pretty easy workaround
to make things nicer for real people.

https://codereview.appspot.com/39030043/

Description of the change

This is the same filter fix that was proposed for trunk, but the fix is reasonable to have for 1.16.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'provider/openstack/export_test.go'
2--- provider/openstack/export_test.go 2013-09-25 12:22:10 +0000
3+++ provider/openstack/export_test.go 2013-12-09 10:38:14 +0000
4@@ -316,3 +316,7 @@
5 swift: swiftClient,
6 }
7 }
8+
9+func GetNovaClient(e environs.Environ) *nova.Client {
10+ return e.(*environ).nova()
11+}
12
13=== modified file 'provider/openstack/local_test.go'
14--- provider/openstack/local_test.go 2013-10-01 13:34:02 +0000
15+++ provider/openstack/local_test.go 2013-12-09 10:38:14 +0000
16@@ -950,3 +950,41 @@
17 // We *don't* test Fetch for sources[3] because it points to
18 // juju.canonical.com
19 }
20+
21+func (s *localServerSuite) TestAllInstancesIgnoresOtherMachines(c *gc.C) {
22+ env := s.Prepare(c)
23+ err := bootstrap.Bootstrap(env, constraints.Value{})
24+ c.Assert(err, gc.IsNil)
25+
26+ // Check that we see 1 instance in the environment
27+ insts, err := env.AllInstances()
28+ c.Assert(err, gc.IsNil)
29+ c.Check(insts, gc.HasLen, 1)
30+
31+ // Now start a machine 'manually' in the same account, with a similar
32+ // but not matching name, and ensure it isn't seen by AllInstances
33+ // See bug #1257481, for how similar names were causing them to get
34+ // listed (and thus destroyed) at the wrong time
35+ existingEnvName := s.TestConfig["name"]
36+ newMachineName := fmt.Sprintf("juju-%s-2-machine-0", existingEnvName)
37+
38+ // We grab the Nova client directly from the env, just to save time
39+ // looking all the stuff up
40+ novaClient := openstack.GetNovaClient(env)
41+ entity, err := novaClient.RunServer(nova.RunServerOpts{
42+ Name: newMachineName,
43+ FlavorId: "1", // test service has 1,2,3 for flavor ids
44+ ImageId: "1", // UseTestImageData sets up images 1 and 2
45+ })
46+ c.Assert(err, gc.IsNil)
47+ c.Assert(entity, gc.NotNil)
48+
49+ // List all servers with no filter, we should see both instances
50+ servers, err := novaClient.ListServersDetail(nova.NewFilter())
51+ c.Assert(err, gc.IsNil)
52+ c.Assert(servers, gc.HasLen, 2)
53+
54+ insts, err = env.AllInstances()
55+ c.Assert(err, gc.IsNil)
56+ c.Check(insts, gc.HasLen, 1)
57+}
58
59=== modified file 'provider/openstack/provider.go'
60--- provider/openstack/provider.go 2013-10-09 06:17:57 +0000
61+++ provider/openstack/provider.go 2013-12-09 10:38:14 +0000
62@@ -847,7 +847,7 @@
63 // machinesFilter returns a nova.Filter matching all machines in the environment.
64 func (e *environ) machinesFilter() *nova.Filter {
65 filter := nova.NewFilter()
66- filter.Set(nova.FilterServer, fmt.Sprintf("juju-%s-.*", e.Name()))
67+ filter.Set(nova.FilterServer, fmt.Sprintf("juju-%s-machine-\\d*", e.Name()))
68 return filter
69 }
70

Subscribers

People subscribed via source and target branches

to all changes: