Merge lp:~bigkevmcd/offspring/remove-ssh-url into lp:offspring

Proposed by Kevin McDermott
Status: Merged
Approved by: Cody A.W. Somerville
Approved revision: 127
Merged at revision: 125
Proposed branch: lp:~bigkevmcd/offspring/remove-ssh-url
Merge into: lp:offspring
Diff against target: 353 lines (+29/-222)
6 files modified
lib/offspring/master/models.py (+1/-9)
lib/offspring/master/tests/helpers.py (+0/-2)
lib/offspring/slave/slave.py (+3/-48)
lib/offspring/slave/tests/helpers.py (+24/-0)
lib/offspring/slave/tests/test_slave.py (+1/-161)
migration/002-bzr-ssh-user-key.sql (+0/-2)
To merge this branch: bzr merge lp:~bigkevmcd/offspring/remove-ssh-url
Reviewer Review Type Date Requested Status
Cody A.W. Somerville Approve
Review via email: mp+96544@code.launchpad.net

Description of the change

This strips the SSH url logic and tests.

To post a comment you must log in.
126. By Kevin McDermott

And remove from master.

127. By Kevin McDermott

No longer need the migration directory.

Revision history for this message
Cody A.W. Somerville (cody-somerville) wrote :

You haven't reverted the changes to offspring-build or offspring-web but I'll take care of that when I merge your branch.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/offspring/master/models.py'
2--- lib/offspring/master/models.py 2012-02-16 06:16:58 +0000
3+++ lib/offspring/master/models.py 2012-03-08 18:59:19 +0000
4@@ -105,9 +105,7 @@
5 Pass BuildRequest to a slave server.
6 """
7 status = self.server_proxy.startBuild(request.project.name,
8- request.project.config_url,
9- request.project.lp_user,
10- request.project.lp_ssh_key)
11+ request.project.config_url)
12
13 if status == LexbuilderSlaveServer.REQUEST_OKAY:
14 self.previous_state = self.current_state
15@@ -177,12 +175,6 @@
16 config_url = Unicode()
17 notes = Unicode()
18
19- # The Launchpad User and SSH key are stored per project. If we stored them
20- # per LaunchpadProject, anyone who could create a Project referencing that
21- # LaunchpadProject could get access to the private data in it.
22- lp_user = Unicode()
23- lp_ssh_key = Unicode()
24-
25 def __init__(self, name, priority=40):
26 self.title = unicode(name.capitalize())
27 self.name = unicode(name)
28
29=== modified file 'lib/offspring/master/tests/helpers.py'
30--- lib/offspring/master/tests/helpers.py 2012-02-16 06:16:58 +0000
31+++ lib/offspring/master/tests/helpers.py 2012-03-08 18:59:19 +0000
32@@ -128,8 +128,6 @@
33 "suite VARCHAR(200) NOT NULL, "
34 "status VARCHAR(200), "
35 "notes TEXT, "
36- "lp_user TEXT, "
37- "lp_ssh_key text, "
38 "is_active BOOLEAN NOT NULL DEFAULT TRUE)")
39
40 self.connection.execute(
41
42=== modified file 'lib/offspring/slave/slave.py'
43--- lib/offspring/slave/slave.py 2012-01-24 17:44:17 +0000
44+++ lib/offspring/slave/slave.py 2012-03-08 18:59:19 +0000
45@@ -57,36 +57,13 @@
46 self.server.stop()
47 self.server.join()
48
49- def addUserToBzrSshUrl(self, configBranchURL, lpUser):
50- """Adds lpUser to configBranchURL, returns updated configBranchURL."""
51-
52- # check for lp: format URLs. Convert these to bzr+ssh ones
53- configBranchURL = re.sub("lp:", "bzr+ssh://bazaar.launchpad.net/",
54- configBranchURL)
55-
56- # The assumption is that this function will only be called with a
57- # bzr+ssh URL (hence the name!)
58- assert(re.search("bzr\+ssh://", configBranchURL))
59-
60- # Add user to URL
61- configBranchURL = re.sub("bzr\+ssh://",
62- "bzr+ssh://" + lpUser + "@", configBranchURL)
63-
64- return configBranchURL
65-
66- def startBuild(self, projectName, configBranchURL, lpUser=None,
67- lpSSHKey=None):
68+ def startBuild(self, projectName, configBranchURL):
69 """
70 Instigate a new build for projectName, using the configuration at
71 configBranchURL.
72 """
73- if lpUser:
74- # We don't want to pass the user separately, we want it to be
75- # integrated into the configBranchURL.
76- configBranchURL = self.addUserToBzrSshUrl(configBranchURL, lpUser)
77-
78 self.currentBuild = ProjectBuildProcess(
79- self, projectName, configBranchURL, lpSSHKey)
80+ self, projectName, configBranchURL)
81 logging.info("Starting build: %s %s %s" % (
82 self.currentBuild.getCommandPath(), projectName, configBranchURL))
83 self.currentBuild.start()
84@@ -263,32 +240,11 @@
85
86 class ProjectBuildProcess(MonitoredProcess):
87
88- def __init__(self, supervisor, projectName, configBranchURL,
89- lpSSHKey=None):
90+ def __init__(self, supervisor, projectName, configBranchURL):
91 args = [projectName, configBranchURL]
92- self.ssh_key_file = None
93-
94- if lpSSHKey:
95- # Write SSH key to disk. tempfile will delete it after the build
96- # when this class goes out of scope.
97- # Need to have this here so we can pass the temp file name
98- # containing the key to the builder process on its command line.
99- self.ssh_key_file = tempfile.NamedTemporaryFile()
100- args.append(self.ssh_key_file.name)
101- self.ssh_key_file.write(lpSSHKey)
102- self.ssh_key_file.flush()
103-
104 MonitoredProcess.__init__(self, supervisor, args)
105 self.projectName = projectName
106
107- def __del__(self):
108- self.tidyUp()
109-
110- def tidyUp(self):
111- if self.ssh_key_file:
112- self.ssh_key_file.close()
113- self.ssh_key_file = None
114-
115 def setup(self):
116 self.buildName = None
117
118@@ -311,7 +267,6 @@
119 logging.debug(
120 "Setting state of slave to %s", LexbuilderSlave.STATE_IDLE)
121 self.master.state = LexbuilderSlave.STATE_IDLE
122- self.tidyUp()
123
124 def getCommandPath(self):
125 return self.master.config.get("slave", "build_command")
126
127=== added file 'lib/offspring/slave/tests/helpers.py'
128--- lib/offspring/slave/tests/helpers.py 1970-01-01 00:00:00 +0000
129+++ lib/offspring/slave/tests/helpers.py 2012-03-08 18:59:19 +0000
130@@ -0,0 +1,24 @@
131+from ConfigParser import ConfigParser
132+
133+SLAVE_PORT = 8765
134+
135+
136+class LexbuilderSlaveTestMixin(object):
137+ """
138+ Sets up a configuration object usable by Slave tests.
139+ """
140+
141+ def setUp(self):
142+ super(LexbuilderSlaveTestMixin, self).setUp()
143+ self.log_dir = self.makeDir()
144+ self.config = ConfigParser()
145+ self.config.add_section("slave")
146+ self.config.set("slave", "bin_dir", "/usr/bin")
147+ self.config.set("slave", "log_dir", self.log_dir)
148+ self.config.set("slave", "build_command",
149+ "%(bin_dir)s/offspring-build")
150+ self.config.set("slave", "child_wait_timeout", "0")
151+ self.config.set("slave", "xmlrpc_server_auth", "admin:password")
152+ self.config.set("slave", "request_timeout", "60")
153+ self.config.set("slave", "logfile", "%(log_dir)s/offspring-slave-log")
154+ self.config.set("slave", "port", str(SLAVE_PORT))
155
156=== modified file 'lib/offspring/slave/tests/test_slave.py'
157--- lib/offspring/slave/tests/test_slave.py 2012-01-24 17:44:17 +0000
158+++ lib/offspring/slave/tests/test_slave.py 2012-03-08 18:59:19 +0000
159@@ -8,11 +8,11 @@
160 import subprocess
161 import xmlrpclib
162 from datetime import datetime
163-from ConfigParser import ConfigParser
164
165 from mocker import MockerTestCase
166
167 from offspring.tests.helpers import CaptureLoggingTestCase
168+from offspring.slave.tests.helpers import LexbuilderSlaveTestMixin
169
170 from offspring.enums import ProjectBuildStates
171 from offspring.slave import (
172@@ -68,27 +68,6 @@
173 self.tidied = True
174
175
176-class LexbuilderSlaveTestMixin(object):
177- """
178- Sets up a configuration object usable by Slave tests.
179- """
180-
181- def setUp(self):
182- super(LexbuilderSlaveTestMixin, self).setUp()
183- self.log_dir = self.makeDir()
184- self.config = ConfigParser()
185- self.config.add_section("slave")
186- self.config.set("slave", "bin_dir", "/usr/bin")
187- self.config.set("slave", "log_dir", self.log_dir)
188- self.config.set("slave", "build_command",
189- "%(bin_dir)s/offspring-build")
190- self.config.set("slave", "child_wait_timeout", "0")
191- self.config.set("slave", "xmlrpc_server_auth", "admin:password")
192- self.config.set("slave", "request_timeout", "60")
193- self.config.set("slave", "logfile", "%(log_dir)s/offspring-slave-log")
194- self.config.set("slave", "port", 8765)
195-
196-
197 class FakeProjectBuildProcess(object):
198 state = ProjectBuildProcess.STATE_ACTIVE
199
200@@ -202,145 +181,6 @@
201 self.slave.currentBuild.state = ProjectBuildProcess.STATE_FAILED
202 self.assertEqual(self.slave.currentBuildIsActive(), False)
203
204- def test_add_user_to_bzr_ssh_url(self):
205- """Test lp:project URL form converted into bzr+ssh form adding user."""
206-
207- config_url = u"lp:~dooferlad/offspring/config"
208- user = "user"
209-
210- updated_url = self.slave.addUserToBzrSshUrl(config_url, user)
211- expected_url = ("bzr+ssh://user@bazaar.launchpad.net/~dooferlad/" +
212- "offspring/config")
213- self.assertEqual(updated_url, expected_url)
214-
215- def test_start_build_with_custom_ssh_key(self):
216- """Test slave converts lp:project URL into bzr+ssh form adding user.
217-
218- When sending a URL to the slave in the form lp:project, and
219- a user and SSH key are sent as well, that the slave adds the user
220- into the URL so a private config branch can be checked out (URL needs
221- to be modified to send the user name through BZR to SSH).
222- """
223- log_file = self.capture_logging()
224- build_process_mock = self.mocker.patch(ProjectBuildProcess)
225- build_process_mock.start()
226-
227- sshkey_filename = self.makeFile()
228- tempfile_mock = self.mocker.replace("tempfile.NamedTemporaryFile")
229- tempfile_mock()
230- self.mocker.result(open(sshkey_filename, "w"))
231-
232- self.mocker.replay()
233-
234- config_url = u"lp:~dooferlad/offspring/config"
235- args = ["project_name", config_url, "user", "key"]
236-
237- self.slave.startBuild(*args)
238-
239- new_url = re.sub("lp:",
240- "bzr+ssh://" + args[2] + "@bazaar.launchpad.net/",
241- args[1])
242- self.assertEqual(["project_name", new_url, sshkey_filename],
243- self.slave.currentBuild.arguments)
244- self.assertEqual(
245- "Starting build: /usr/bin/offspring-build project_name %s\n"
246- % new_url, log_file.getvalue())
247-
248- def test_check_ssh_key_deleted_when_build_finished(self):
249- """Test SSH key file lifetime management.
250-
251- The SSH key of a project is written to a temporary file when the
252- build process starts, this is tested by the first assert. When the
253- build has finished or is stopped, the key file is deleted. This is
254- tested by the second assert.
255- """
256- log_file = self.capture_logging()
257- build_process_mock = self.mocker.patch(ProjectBuildProcess)
258- build_process_mock.start()
259- self.mocker.replay()
260-
261- config_url = u"lp:~dooferlad/offspring/config"
262- args = ["project_name", config_url, "user", "key"]
263-
264- self.slave.startBuild(*args)
265-
266- file_path = self.slave.currentBuild.ssh_key_file.name
267- read_key = open(file_path).read()
268-
269- # We should have a key written to a file for the slave to read...
270- self.assertEqual(read_key, args[3])
271-
272- # Can't use XMLRPC interface here because it checks to see if a build
273- # has actually started. We just want to test the clean up logic.
274- self.slave.stopBuild()
275- # Having stopped the slave, the key should have been erased
276- self.assertFalse(os.path.exists(file_path))
277-
278- def test_check_ssh_agent(self):
279- """Check that SSH agent is started and killed by build.
280-
281- In order to pass private keys to SSH, the build script starts
282- ssh-agent if a private key file is passed to it. When the build has
283- completed, the build script kills SSH agent.
284-
285- This test uses the called shell script to test the functions used
286- by the build script to start ssh-agent, load the specified key and
287- kill the started ssh-agent process.
288-
289- """
290- # This is a wrapper around a shell script that runs the commands and
291- # we just check the output.
292-
293- dir_of_this_file = os.path.dirname(os.path.abspath(__file__))
294- test_script = os.path.join(dir_of_this_file,
295- "../../build/tests/test.sh")
296-
297- test_script_process = subprocess.Popen(test_script,
298- stdout=subprocess.PIPE,
299- stderr=subprocess.STDOUT)
300-
301- stdout = test_script_process.communicate()[0]
302-
303- lines = stdout.split("\n")
304-
305- # Sample output:
306- # Agent pid 9839
307- # Identity added: /bla/offspring_test_key (/bla/offspring_test_key)
308- # After loading test key, keys are:
309- # 2048 <fingerprint> /bla/offspring_test_key (RSA)
310- # After killing ssh agent, we shouldn't be able to find any keys...
311- # Could not open a connection to your authentication agent.
312-
313- # Expect the first line to be of the form "Agent pid [PID]"
314- self.assertTrue(re.search("Agent pid \d+", lines[0]),
315- "Test build ssh-agent check failed: Expected to find" +
316- "\nAgent pid <PID>\nfound:\n" + lines[0])
317-
318- # Expect the second line to be of the form:
319- # Identity added: <path to...>/offspring_test_key
320- self.assertTrue(re.search("Identity added:.*?offspring_test_key",
321- lines[1]),
322- "Test build ssh-agent check failed: Expected to find" +
323- "\nIdentity added: <path to...>/offspring_test_key" +
324- "\nfound:\n" + lines[1])
325-
326- # Ignore the third line, it is just a fixed message
327- # Expect the fourth line to be:
328- # <key fingerprint> /path/to/offspring_test_key (RSA)
329- self.assertTrue(re.search("offspring_test_key \(RSA\)", lines[3]),
330- "Test build ssh-agent check failed: Expected to find" +
331- "\noffspring_test_key (RSA)\nfound:\n" + lines[3])
332-
333- # Ignore the fifth line, it is just a fixed message
334- # Expect the sixth line to be:
335- # "Could not open a connection to your authentication agent."
336- search_string = (
337- "^Could not open a connection to your authentication agent\.$")
338- message = ("Test build ssh-agent check failed: Expected to find" +
339- "\nCould not open a connection to your authentication" +
340- "agent\n, found:\n" + lines[5])
341- self.assertTrue(re.search(search_string, lines[5]), message)
342-
343
344 class FakeLexbuilderSlave(object):
345 """Fake slave for use in tests."""
346
347=== removed directory 'migration'
348=== removed file 'migration/002-bzr-ssh-user-key.sql'
349--- migration/002-bzr-ssh-user-key.sql 2011-11-30 14:20:32 +0000
350+++ migration/002-bzr-ssh-user-key.sql 1970-01-01 00:00:00 +0000
351@@ -1,2 +0,0 @@
352-ALTER TABLE projects ADD COLUMN "lp_user" text;
353-ALTER TABLE projects ADD COLUMN "lp_ssh_key" text;

Subscribers

People subscribed via source and target branches