Merge lp:~elopio/snappy-tests-job/snappy-cloud-client into lp:snappy-tests-job

Proposed by Leo Arias
Status: Merged
Approved by: Federico Gimenez
Approved revision: 71
Merged at revision: 69
Proposed branch: lp:~elopio/snappy-tests-job/snappy-cloud-client
Merge into: lp:snappy-tests-job
Prerequisite: lp:~fgimenez/snappy-tests-job/generic-openstack-provider
Diff against target: 260 lines (+100/-23)
5 files modified
cloud/cloud.go (+1/-1)
cloud/openstack.go (+19/-19)
cloud/openstack_test.go (+9/-2)
cmd/snappy-cloud-client/main.go (+70/-0)
cmd/snappy-tests-job/main.go (+1/-1)
To merge this branch: bzr merge lp:~elopio/snappy-tests-job/snappy-cloud-client
Reviewer Review Type Date Requested Status
Leo Arias (community) Approve
Federico Gimenez (community) Approve
Review via email: mp+278860@code.launchpad.net

Commit message

Added a snappy-cloud-client command.

To post a comment you must log in.
Revision history for this message
Federico Gimenez (fgimenez) wrote :

Looks good, a couple of comments, the most important IMO is related to the constructor.

Thanks!

review: Needs Fixing
71. By Leo Arias

Updated the default cloud provider.

Revision history for this message
Leo Arias (elopio) wrote :

I fixed the default cloud provider.
The reason I didn't use the constructor is that it receives a flavor. I could pass an empty string there if you prefer.
I left a question about why is the flavor passed in the contructor and not on the Create method, but forgot to hit save.

Revision history for this message
Federico Gimenez (fgimenez) wrote :

Yes, it makes more sense to pass the flavor to the Create method, we can iterate on that later.

In order to use the constructor we could define an options type, so that the constructor gets as the only parameter an instance of that type and we can pass only the required opntions as fields, but also for the next iteration IMO.

review: Approve
Revision history for this message
Leo Arias (elopio) wrote :

Ok, merging then. I'll make the flavor change in the evening.

review: Approve
Revision history for this message
Leo Arias (elopio) wrote :

