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

Proposed by Brad Crittenden on 2012-07-11
Status: Merged
Approved by: Gary Poster on 2012-07-13
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) 2012-07-11 Approve on 2012-07-13
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.
Brad Crittenden (bac) wrote :

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

54. By Brad Crittenden on 2012-07-11

Fix fatal typo

55. By Brad Crittenden on 2012-07-11

Don't error if launchpad repo already exists

56. By Brad Crittenden on 2012-07-11

Fix typo

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
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 on 2012-07-12

Added notes on broken install-lxc

58. By Brad Crittenden on 2012-07-12

checkpoint

59. By Brad Crittenden on 2012-07-12

Fixes to install_lxc.

60. By Brad Crittenden on 2012-07-12

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

Brad Crittenden (bac) wrote :

Gary please look at this again.

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
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.

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