Merge lp:~bac/lpsetup/fix-inithost-install-lxc into lp:lpsetup

Proposed by Brad Crittenden
Status: Merged
Approved by: Gary Poster
Approved revision: 60
Merged at revision: 52
Proposed branch: lp:~bac/lpsetup/fix-inithost-install-lxc
Merge into: lp:lpsetup
Diff against target: 941 lines (+224/-301)
17 files modified
README.rst (+11/-3)
lplxcip/tests/utils.py (+1/-1)
lpsetup/handlers.py (+7/-4)
lpsetup/settings.py (+3/-1)
lpsetup/subcommands/finish_inithost.py (+48/-94)
lpsetup/subcommands/inithost.py (+15/-4)
lpsetup/subcommands/initlxc.py (+7/-2)
lpsetup/subcommands/initrepo.py (+16/-3)
lpsetup/subcommands/install_lxc.py (+54/-116)
lpsetup/subcommands/update.py (+17/-13)
lpsetup/tests/subcommands/test_finish_inithost.py (+8/-22)
lpsetup/tests/subcommands/test_inithost.py (+1/-1)
lpsetup/tests/subcommands/test_initlxc.py (+2/-2)
lpsetup/tests/subcommands/test_install_lxc.py (+26/-27)
lpsetup/tests/subcommands/test_update.py (+2/-1)
pre-commit.sh (+1/-1)
setup.cfg (+5/-6)
To merge this branch: bzr merge lp:~bac/lpsetup/fix-inithost-install-lxc
Reviewer Review Type Date Requested Status
Gary Poster (community) Approve
Review via email: mp+114486@code.launchpad.net

Commit message

Fix install-lxc and finish-init-host.

Description of the change

A previous branch refactored away some methods that install-lxc and finish-init-host needed. Those commands were neutered and their tests disabled.

This branch fixes them properly. Some stuff from finish-init-host was moved to init-host so that everything in the latter stage all depend upon a Launchpad tree existing.

I poked and prodded setup.cfg and with Francesco's help got a work-around that seems to appease nose.

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :

A run of install-lxc is currently under test in a clean precise VM.

54. By Brad Crittenden

Fix fatal typo

55. By Brad Crittenden

Don't error if launchpad repo already exists

56. By Brad Crittenden

Fix typo

Revision history for this message
Gary Poster (gary) wrote :

Hi Brad. Thank you, this looks very good.

I believe the make_launchpad is called only once, with install=True. This suggests that we could remove that argument from the signature; and it further suggests that we could maybe collapse it into setup_launchpad. Take that as far as you feel comfortable.

I think it would be nice if finish-inithost had a docstring (and help text?) that indicated that it was slated for eventual removal.

The only "must-have" change I have is that install_lxc should not include inithost.SubCommand.initialize_lxc_step. That is run in the lxc container for this story, when we run setup_lxc (which calls inithost in the container). We should not run it in the lxc host.

Thanks again!

Gary

review: Approve
Revision history for this message
Gary Poster (gary) wrote :

Brad and I talked further. install-lxc still needs some more refactoring. he'll circle around and finish that up.

review: Needs Fixing
57. By Brad Crittenden

Added notes on broken install-lxc

58. By Brad Crittenden

checkpoint

59. By Brad Crittenden

Fixes to install_lxc.

60. By Brad Crittenden

Finish up install-lxc and make changes due to testing. Made command-line options unique.

Revision history for this message
Brad Crittenden (bac) wrote :

Gary please look at this again.

Revision history for this message
Gary Poster (gary) wrote :

Wow, thank you Brad. This is great. Everything from the code cleanup, to the code reduction, to the help & doc text improvements are really wonderful.

Could you please make a card, or a quick branch, to have handle_directories use os.path.abspath so we can pass directories like '.'?

The help for the user argument of finish-init-host does not make sense right now. Could you arrange for it to be adjusted to remove references to creating a user, unless you disagree?

review: Approve
Revision history for this message
Francesco Banconi (frankban) wrote :

Gary wrote:
> Could you please make a card, or a quick branch, to have handle_directories use os.path.abspath
> so we can pass directories like '.'?

Yesterday I made this change in the branch I am currently working on: I thought that being able to pass relative paths (e.g. to init-repo) is a really nice thing to have.

Revision history for this message
Brad Crittenden (bac) wrote :

Thanks Gary.
Changes being made in a different branch and merge proposal.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README.rst'
2--- README.rst 2012-07-10 20:00:37 +0000
3+++ README.rst 2012-07-12 22:14:19 +0000
4@@ -11,7 +11,14 @@
5 ~~~~~~~~~~~~
6
7 lp-setup requires:
8-Python >= 2.7, `python-shelltoolbox`, and `pep8`.
9+ lxc
10+ Python >= 2.7
11+ pep8
12+ python-shelltoolbox
13+ python-pocket-lint
14+ python-nose
15+ python-coverage (optional)
16+
17 The package `python-argparse` is required to run lp-setup using Python 2.6.
18
19
20@@ -40,8 +47,10 @@
21
22 To run *lpsetup* tests install nose and run `nosetests` from this directory::
23
24- apt-get install python-nose
25+ apt-get install python-nose python-coverage
26 nosetests
27+ or
28+ ./pre-commit.sh
29
30
31 Integration tests
32@@ -69,7 +78,6 @@
33
34 Install pocketlint::
35
36- sudo apt-add-repository ppa:sinzui/ppa
37 sudo apt-get update
38 sudo apt-get install python-pocket-lint
39
40
41=== modified file 'lplxcip/tests/utils.py'
42--- lplxcip/tests/utils.py 2012-05-03 14:20:13 +0000
43+++ lplxcip/tests/utils.py 2012-07-12 22:14:19 +0000
44@@ -87,7 +87,7 @@
45 '-n', self.name,
46 '-f', self._write_config(),
47 '--',
48- '-r {} -a {}'.format(self.release, self.arch)
49+ '-R {} -a {}'.format(self.release, self.arch),
50 ]
51 return self._call(cmd)
52
53
54=== modified file 'lpsetup/handlers.py'
55--- lpsetup/handlers.py 2012-07-10 18:11:30 +0000
56+++ lpsetup/handlers.py 2012-07-12 22:14:19 +0000
57@@ -220,18 +220,21 @@
58
59
60 def handle_directories(namespace):
61- """Handle checkout and dependencies directories.
62+ """Handle repository, code_dir, and dependencies directories.
63
64 - The ~ construction is automatically expanded.
65 - The validation fails for directories not residing inside the home.
66 - The validation fails if the directory contains spaces.
67 """
68- if ' ' in namespace.repository:
69- raise ValidationError('argument directory can not contain spaces.')
70- for attr in ('repository', 'dependencies_dir'):
71+ for attr in ('repository', 'code_dir', 'dependencies_dir'):
72 directory = getattr(namespace, attr, None)
73 if directory is None:
74 continue
75+ if ' ' in directory:
76+ err = ("argument directory cannot contain "
77+ "spaces: '{0}'".format(directory))
78+ raise ValidationError(err)
79+
80 directory = directory.replace('~', namespace.home_dir)
81 if not directory.startswith(namespace.home_dir + os.path.sep):
82 raise ValidationError(
83
84=== modified file 'lpsetup/settings.py'
85--- lpsetup/settings.py 2012-07-10 15:50:26 +0000
86+++ lpsetup/settings.py 2012-07-12 22:14:19 +0000
87@@ -3,6 +3,7 @@
88 # GNU Affero General Public License version 3 (see the file LICENSE).
89
90 """Global settings and defaults for lpsetup."""
91+import os.path
92
93
94 APT_REPOSITORIES = (
95@@ -53,12 +54,13 @@
96 }
97 LP_BRANCH_NAME = 'devel'
98 LP_CHECKOUT_NAME = 'sandbox'
99+LP_CODE_DIR = os.path.join(CHECKOUT_DIR, LP_CHECKOUT_NAME)
100 LP_PACKAGES = [
101 # "launchpad-database-dependencies-9.1" can be removed once 8.x is
102 # no longer an option in "launchpad-developer-dependencies.
103 'launchpad-database-dependencies-9.1',
104 'launchpad-developer-dependencies', 'apache2',
105- 'apache2-mpm-worker', 'libapache2-mod-wsgi'
106+ 'apache2-mpm-worker', 'libapache2-mod-wsgi',
107 ]
108 LP_HTTP_REPO = 'http://bazaar.launchpad.net/~launchpad-pqm/launchpad/devel'
109 LP_SSH_REPO = 'lp:launchpad'
110
111=== modified file 'lpsetup/subcommands/finish_inithost.py'
112--- lpsetup/subcommands/finish_inithost.py 2012-07-10 15:41:13 +0000
113+++ lpsetup/subcommands/finish_inithost.py 2012-07-12 22:14:19 +0000
114@@ -7,11 +7,12 @@
115 Perform all tasks required to be run to initialize a Launchpad development
116 host that need to be done 1) after the Launchpad tree has been retrieved and
117 2) run as root.
118+
119+This subcommand is slated for eventual removal.
120 """
121
122 __metaclass__ = type
123 __all__ = [
124- 'setup_bzr_locations_as_root',
125 'setup_launchpad',
126 'SubCommand',
127 ]
128@@ -19,7 +20,6 @@
129 from contextlib import nested
130 import os
131 import pwd
132-import subprocess
133
134 from shelltoolbox import (
135 cd,
136@@ -27,116 +27,70 @@
137 su,
138 )
139
140-from lpsetup.handlers import handle_directories
141-from lpsetup.subcommands import (
142- inithost,
143- initrepo,
144- )
145-from lpsetup.settings import (
146- CHECKOUT_DIR,
147- DEPENDENCIES_DIR,
148- LP_BRANCH_NAME,
149- )
150+from lpsetup import argparser
151+from lpsetup.handlers import (
152+ handle_directories,
153+ handle_user,
154+ )
155+from lpsetup.settings import LP_CODE_DIR
156 from lpsetup.utils import call
157
158
159-def make_launchpad(user, checkout_dir, install=False):
160- """Make and optionally install Launchpad."""
161- # Using real su because mailman make script uses uid.
162- call(*get_su_command(user, ['make', '-C', checkout_dir]))
163- if install:
164- call('make', '-C', checkout_dir, 'install')
165-
166-
167-def setup_external_sourcecode(
168- user, sandbox_dir, checkout_dir, dependencies_dir, valid_ssh_keys=True):
169- """Update and link external sourcecode."""
170- cmd = (
171- 'utilities/update-sourcecode',
172- None if valid_ssh_keys else '--use-http',
173- os.path.join(dependencies_dir, 'sourcecode'),
174- )
175- if os.path.exists(sandbox_dir):
176- build_dir = sandbox_dir
177- elif os.path.exists(checkout_dir):
178- build_dir = checkout_dir
179-
180- with cd(build_dir):
181- # Using real su because update-sourcecode uses uid.
182- call(*get_su_command(user, cmd))
183- with su(user):
184- call('utilities/link-external-sourcecode', dependencies_dir)
185-
186-
187-def setup_launchpad(user, dependencies_dir, repository, valid_ssh_keys):
188+def setup_launchpad(user, code_dir):
189 """Set up the Launchpad environment."""
190- # User configuration.
191- subprocess.call(['adduser', user, 'sudo'])
192- pwd_database = pwd.getpwnam(user)
193- subprocess.call(['addgroup', '--gid', str(pwd_database.pw_gid), user])
194- # Set up Launchpad dependencies.
195- # XXX: Eventually move to 'update'.
196- checkout_dir = os.path.join(repository, LP_BRANCH_NAME)
197- setup_external_sourcecode(
198- user, checkout_dir, dependencies_dir, valid_ssh_keys)
199
200 # Launchpad database setup.
201 # nested is required for use by python 2.6.
202- with nested(su(user), cd(checkout_dir)):
203+ with nested(su(user), cd(code_dir)):
204 call('utilities/launchpad-database-setup', user)
205
206 # Make and install launchpad.
207- make_launchpad(user, checkout_dir, install=True)
208+ with cd(code_dir):
209+ # Using real su because mailman make script uses uid.
210+ call(*get_su_command(user, ['make', 'schema']))
211+ call('make', 'install')
212
213 # Change owner of /srv/launchpad.dev/.
214+ pwd_database = pwd.getpwnam(user)
215 os.chown('/srv/launchpad.dev/', pwd_database.pw_uid, pwd_database.pw_gid)
216
217
218-def setup_bzr_locations_as_root(user, lpuser, repository):
219- with su(user):
220- initrepo.setup_bzr_locations(lpuser, repository)
221-
222-
223-class SubCommand(inithost.SubCommand):
224- """Finish the initialization of a Launchpad development host."""
225-
226- # The steps for "install" are a superset of the steps for "inithost".
227+class SubCommand(argparser.StepsBasedSubCommand):
228+ """Finish the initialization of a Launchpad development host.
229+
230+ Run the commands as root in the Launchpad target machine that must be done
231+ after the Launchpad tree is available.
232+
233+ This subcommand is slated for eventual removal.
234+ """
235
236 help = __doc__
237
238- @property
239- def steps(self):
240- # Break import loop (and break it here because this subcommand is
241- # going away soon).
242- import install_lxc
243- return (
244- inithost.SubCommand.initialize_step,
245- install_lxc.SubCommand.fetch_step,
246- (setup_bzr_locations_as_root,
247- 'user', 'lpuser', 'repository'),
248- inithost.SubCommand.setup_apt_step,
249- (setup_launchpad,
250- 'user', 'dependencies_dir', 'repository', 'valid_ssh_keys'),
251- )
252-
253- def get_handlers(self, namespace):
254- handlers = super(SubCommand, self).get_handlers(namespace)
255- return handlers + (handle_directories,)
256+ needs_root = True
257+
258+ steps = (
259+ (setup_launchpad, 'user', 'code_dir'),
260+ )
261+
262+ handlers = (
263+ handle_user,
264+ handle_directories,
265+ )
266+
267+ @staticmethod
268+ def add_common_arguments(parser):
269+ parser.add_argument(
270+ '-c', '--code-dir', default=LP_CODE_DIR,
271+ help='The directory of the Launchpad code checkout. '
272+ 'The directory must reside under the home directory of the '
273+ 'given user (see -u argument). '
274+ '[DEFAULT={0}]'.format(LP_CODE_DIR))
275
276 def add_arguments(self, parser):
277 super(SubCommand, self).add_arguments(parser)
278- parser.add_argument(
279- '-d', '--dependencies-dir', default=DEPENDENCIES_DIR,
280- help='The directory of the Launchpad dependencies to be created. '
281- 'The directory must reside under the home directory of the '
282- 'given user (see -u argument). '
283- '[DEFAULT={0}]'.format(DEPENDENCIES_DIR))
284- parser.add_argument(
285- '-r', '--repository', default=CHECKOUT_DIR,
286- help='The directory of the Launchpad repository to be created. '
287- 'The directory must reside under the home directory of the '
288- 'given user (see -u argument). '
289- '[DEFAULT={0}]'.format(CHECKOUT_DIR))
290- parser.add_argument(
291- '-t', '--with-trees', action='store_false', dest='lightweight',
292- default=True, help='Do not use a lightweight checkout.')
293+ self.add_common_arguments(parser)
294+ parser.add_argument(
295+ '-u', '--user',
296+ help='The name of the system user to be created or updated. '
297+ 'The current user is used if this script is not run as '
298+ 'root and this argument is omitted.')
299
300=== modified file 'lpsetup/subcommands/inithost.py'
301--- lpsetup/subcommands/inithost.py 2012-07-11 11:25:22 +0000
302+++ lpsetup/subcommands/inithost.py 2012-07-12 22:14:19 +0000
303@@ -14,6 +14,7 @@
304
305 from email.Utils import formataddr
306 import os
307+import pwd
308 import shutil
309 import subprocess
310
311@@ -109,6 +110,12 @@
312 if not user_exists(user):
313 call('useradd', '-m', '-s', '/bin/bash', '-U', user)
314
315+ # Add user to the sudo group.
316+ subprocess.call(['adduser', user, 'sudo'])
317+ # Add the user to his own group.
318+ pwd_database = pwd.getpwnam(user)
319+ subprocess.call(['addgroup', '--gid', str(pwd_database.pw_gid), user])
320+
321
322 def initialize(
323 user, full_name, email, lpuser, private_key, public_key, valid_ssh_keys,
324@@ -146,16 +153,20 @@
325 # XXX benji 2012-03-19 bug=959352: this is so graphviz will work in an
326 # ephemeral container
327 mkdirs('/rootfs/usr/lib')
328- os.symlink('/usr/lib/graphviz', '/rootfs/usr/lib/graphviz')
329+ dst = '/rootfs/usr/lib/graphviz'
330+ if not os.path.exists(dst):
331+ os.symlink('/usr/lib/graphviz', dst)
332 # XXX gary 2012-06-26 bug=1014916: this fixes a bug in Lucid LXC
333 # containers.
334 if lxc_os == 'lucid':
335 # Change /var/lib/lxc/lptests/rootfs/etc/init/networking.conf to not
336 # wait for udev (that is, use start on (local-filesystems)).
337 udevtrigger = '/etc/init/udevtrigger.conf'
338- shutil.move(udevtrigger, udevtrigger + '.orig')
339+ if os.path.exists(udevtrigger):
340+ shutil.move(udevtrigger, udevtrigger + '.orig')
341 networking = '/etc/init/networking.conf'
342- shutil.move(networking, networking + '.orig')
343+ if not os.path.exists(networking + '.orig'):
344+ shutil.move(networking, networking + '.orig')
345 render_to_file('networking.conf', {}, networking)
346
347
348@@ -215,7 +226,7 @@
349 'The current user is used if this script is not run as '
350 'root and this argument is omitted.')
351 parser.add_argument(
352- '-e', '--email',
353+ '-E', '--email',
354 help='The email of the user, used for bzr whoami. This argument '
355 'can be omitted if a bzr id exists for current user.')
356 parser.add_argument(
357
358=== modified file 'lpsetup/subcommands/initlxc.py'
359--- lpsetup/subcommands/initlxc.py 2012-07-10 17:36:49 +0000
360+++ lpsetup/subcommands/initlxc.py 2012-07-12 22:14:19 +0000
361@@ -156,7 +156,7 @@
362 private_key, public_key, ssh_key_name, home_dir):
363 """Prepare the Launchpad environment inside an LXC."""
364 # Use ssh to call this script from inside the container.
365- args = ['init-host', '-u', user, '-e', email, '-f', full_name,
366+ args = ['init-host', '-u', user, '-E', email, '-f', full_name,
367 '-l', lpuser, '-S', ssh_key_name,
368 ]
369
370@@ -220,10 +220,15 @@
371 help='The LXC container architecture. '
372 '[DEFAULT={0}]'.format(LXC_GUEST_ARCH))
373 parser.add_argument(
374- '-r', '--lxc-os', default=LXC_GUEST_OS,
375+ '-R', '--lxc-os', default=LXC_GUEST_OS,
376 choices=LXC_GUEST_CHOICES,
377 help='The LXC container distro codename. '
378 '[DEFAULT={0}]'.format(LXC_GUEST_OS))
379 parser.add_argument(
380 '--stop-lxc', action='store_true',
381 help='Shut down the LXC container at the end of the process.')
382+ parser.add_argument(
383+ '--install-subunit', action='store_true',
384+ help='Install subunit in the host machine. Activate this if you '
385+ 'are using this command to create an automated parallel '
386+ 'testing environment e.g. for buildbot.')
387
388=== modified file 'lpsetup/subcommands/initrepo.py'
389--- lpsetup/subcommands/initrepo.py 2012-07-10 18:11:30 +0000
390+++ lpsetup/subcommands/initrepo.py 2012-07-12 22:14:19 +0000
391@@ -2,7 +2,16 @@
392 # Copyright 2012 Canonical Ltd. This software is licensed under the
393 # GNU Affero General Public License version 3 (see the file LICENSE).
394
395-"""initrepo subcommand: prepare source code destinations and download it."""
396+"""init-repo subcommand: prepare source code destinations and download them.
397+
398+Prepares the user's Launchpad directory structure and downloads the
399+latest Launchpad source code. Sets up ~/.bazaar/locations.conf
400+appropriately. The repository uses the sandbox development model as
401+specified in `lxc-install`.
402+
403+Run as the user in the Launchpad target, either a host machine or LXC
404+container.
405+"""
406
407 __metaclass__ = type
408 __all__ = [
409@@ -81,8 +90,8 @@
410 handlers.handle_source,
411 )
412
413- def add_arguments(self, parser):
414- super(SubCommand, self).add_arguments(parser)
415+ @staticmethod
416+ def add_common_arguments(parser):
417 parser.add_argument(
418 '--source', default=None,
419 help='Location from which to retrieve Launchpad source. Default '
420@@ -106,3 +115,7 @@
421 'The directory must reside under the home directory of the '
422 'given user (see -u argument). '
423 '[DEFAULT={0}]'.format(CHECKOUT_DIR))
424+
425+ def add_arguments(self, parser):
426+ super(SubCommand, self).add_arguments(parser)
427+ self.add_common_arguments(parser)
428
429=== modified file 'lpsetup/subcommands/install_lxc.py'
430--- lpsetup/subcommands/install_lxc.py 2012-07-10 19:06:12 +0000
431+++ lpsetup/subcommands/install_lxc.py 2012-07-12 22:14:19 +0000
432@@ -8,38 +8,25 @@
433 __all__ = [
434 'create_scripts',
435 'SubCommand',
436- 'setup_lxc',
437 ]
438
439 import os
440-import subprocess
441
442-from shelltoolbox import (
443- get_su_command,
444- mkdirs,
445- run,
446- su,
447- )
448 from lpsetup.handlers import (
449 handle_directories,
450- handle_testing,
451+ handle_source,
452 )
453 from lpsetup.settings import (
454- LP_BRANCH_NAME,
455- LP_HTTP_REPO,
456- LP_SOURCE_DEPS,
457- LP_SSH_REPO,
458- CHECKOUT_DIR,
459- DEPENDENCIES_DIR,
460 LXC_IP_COMMAND,
461 SCRIPTS,
462 )
463 from lpsetup.subcommands import (
464- inithost,
465+ finish_inithost,
466 initlxc,
467+ initrepo,
468+ update,
469 )
470 from lpsetup.utils import (
471- call,
472 get_file_header,
473 render_to_file,
474 sshlxc as ssh,
475@@ -81,67 +68,43 @@
476 f.write('0\n')
477
478
479-def setup_lxc(lxc_name, ssh_key_path, user, dependencies_dir, repository):
480- """Set up the Launchpad environment inside an LXC."""
481- # Use ssh to call this script from inside the container.
482- args = [
483- 'install', '-u', user, '-s', 'setup_apt', 'setup_bzr_locatoins',
484- 'setup_launchpad', '-d', dependencies_dir, '-r', repository,
485- ]
486- cmd = this_command(repository, args)
487+def cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args, as_user=None):
488+ print "args = ", args
489+ cmd = this_command(home_dir, args)
490+ if as_user is not None:
491+ cmd = "su {} -c '{}'".format(as_user, cmd)
492+ print "CMD = ", cmd
493 ssh(lxc_name, cmd, key=ssh_key_path)
494
495
496-def setup_codebase(user, checkout_dir, dependencies_dir, valid_ssh_keys=True):
497- """Set up Launchpad repository and source dependencies.
498-
499- Return True if new changes are pulled from bzr repository.
500- """
501- # TODO If doing no trees, use --lightweight.
502- # Using real su because bzr uses uid.
503- if os.path.exists(checkout_dir):
504- # Pull the repository.
505- revno_args = ('bzr', 'revno', checkout_dir)
506- revno = run(*revno_args)
507- call(*get_su_command(user, ['bzr', 'pull', '-d', checkout_dir]))
508- changed = revno != run(*revno_args)
509- else:
510- # Branch the repository.
511- # If we have valid SSH keys we should use the "lp:" style URL, "http"
512- # if not.
513- if valid_ssh_keys:
514- repo = LP_SSH_REPO
515- else:
516- repo = LP_HTTP_REPO
517- cmd = ('bzr', 'branch', repo, checkout_dir)
518- call(*get_su_command(user, cmd))
519- changed = True
520- # Check repository integrity.
521- if subprocess.call(['bzr', 'status', '-q', checkout_dir]):
522- raise subprocess.CalledProcessError(
523- 'Repository {0} is corrupted.'.format(checkout_dir))
524- # Set up source dependencies.
525- with su(user):
526- for subdir in ('eggs', 'yui', 'sourcecode'):
527- mkdirs(os.path.join(dependencies_dir, subdir))
528- download_cache = os.path.join(dependencies_dir, 'download-cache')
529- if os.path.exists(download_cache):
530- call('bzr', 'up', download_cache)
531- else:
532- call('bzr', 'co', '--lightweight', LP_SOURCE_DEPS, download_cache)
533- return changed
534-
535-
536-def fetch(user, repository, dependencies_dir, valid_ssh_keys):
537- """Create a repo for the Launchpad code and retrieve it."""
538- # TODO Add --no-trees handling.
539- with su(user):
540- # Set up the repository.
541- mkdirs(repository)
542- call('bzr', 'init-repo', repository)
543- # Set up the codebase.
544- checkout_dir = os.path.join(repository, LP_BRANCH_NAME)
545- setup_codebase(user, checkout_dir, dependencies_dir, valid_ssh_keys)
546+def init_repo_in_lxc(lxc_name, ssh_key_path, home_dir, user, source,
547+ use_http, branch_name, checkout_name, repository):
548+ args = [
549+ 'init-repo', '--source', source,
550+ '--branch-name', branch_name, '--checkout-name', checkout_name,
551+ '--repository', repository,
552+ ]
553+ if use_http:
554+ args.append('--use-http')
555+ cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args, as_user=user)
556+
557+
558+def update_in_lxc(lxc_name, ssh_key_path, home_dir, user, external_path,
559+ use_http, checkout_name, repository):
560+ working_dir = os.path.join(repository, checkout_name)
561+ args = [
562+ 'update', '--external-path', external_path, '-W', working_dir,
563+ ]
564+ if use_http:
565+ args.append('--use-http')
566+ cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args, as_user=user)
567+
568+
569+def finish_inithost_in_lxc(lxc_name, ssh_key_path, home_dir, user, code_dir):
570+ args = [
571+ 'finish-init-host', '--user', user, '--code-dir', code_dir,
572+ ]
573+ cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args)
574
575
576 class SubCommand(initlxc.SubCommand):
577@@ -149,29 +112,23 @@
578 development model.
579 """
580
581- fetch_step = (fetch,
582- 'user', 'repository', 'dependencies_dir', 'valid_ssh_keys')
583-
584- steps = (
585- inithost.SubCommand.initialize_step,
586- fetch_step,
587- (create_scripts,
588- 'lxc_name', 'ssh_key_path', 'user'),
589- initlxc.SubCommand.create_lxc_step + ('install_subunit',),
590- initlxc.SubCommand.start_lxc_step,
591- initlxc.SubCommand.wait_for_lxc_step,
592- # XXX bac, the following step no longer exists. The functionality for
593- # this step needs to be refactored or removed.
594- # initlxc.SubCommand.initialize_lxc_step,
595- (setup_lxc,
596- 'lxc_name', 'ssh_key_path', 'user', 'dependencies_dir', 'repository'),
597- initlxc.SubCommand.stop_lxc_step,
598+ steps = initlxc.SubCommand.steps + (
599+ # Run on host:
600+ (create_scripts, 'lxc_name', 'ssh_key_path', 'user'),
601+ # Run inside the container:
602+ (init_repo_in_lxc, 'lxc_name', 'ssh_key_path', 'home_dir', 'user',
603+ 'source', 'use_http', 'branch_name', 'checkout_name', 'repository'),
604+ (update_in_lxc, 'lxc_name', 'ssh_key_path', 'home_dir', 'user',
605+ 'external_path', 'use_http', 'checkout_name', 'repository'),
606+ (finish_inithost_in_lxc, 'lxc_name', 'ssh_key_path', 'home_dir',
607+ 'user', 'code_dir'),
608 )
609+
610 help = __doc__
611
612 def get_handlers(self, namespace):
613 handlers = super(SubCommand, self).get_handlers(namespace)
614- return handlers + (handle_directories, handle_testing)
615+ return handlers + (handle_directories, handle_source)
616
617 def call_create_scripts(self, namespace, step, args):
618 """Run the `create_scripts` step only if the related flag is set."""
619@@ -180,30 +137,11 @@
620
621 def add_arguments(self, parser):
622 super(SubCommand, self).add_arguments(parser)
623- parser.add_argument(
624- '-d', '--dependencies-dir', default=DEPENDENCIES_DIR,
625- help='The directory of the Launchpad dependencies to be created. '
626- 'The directory must reside under the home directory of the '
627- 'given user (see -u argument). '
628- '[DEFAULT={0}]'.format(DEPENDENCIES_DIR))
629- parser.add_argument(
630- '-c', '--repository', default=CHECKOUT_DIR,
631- help='The directory of the Launchpad repository to be created. '
632- 'The directory must reside under the home directory of the '
633- 'given user (see -u argument). '
634- '[DEFAULT={0}]'.format(CHECKOUT_DIR))
635+ # Inherit arguments from subcommands we depend upon.
636+ initrepo.SubCommand.add_common_arguments(parser)
637+ update.SubCommand.add_common_arguments(parser)
638+ finish_inithost.SubCommand.add_common_arguments(parser)
639 # Add parallel testing related arguments.
640 parser.add_argument(
641 '-C', '--create-scripts', action='store_true',
642 help='Create the scripts used by buildbot for parallel testing.')
643- # The following flag is not present in the inithost sub command since
644- # subunit is always installed there as a dependency of
645- # launchpad-developer-dependencies.
646- parser.add_argument(
647- '--install-subunit', action='store_true',
648- help='Install subunit in the host machine. Activate this if you '
649- 'are using this command to create an automated parallel '
650- 'testing environment e.g. for buildbot.')
651- parser.add_argument(
652- '--testing', action='store_true',
653- help='Same as --feed-random --create-scripts --install-subunit.')
654
655=== modified file 'lpsetup/subcommands/update.py'
656--- lpsetup/subcommands/update.py 2012-07-10 17:25:09 +0000
657+++ lpsetup/subcommands/update.py 2012-07-12 22:14:19 +0000
658@@ -18,7 +18,10 @@
659
660 from lpsetup import argparser
661 from lpsetup import handlers
662-from lpsetup.settings import LP_SOURCE_DEPS
663+from lpsetup.settings import (
664+ LP_CODE_DIR,
665+ LP_SOURCE_DEPS,
666+ )
667
668
669 def initialize_directories(external_path):
670@@ -38,7 +41,7 @@
671 run(cmd, use_http_param, source_path)
672
673 # Update the download cache.
674- download_cache = os.path.join(external_path, 'download-cache')
675+ download_cache = os.path.join(working_dir, 'download-cache')
676 if os.path.exists(download_cache):
677 run('bzr', 'up', download_cache)
678 else:
679@@ -77,20 +80,21 @@
680 handlers.handle_working_dir,
681 )
682
683+ @staticmethod
684+ def add_common_arguments(parser):
685+ parser.add_argument(
686+ '-e', '--external-path', default='.',
687+ help='Path to directory that contains sourcecode '
688+ 'and download-cache directories.')
689+
690 def add_arguments(self, parser):
691 super(SubCommand, self).add_arguments(parser)
692- parser.add_argument(
693- '-e', '--external-path', default='.',
694- help='Path to directory that contains sourcecode '
695- 'and download-cache directories.'
696- )
697+ self.add_common_arguments(parser)
698 parser.add_argument(
699 '--use-http', default=False, action='store_true',
700 help='Force bzr to use http to get the sourcecode '
701- 'branches rather than using bzr+ssh.'
702- )
703+ 'branches rather than using bzr+ssh.')
704 parser.add_argument(
705- 'working_dir', default='.',
706- help='Path to branch to update. Default is '
707- 'the current directory. '
708- )
709+ '-W', '--working-dir', default=LP_CODE_DIR,
710+ help='Path to branch to update. '
711+ '[DEFAULT={0}]'.format(LP_CODE_DIR))
712
713=== renamed file 'lpsetup/tests/subcommands/disabled_test_finish_inithost.py' => 'lpsetup/tests/subcommands/test_finish_inithost.py' (properties changed: +x to -x)
714--- lpsetup/tests/subcommands/disabled_test_finish_inithost.py 2012-07-10 19:35:18 +0000
715+++ lpsetup/tests/subcommands/test_finish_inithost.py 2012-07-12 22:14:19 +0000
716@@ -2,54 +2,40 @@
717 # Copyright 2012 Canonical Ltd. This software is licensed under the
718 # GNU Affero General Public License version 3 (see the file LICENSE).
719
720-"""Tests for the install sub command."""
721+"""Tests for the finish-init-host sub command."""
722
723 import unittest
724
725 from lpsetup import handlers
726 from lpsetup.subcommands import finish_inithost
727-from lpsetup.tests.subcommands import test_inithost
728 from lpsetup.tests.utils import (
729 get_random_string,
730 StepsBasedSubCommandTestMixin,
731 )
732
733
734-setup_bzr_locations_step = (
735- finish_inithost.setup_bzr_locations_as_root,
736- ['user', 'lpuser', 'repository'])
737 setup_launchpad_step = (
738- finish_inithost.setup_launchpad, ['user', 'dependencies_dir', 'repository',
739- 'valid_ssh_keys'])
740+ finish_inithost.setup_launchpad, ['user', 'code_dir'])
741
742
743 def get_arguments():
744- inithost_arguments = test_inithost.get_arguments()
745- dependencies_dir = '~/' + get_random_string()
746- repository = '~/' + get_random_string()
747- return inithost_arguments + ('-d', dependencies_dir, '-r', repository)
748-
749-
750-class InstallTest(StepsBasedSubCommandTestMixin, unittest.TestCase):
751+ code_dir = '~/' + get_random_string()
752+ user = get_random_string()
753+ return ('-c', code_dir, '-u', user)
754+
755+
756+class FinishInitHostTest(StepsBasedSubCommandTestMixin, unittest.TestCase):
757
758 sub_command_class = finish_inithost.SubCommand
759 expected_arguments = get_arguments()
760 expected_handlers = (
761 handlers.handle_user,
762- handlers.handle_lpuser_as_username,
763- handlers.handle_userdata,
764- handlers.handle_ssh_keys,
765 handlers.handle_directories,
766 )
767
768 @property
769 def expected_steps(self):
770- from lpsetup.tests.subcommands import test_install_lxc
771 return (
772- test_inithost.initialize_step,
773- test_install_lxc.fetch_step,
774- setup_bzr_locations_step,
775- test_inithost.setup_apt_step,
776 setup_launchpad_step,
777 )
778 needs_root = True
779
780=== modified file 'lpsetup/tests/subcommands/test_inithost.py'
781--- lpsetup/tests/subcommands/test_inithost.py 2012-07-11 11:47:39 +0000
782+++ lpsetup/tests/subcommands/test_inithost.py 2012-07-12 22:14:19 +0000
783@@ -36,7 +36,7 @@
784 public_key = get_random_string()
785 ssh_key_name = get_random_string()
786 return (
787- '-u', user, '-e', email, '-f', full_name, '-l', lpuser,
788+ '-u', user, '-E', email, '-f', full_name, '-l', lpuser,
789 '-v', private_key, '-b', public_key, '-S', ssh_key_name)
790
791
792
793=== modified file 'lpsetup/tests/subcommands/test_initlxc.py'
794--- lpsetup/tests/subcommands/test_initlxc.py 2012-07-10 17:36:49 +0000
795+++ lpsetup/tests/subcommands/test_initlxc.py 2012-07-12 22:14:19 +0000
796@@ -38,11 +38,11 @@
797 lxc_arch = random.choice(['i386', 'amd64'])
798 lxc_os = random.choice(settings.LXC_GUEST_CHOICES)
799 return (
800- lxc_name, '-A', lxc_arch, '-r', lxc_os,
801+ lxc_name, '-A', lxc_arch, '-R', lxc_os,
802 '--stop-lxc') + inithost_arguments
803
804
805-class InithostTest(StepsBasedSubCommandTestMixin, unittest.TestCase):
806+class InitLxcTest(StepsBasedSubCommandTestMixin, unittest.TestCase):
807
808 sub_command_class = initlxc.SubCommand
809 expected_arguments = get_arguments()
810
811=== renamed file 'lpsetup/tests/subcommands/disabled_test_install_lxc.py' => 'lpsetup/tests/subcommands/test_install_lxc.py' (properties changed: +x to -x)
812--- lpsetup/tests/subcommands/disabled_test_install_lxc.py 2012-07-10 19:35:18 +0000
813+++ lpsetup/tests/subcommands/test_install_lxc.py 2012-07-12 22:14:19 +0000
814@@ -9,7 +9,6 @@
815 from lpsetup import handlers
816 from lpsetup.subcommands import install_lxc
817 from lpsetup.tests.subcommands import (
818- test_inithost,
819 test_initlxc,
820 )
821 from lpsetup.tests.utils import (
822@@ -18,24 +17,32 @@
823 )
824
825
826-fetch_step = (
827- install_lxc.fetch, ['user', 'repository', 'dependencies_dir',
828- 'valid_ssh_keys'])
829 create_scripts_step = (
830 install_lxc.create_scripts, ['lxc_name', 'ssh_key_path', 'user'])
831-create_lxc_callable, create_lxc_args = test_initlxc.create_lxc_step
832-create_lxc_step = (create_lxc_callable, create_lxc_args + ['install_subunit'])
833-setup_lxc_step = (
834- install_lxc.setup_lxc, ['lxc_name', 'ssh_key_path', 'user',
835- 'dependencies_dir', 'repository'])
836+
837+init_repo_in_lxc_step = (
838+ install_lxc.init_repo_in_lxc, [
839+ 'lxc_name', 'ssh_key_path', 'home_dir', 'user', 'source', 'use_http',
840+ 'branch_name', 'checkout_name', 'repository',
841+ ])
842+
843+update_in_lxc_step = (
844+ install_lxc.update_in_lxc, [
845+ 'lxc_name', 'ssh_key_path', 'home_dir', 'user', 'external_path',
846+ 'use_http', 'checkout_name', 'repository',
847+ ])
848+
849+finish_inithost_in_lxc_step = (
850+ install_lxc.finish_inithost_in_lxc, [
851+ 'lxc_name', 'ssh_key_path', 'home_dir', 'user', 'code_dir',
852+ ])
853
854
855 def get_arguments():
856- dependencies_dir = '~/' + get_random_string()
857 repository = '~/' + get_random_string()
858 return test_initlxc.get_arguments() + (
859- '-d', dependencies_dir, '-c', repository,
860- '--create-scripts', '--install-subunit', '--testing',
861+ '-r', repository,
862+ '--create-scripts',
863 )
864
865
866@@ -43,23 +50,15 @@
867
868 sub_command_class = install_lxc.SubCommand
869 expected_arguments = get_arguments()
870- expected_handlers = (
871- handlers.handle_user,
872- handlers.handle_lpuser_as_username,
873- handlers.handle_userdata,
874- handlers.handle_ssh_keys,
875+ expected_handlers = test_initlxc.InitLxcTest.expected_handlers + (
876 handlers.handle_directories,
877- handlers.handle_testing,
878+ handlers.handle_source,
879 )
880- expected_steps = (
881- test_inithost.initialize_step,
882- fetch_step,
883+ expected_steps = test_initlxc.InitLxcTest.expected_steps + (
884 create_scripts_step,
885- create_lxc_step,
886- test_initlxc.start_lxc_step,
887- test_initlxc.wait_for_lxc_step,
888- test_initlxc.initialize_lxc_step,
889- setup_lxc_step,
890- test_initlxc.stop_lxc_step,
891+ init_repo_in_lxc_step,
892+ update_in_lxc_step,
893+ finish_inithost_in_lxc_step,
894 )
895 needs_root = True
896+ maxDiff = None
897
898=== modified file 'lpsetup/tests/subcommands/test_update.py'
899--- lpsetup/tests/subcommands/test_update.py 2012-07-07 12:58:12 +0000
900+++ lpsetup/tests/subcommands/test_update.py 2012-07-12 22:14:19 +0000
901@@ -18,7 +18,8 @@
902 return (
903 '--external-path', get_random_string(),
904 '--use-http',
905- get_random_string(),
906+ '-e', '../devel',
907+ '-W', '~/' + get_random_string(),
908 )
909
910 init_dir_step = (update.initialize_directories, ['external_path'])
911
912=== modified file 'pre-commit.sh'
913--- pre-commit.sh 2012-07-10 17:58:00 +0000
914+++ pre-commit.sh 2012-07-12 22:14:19 +0000
915@@ -1,4 +1,4 @@
916 #!/bin/bash
917
918-pyfiles=`find . -name "*.py" | grep -v distribute_setup.py `
919+pyfiles=`find . -name "*.py" | grep -v distribute_setup.py`
920 pocketlint $pyfiles && pep8 $pyfiles && nosetests
921
922=== modified file 'setup.cfg'
923--- setup.cfg 2012-07-10 19:35:18 +0000
924+++ setup.cfg 2012-07-12 22:14:19 +0000
925@@ -1,11 +1,10 @@
926 [nosetests]
927 detailed-errors=1
928 exclude=handle_testing
929-with-coverage=0
930+with-coverage=1
931 cover-package=lpsetup
932 with-doctest=1
933-# Including ignore-files here or on the command line causes the tests
934-# to fail with a complaint about the version of distribute. As a
935-# work-around, rename disabled tests to 'disabled_'+test_name and set
936-# the execute bit.
937-#ignore-files=disabled*
938+# Specifying 'where' should not be required but it is a work-around
939+# for a problem presented by having 'ignore-files'.
940+where=lpsetup
941+ignore-files=disabled*

Subscribers

People subscribed via source and target branches