oh, you merged already :) thanks.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cloud/cloud.go'
2--- cloud/cloud.go 2015-11-27 16:29:33 +0000
3+++ cloud/cloud.go 2015-11-30 15:31:39 +0000
4@@ -23,7 +23,7 @@
5
6 // Clouder is the interface for all the cloud clients
7 type Clouder interface {
8- CreateInstance(release, channel string) (ip string, err error)
9+ CreateInstance(release, channel string) (ip string, id string, err error)
10 KillInstance() error
11 }
12
13
14=== modified file 'cloud/openstack.go'
15--- cloud/openstack.go 2015-11-27 16:29:33 +0000
16+++ cloud/openstack.go 2015-11-30 15:31:39 +0000
17@@ -45,26 +45,26 @@
18
19 // OpenstackClient is the client for connecting to Openstack
20 type OpenstackClient struct {
21- util utils.Utilizer
22+ Util utils.Utilizer
23 flavor string
24- instanceID string
25+ InstanceID string
26 }
27
28 // CreateInstance launches a snappy instance from the latest image with the passed release
29-// and channel and returns its ip
30-func (c *OpenstackClient) CreateInstance(release, channel string) (ip string, err error) {
31+// and channel and returns its ip and id
32+func (c *OpenstackClient) CreateInstance(release, channel string) (ip string, id string, err error) {
33 log.Printf("*** Creating Snappy instance for release %s and channel %s ***", release, channel)
34 imageID, err := c.listImages(release, channel)
35 if err == nil {
36- ip, err = c.launchInstance(imageID)
37+ ip, id, err = c.launchInstance(imageID)
38 }
39 return
40 }
41
42 // KillInstance kills the current running instance if any
43 func (c *OpenstackClient) KillInstance() (err error) {
44- if c.instanceID != "" {
45- log.Printf("*** Killing instance %s ***", c.instanceID)
46+ if c.InstanceID != "" {
47+ log.Printf("*** Killing instance %s ***", c.InstanceID)
48 err = c.killInstance()
49 }
50 return
51@@ -72,7 +72,7 @@
52
53 // NewOpenstackClient is OpenstackClient's constructor
54 func NewOpenstackClient(flavor string, util utils.Utilizer) *OpenstackClient {
55- return &OpenstackClient{flavor: flavor, util: util}
56+ return &OpenstackClient{flavor: flavor, Util: util}
57 }
58
59 func (c *OpenstackClient) imgTemplate(release, channel string) string {
60@@ -82,7 +82,7 @@
61
62 func (c *OpenstackClient) listImages(release, channel string) (imageID string, err error) {
63 params := utils.NewExecCommandParams("", strings.Fields(listImagesCmd), false)
64- list, err := c.util.ExecCommand(params)
65+ list, err := c.Util.ExecCommand(params)
66 if err == nil {
67 imageID = c.getLatestImageID(release, channel, list)
68 log.Printf("Found image with id %s for release %s and channel %s", imageID, release, channel)
69@@ -90,29 +90,29 @@
70 return
71 }
72
73-func (c *OpenstackClient) launchInstance(imageID string) (ip string, err error) {
74+func (c *OpenstackClient) launchInstance(imageID string) (ip string, id string, err error) {
75 log.Printf("Launching instance for Snappy image %s", imageID)
76
77 launchInstanceCmd := fmt.Sprintf(launchInstanceCmdTpl, c.flavor, imageID, os.Getpid())
78 params := utils.NewExecCommandParams("", strings.Fields(launchInstanceCmd), false)
79
80- output, err := c.util.ExecCommand(params)
81+ output, err := c.Util.ExecCommand(params)
82 if err == nil {
83- c.instanceID = c.getinstanceID(output)
84+ c.InstanceID = c.getinstanceID(output)
85 log.Print("Instance launch requested, getting IP...")
86 ip, err = c.getInstanceIP()
87 if ip != "" {
88 log.Printf("Got IP %s", ip)
89 }
90 }
91- return
92+ return ip, c.InstanceID, err
93 }
94
95 func (c *OpenstackClient) killInstance() (err error) {
96- killInstanceCmd := fmt.Sprintf(killInstanceCmdTpl, c.instanceID)
97+ killInstanceCmd := fmt.Sprintf(killInstanceCmdTpl, c.InstanceID)
98 params := utils.NewExecCommandParams("", strings.Fields(killInstanceCmd), false)
99
100- _, err = c.util.ExecCommand(params)
101+ _, err = c.Util.ExecCommand(params)
102 return
103 }
104
105@@ -194,12 +194,12 @@
106 }
107
108 func (c *OpenstackClient) getInstanceIP() (instanceIP string, err error) {
109- describeInstanceCmd := fmt.Sprintf(describeInstanceCmdTpl, c.instanceID)
110+ describeInstanceCmd := fmt.Sprintf(describeInstanceCmdTpl, c.InstanceID)
111
112 params := utils.NewExecCommandParams("", strings.Fields(describeInstanceCmd), false)
113
114 for i := 0; i < maxAttempsInstanceWait; i++ {
115- output, _ := c.util.ExecCommand(params)
116+ output, _ := c.Util.ExecCommand(params)
117
118 if instanceIP = extractInstanceIP(output); instanceIP == "" {
119 log.Print("IP not found, waiting...")
120@@ -207,13 +207,13 @@
121 time.Sleep(time.Duration(secondsToWaitForInstance) * time.Second)
122 } else {
123
124- log.Printf("The IP asigned to instance %s is %s", c.instanceID, instanceIP)
125+ log.Printf("The IP asigned to instance %s is %s", c.InstanceID, instanceIP)
126 break
127 }
128 }
129
130 if instanceIP == "" {
131- err = errors.New("Instance IP not found for instance " + c.instanceID)
132+ err = errors.New("Instance IP not found for instance " + c.InstanceID)
133 }
134 return
135 }
136
137=== modified file 'cloud/openstack_test.go'
138--- cloud/openstack_test.go 2015-11-27 16:29:33 +0000
139+++ cloud/openstack_test.go 2015-11-30 15:31:39 +0000
140@@ -150,7 +150,7 @@
141
142 func (s *openstackSuite) TestCreateInstanceReturnsErrorOnListError(c *check.C) {
143 s.fakeUtil.FailExec = true
144- _, err := s.subject.CreateInstance(defaultRelease, defaultChannel)
145+ _, _, err := s.subject.CreateInstance(defaultRelease, defaultChannel)
146
147 c.Assert(err, check.NotNil, check.Commentf("Expected error from euca list images"))
148 }
149@@ -177,12 +177,19 @@
150 }
151
152 func (s *openstackSuite) TestCreateInstanceReturnsInstanceIP(c *check.C) {
153- ip, _ := s.subject.CreateInstance(defaultRelease, defaultChannel)
154+ ip, _, _ := s.subject.CreateInstance(defaultRelease, defaultChannel)
155
156 c.Assert(ip, check.Equals, instanceIP,
157 check.Commentf("Expected instance IP not returned %s, got %s", instanceIP, ip))
158 }
159
160+func (s *openstackSuite) TestCreateInstanceReturnsInstanceID(c *check.C) {
161+ _, id, _ := s.subject.CreateInstance(defaultRelease, defaultChannel)
162+
163+ c.Assert(id, check.Equals, s.instanceID,
164+ check.Commentf("Expected instance ID not returned %s, got %s", s.instanceID, id))
165+}
166+
167 func (s *openstackSuite) TestKillInstanceCallsKillCommand(c *check.C) {
168 s.subject.CreateInstance(defaultRelease, defaultChannel)
169 s.subject.KillInstance()
170
171=== added directory 'cmd'
172=== added directory 'cmd/snappy-cloud-client'
173=== added file 'cmd/snappy-cloud-client/main.go'
174--- cmd/snappy-cloud-client/main.go 1970-01-01 00:00:00 +0000
175+++ cmd/snappy-cloud-client/main.go 2015-11-30 15:31:39 +0000
176@@ -0,0 +1,70 @@
177+// -*- Mode: Go; indent-tabs-mode: t -*-
178+
179+/*
180+ * Copyright (C) 2015 Canonical Ltd
181+ *
182+ * This program is free software: you can redistribute it and/or modify
183+ * it under the terms of the GNU General Public License version 3 as
184+ * published by the Free Software Foundation.
185+ *
186+ * This program is distributed in the hope that it will be useful,
187+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
188+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
189+ * GNU General Public License for more details.
190+ *
191+ * You should have received a copy of the GNU General Public License
192+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
193+ *
194+ */
195+
196+package main
197+
198+import (
199+ "flag"
200+ "fmt"
201+ "log"
202+ "os"
203+
204+ "launchpad.net/snappy-tests-job/cloud"
205+ "launchpad.net/snappy-tests-job/utils"
206+)
207+
208+const (
209+ defaultCloudProvider = "openstack"
210+ defaultFlavor = "m1.medium"
211+ defaultRelease = "rolling"
212+ defaultChannel = "edge"
213+)
214+
215+func main() {
216+ fCreate := flag.NewFlagSet("fCreate", flag.ContinueOnError)
217+ var (
218+ flavor = fCreate.String("flavor", defaultFlavor,
219+ "Cloud flavor to use, defaults to "+defaultFlavor)
220+ release = fCreate.String("release", defaultRelease,
221+ "Release of the image, defaults to "+defaultRelease)
222+ channel = fCreate.String("channel", defaultChannel,
223+ "Channel of the image, defaults to "+defaultChannel)
224+ )
225+ fKill := flag.NewFlagSet("fKill", flag.ContinueOnError)
226+ var instanceID = fKill.String("instance-id", "", "ID of the instance to kill")
227+
228+ utilHandler := utils.NewBasicHandler()
229+ switch os.Args[1] {
230+ case "create":
231+ if err := fCreate.Parse(os.Args[2:]); err == nil {
232+ cloudClient := cloud.NewCloudClient(defaultCloudProvider, *flavor, utilHandler)
233+ ip, id, err := cloudClient.CreateInstance(*release, *channel)
234+ if err != nil {
235+ log.Panicf("Error creating image for release %s and channel %s, %s", *release, *channel, err)
236+ }
237+ fmt.Println("Instance ID: " + id)
238+ fmt.Println("IP address: " + ip)
239+ }
240+ case "kill":
241+ if err := fKill.Parse(os.Args[2:]); err == nil {
242+ cloudClient := &cloud.OpenstackClient{InstanceID: *instanceID, Util: utilHandler}
243+ cloudClient.KillInstance()
244+ }
245+ }
246+}
247
248=== renamed directory 'snappy-tests-job' => 'cmd/snappy-tests-job'
249=== modified file 'cmd/snappy-tests-job/main.go'
250--- snappy-tests-job/main.go 2015-11-27 16:29:33 +0000
251+++ cmd/snappy-tests-job/main.go 2015-11-30 15:31:39 +0000
252@@ -81,7 +81,7 @@
253 ipString := *ip
254 if ipString == "" {
255 cloudClient := cloud.NewCloudClient(*cloudProvider, *flavor, utilHandler)
256- ipString, err = cloudClient.CreateInstance(*release, *channel)
257+ ipString, _, err = cloudClient.CreateInstance(*release, *channel)
258 defer cloudClient.KillInstance()
259
260 if err != nil {

Subscribers

People subscribed via source and target branches

to all changes: