Merge lp:~bac/lpsetup/muerte_finis_init_host into lp:lpsetup

Proposed by Brad Crittenden on 2012-08-23
Status: Merged
Approved by: Brad Crittenden on 2012-08-24
Approved revision: 82
Merged at revision: 76
Proposed branch: lp:~bac/lpsetup/muerte_finis_init_host
Merge into: lp:lpsetup
Diff against target: 342 lines (+58/-138)
8 files modified
commands.rst (+1/-19)
lpsetup/cli.py (+0/-2)
lpsetup/subcommands/finish_init_target.py (+0/-99)
lpsetup/subcommands/install_lxc.py (+22/-12)
lpsetup/subcommands/update.py (+13/-0)
lpsetup/tests/subcommands/test_smoke.py (+0/-1)
lpsetup/tests/test_utils.py (+6/-0)
lpsetup/utils.py (+16/-5)
To merge this branch: bzr merge lp:~bac/lpsetup/muerte_finis_init_host
Reviewer Review Type Date Requested Status
Gary Poster (community) 2012-08-23 Approve on 2012-08-23
Review via email: mp+121085@code.launchpad.net

Commit Message

Move everything from finish-init-host to update or install-lxc and remove finish-init-host.

Description of the Change

Move 'make schema' to 'update' subcommand. Move 'make install' and the ownership change of /srv/launchpad.dev to be a final step of 'install-lxc'.

The function 'this_command' was changed to take an optional arbitrary command rather than always using sys.argv[0] to allow other commands to be invoked inside the lxc.

To post a comment you must log in.
Gary Poster (gary) wrote :

Thank you, Brad. This looks good. It is nice to see so much deleted code!

I'm slightly concerned that this code in the new finish function...

206 + # Change owner of /srv/launchpad.dev/.
207 + pwd_database = pwd.getpwnam(user)
208 + os.chown('/srv/launchpad.dev/', pwd_database.pw_uid, pwd_database.pw_gid)

...won't work in some edge cases because it should be using the password database in the container, and not in the host. I can imagine that this edge case won't happen because we need to have the same user in the host and the container, and they need to share passwords. If that's the case, please add a comment to that effect; otherwise, please consider using the container's password database.

In this help text...

231 This is basically the same of running `init-lxc` and then, inside the \
232 - newly created container, `init-repo`, `update` and `finish-init-target`.
233 + newly created container, `init-repo` and `update`.

...I suggest that we instead change the text to say, "This is basically the same as running `init-lxc` and then, inside the newly created container, `lp-setup init-repo`, `lp-setup update` and `make install`." To be clear, that is four changes: s/the same of running/the same as running/, s/`init-repo`/`lp-setup init-repo`, s/`update`/`lp-setup update`/, and s/`finish-init-target`/`make install`.

Thank you!

review: Approve
Launchpad QA Bot (lpqabot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Launchpad QA Bot (lpqabot) wrote :

The attempt to merge lp:~bac/lpsetup/muerte_finis_init_host into lp:lpsetup failed. Below is the output from the failed tests.

./lpsetup/subcommands/install_lxc.py
      16: 'pwd' imported but unused

+ set -o errexit
++ grep -v distribute_setup.py
++ find . -name build -prune -o -name '*.py'
+ pyfiles='./setup.py
./lplxcip/tests/utils.py
./lplxcip/tests/__init__.py
./lplxcip/tests/test_lxcip.py
./lplxcip/tests/test_helpers.py
./lplxcip/tests/test_utils.py
./lplxcip/lxcip.py
./lpsetup/utils.py
./lpsetup/__init__.py
./lpsetup/handlers.py
./lpsetup/tests/utils.py
./lpsetup/tests/__init__.py
./lpsetup/tests/test_argparser.py
./lpsetup/tests/test_cli.py
./lpsetup/tests/test_handlers.py
./lpsetup/tests/subcommands/__init__.py
./lpsetup/tests/subcommands/test_version.py
./lpsetup/tests/subcommands/test_initrepo.py
./lpsetup/tests/subcommands/test_init_target.py
./lpsetup/tests/subcommands/test_smoke.py
./lpsetup/tests/integration/common.py
./lpsetup/tests/integration/test_install_lxc.py
./lpsetup/tests/integration/test_init_target.py
./lpsetup/tests/test_utils.py
./lpsetup/subcommands/__init__.py
./lpsetup/subcommands/install_lxc.py
./lpsetup/subcommands/initlxc.py
./lpsetup/subcommands/init_target.py
./lpsetup/subcommands/update.py
./lpsetup/subcommands/initrepo.py
./lpsetup/subcommands/version.py
./lpsetup/exceptions.py
./lpsetup/argparser.py
./lpsetup/settings.py
./lpsetup/cli.py'
+ pocketlint ./setup.py ./lplxcip/tests/utils.py ./lplxcip/tests/__init__.py ./lplxcip/tests/test_lxcip.py ./lplxcip/tests/test_helpers.py ./lplxcip/tests/test_utils.py ./lplxcip/lxcip.py ./lpsetup/utils.py ./lpsetup/__init__.py ./lpsetup/handlers.py ./lpsetup/tests/utils.py ./lpsetup/tests/__init__.py ./lpsetup/tests/test_argparser.py ./lpsetup/tests/test_cli.py ./lpsetup/tests/test_handlers.py ./lpsetup/tests/subcommands/__init__.py ./lpsetup/tests/subcommands/test_version.py ./lpsetup/tests/subcommands/test_initrepo.py ./lpsetup/tests/subcommands/test_init_target.py ./lpsetup/tests/subcommands/test_smoke.py ./lpsetup/tests/integration/common.py ./lpsetup/tests/integration/test_install_lxc.py ./lpsetup/tests/integration/test_init_target.py ./lpsetup/tests/test_utils.py ./lpsetup/subcommands/__init__.py ./lpsetup/subcommands/install_lxc.py ./lpsetup/subcommands/initlxc.py ./lpsetup/subcommands/init_target.py ./lpsetup/subcommands/update.py ./lpsetup/subcommands/initrepo.py ./lpsetup/subcommands/version.py ./lpsetup/exceptions.py ./lpsetup/argparser.py ./lpsetup/settings.py ./lpsetup/cli.py

Launchpad QA Bot (lpqabot) wrote :
Download full text (6.7 KiB)

The attempt to merge lp:~bac/lpsetup/muerte_finis_init_host into lp:lpsetup failed. Below is the output from the failed tests.

lxc.aa_profile = lxc-container-with-nesting
WARNING: this command will destroy the 'lpsetup-testing-lxc' environment (type: local).
This includes all machines, services, data, and other resources. Continue [y/N]**********************************************************************
* Checking test environment. *
**********************************************************************
**********************************************************************
* Setting up the test environment for LXC container. *
**********************************************************************
----------------------------------------------------------------------
check_call:
juju bootstrap -e lpsetup-testing-lxc
----------------------------------------------------------------------
**********************************************************************
None
**********************************************************************
**********************************************************************
* Cleaning up. *
**********************************************************************

**********************************************************************
* Run time: 0:00:45.895267 *
**********************************************************************

+ set -o errexit
++ find . -name build -prune -o -name '*.py'
++ grep -v distribute_setup.py
+ pyfiles='./setup.py
./lplxcip/tests/utils.py
./lplxcip/tests/__init__.py
./lplxcip/tests/test_lxcip.py
./lplxcip/tests/test_helpers.py
./lplxcip/tests/test_utils.py
./lplxcip/lxcip.py
./lpsetup/utils.py
./lpsetup/__init__.py
./lpsetup/handlers.py
./lpsetup/tests/utils.py
./lpsetup/tests/__init__.py
./lpsetup/tests/test_argparser.py
./lpsetup/tests/test_cli.py
./lpsetup/tests/test_handlers.py
./lpsetup/tests/subcommands/__init__.py
./lpsetup/tests/subcommands/test_version.py
./lpsetup/tests/subcommands/test_initrepo.py
./lpsetup/tests/subcommands/test_init_target.py
./lpsetup/tests/subcommands/test_smoke.py
./lpsetup/tests/integration/common.py
./lpsetup/tests/integration/test_install_lxc.py
./lpsetup/tests/integration/test_init_target.py
./lpsetup/tests/test_utils.py
./lpsetup/subcommands/__init__.py
./lpsetup/subcommands/install_lxc.py
./lpsetup/subcommands/initlxc.py
./lpsetup/subcommands/init_target.py
./lpsetup/subcommands/update.py
./lpsetup/subcommands/initrepo.py
./lpsetup/subcommands/version.py
./lpsetup/exceptions.py
./lpsetup/argparser.py
./lpsetup/settings.py
./lpsetup/cli.py'
+ pocketlint ./setup.py ./lplxcip/tests/utils.py ./lplxcip/tests/__init__.py ./lplxcip/tests/test_lxcip.py ./lplxcip/tests/test_helpers.py ./lplxcip/tests/test_utils.py ./lplxcip/lxcip.py ./lpsetup/utils.py ./lpsetup/__init__.py ./lpsetup/handlers.py ./lpsetup/tests/utils.py ./lpsetup/tests/__init__.py ./lpsetup/tests/test_argparser.py ./lpsetup/tests/test_cli.py ./lpsetup/tests/test_handlers.py ./lpsetup/tests/subcommands/__init__.py ./lpsetup/tests/subcommands/t...

Read more...

Brad Crittenden (bac) wrote :

The previous failure is curious. Retrying.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'commands.rst'
2--- commands.rst 2012-08-15 20:50:45 +0000
3+++ commands.rst 2012-08-24 11:57:42 +0000
4@@ -6,7 +6,7 @@
5
6 usage: lp-setup [-h]
7
8- {finish-init-target,init-target,init-lxc,init-repo,install-lxc,update,version,help}
9+ {init-target,init-lxc,init-repo,install-lxc,update,version,help}
10 ...
11
12 Create and update Launchpad development and testing environments.
13@@ -15,10 +15,7 @@
14 -h, --help show this help message and exit
15
16 subcommands:
17- {finish-init-target,init-target,init-lxc,init-repo,install-lxc,update,version,help}
18 Each subcommand accepts --h or --help to describe it.
19- finish-init-target Finish the initialization of a Launchpad development
20- target.
21 init-target Prepare a machine to run Launchpad. May be an LXC
22 container or not.
23 init-lxc Create an LXC container suitable for later installing
24@@ -108,21 +105,6 @@
25 Run as the user in the Launchpad target, either a host machine or LXC
26 container.
27
28-finish-init-target
29-~~~~~~~~~~~~~~~~~~
30-
31-Finish the initialization of a Launchpad development host.
32-
33-Perform all tasks required to be run to initialize a Launchpad
34-development host that need to be done after the Launchpad tree has
35-been retrieved and run as root.
36-
37-Run as root in the Launchpad target, either a host machine or LXC
38-container. Must be done after `init-target` and `init-repo` have
39-completed.
40-
41-TODO: rename to finish-init-target
42-
43 update
44 ~~~~~~
45
46
47=== modified file 'lpsetup/cli.py'
48--- lpsetup/cli.py 2012-08-23 13:59:29 +0000
49+++ lpsetup/cli.py 2012-08-24 11:57:42 +0000
50@@ -20,7 +20,6 @@
51 exceptions,
52 )
53 from lpsetup.subcommands import (
54- finish_init_target,
55 init_target,
56 initlxc,
57 initrepo,
58@@ -38,7 +37,6 @@
59 ('init-target', init_target.SubCommand()),
60 ('init-repo', initrepo.SubCommand()),
61 ('update', update.SubCommand()),
62- ('finish-init-target', finish_init_target.SubCommand()),
63 ('install-lxc', install_lxc.SubCommand()),
64 ('version', version.SubCommand()),
65 )
66
67=== removed file 'lpsetup/subcommands/finish_init_target.py'
68--- lpsetup/subcommands/finish_init_target.py 2012-08-23 09:05:38 +0000
69+++ lpsetup/subcommands/finish_init_target.py 1970-01-01 00:00:00 +0000
70@@ -1,99 +0,0 @@
71-#!/usr/bin/env python
72-# Copyright 2012 Canonical Ltd. This software is licensed under the
73-# GNU Affero General Public License version 3 (see the file LICENSE).
74-
75-"""Finish the initialization of a Launchpad development host.
76-
77-Perform all tasks required to be run to initialize a Launchpad development
78-host that need to be done 1) after the Launchpad tree has been retrieved and
79-2) run as root.
80-
81-This subcommand is slated for eventual removal.
82-"""
83-
84-__metaclass__ = type
85-__all__ = [
86- 'setup_launchpad',
87- 'SubCommand',
88- ]
89-
90-import os
91-import pwd
92-
93-from shelltoolbox import (
94- cd,
95- get_su_command,
96- )
97-
98-from lpsetup import argparser
99-from lpsetup.handlers import (
100- handle_user,
101- handle_target_dir,
102- )
103-from lpsetup.utils import call
104-
105-
106-def setup_launchpad(user, target_dir):
107- """Set up the Launchpad environment."""
108-
109- # Make and install launchpad.
110- with cd(target_dir):
111- # Using real su because mailman make script uses uid.
112- call(*get_su_command(user, ['make', 'schema']))
113- call('make', 'install')
114-
115- # Change owner of /srv/launchpad.dev/.
116- pwd_database = pwd.getpwnam(user)
117- os.chown('/srv/launchpad.dev/', pwd_database.pw_uid, pwd_database.pw_gid)
118-
119-setup_launchpad.description = """Set up the Launchpad database: this will \
120- destroy any other Postgres db!
121- Make and install Launchpad (buildout dependencies, Apache configuration).
122-"""
123-
124-
125-class SubCommand(argparser.StepsBasedSubCommand):
126- """Finish the initialization of a Launchpad development host.
127-
128- Run the commands as root in the Launchpad target machine that must be done
129- after the Launchpad tree is available.
130-
131- This subcommand is slated for eventual removal.
132- """
133-
134- help = __doc__
135- root_required = True
136- steps = (
137- (setup_launchpad, ['user', 'target_dir']),
138- )
139- handlers = (handle_user, handle_target_dir)
140-
141- epilog = """`%(prog)s` finalizes the Launchpad environment set up.
142- This subcommand must be run once the Launchpad code is retrieved.
143-
144- \tcd mybranch
145- \t$ %(prog)s
146-
147- This is completely equivalent to the following command:
148-
149- \t$ %(prog)s mybranch
150-
151- A user name is required to set up the Launchpad database, and by \
152- default the current system user name is used. If instead this \
153- subcommand is run as root, the user name needs to be explicitly \
154- specified:
155-
156- \t$ %(prog)s -u myuser
157- """
158-
159- def add_arguments(self, parser):
160- super(SubCommand, self).add_arguments(parser)
161- parser.add_argument(
162- 'target_dir', nargs='?', default=os.getcwd(),
163- help='The directory of the Launchpad code checkout. '
164- '[DEFAULT=current directory]')
165- parser.add_argument(
166- '-u', '--user',
167- help='The name of the system user. '
168- 'The current user is used if this script is not run as '
169- 'root and this argument is omitted.')
170
171=== modified file 'lpsetup/subcommands/install_lxc.py'
172--- lpsetup/subcommands/install_lxc.py 2012-08-23 13:26:47 +0000
173+++ lpsetup/subcommands/install_lxc.py 2012-08-24 11:57:42 +0000
174@@ -7,7 +7,6 @@
175 __metaclass__ = type
176 __all__ = [
177 'create_scripts',
178- 'finish_init_target_in_lxc',
179 'init_repo_in_lxc',
180 'SubCommand',
181 'update_in_lxc',
182@@ -127,13 +126,23 @@
183 update.update_tree.description)
184
185
186-def finish_init_target_in_lxc(
187- lxc_name, ssh_key_path, home_dir, user, target_dir):
188- args = ['finish-init-target', target_dir, '--user', user, '--yes']
189- cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args)
190-
191-finish_init_target_in_lxc.description = """Set up the database, make and \
192- install Launchpad inside the LXC instance $lxc_name.
193+def finish_install_in_lxc(
194+ lxc_name, ssh_key_path, user, target_dir):
195+ args = ['install']
196+ cmd = this_command(target_dir, args, cmd='make')
197+ ssh(lxc_name, cmd, key=ssh_key_path)
198+
199+ # Change owner of /srv/launchpad.dev/ by running the following in the
200+ # container as root:
201+ # % chown user:user /srv/launchpad.dev
202+ args = ['{0}:{0}'.format(user), '/srv/launchpad.dev']
203+ cmd = this_command('/', args, cmd='chown')
204+ ssh(lxc_name, cmd, key=ssh_key_path)
205+
206+finish_install_in_lxc.description = """Install Launchpad and \
207+ configure Apache.
208+
209+ Also change ownership of /srv/launchpad.dev to the user.
210 """
211
212
213@@ -151,8 +160,8 @@
214 (update_in_lxc,
215 ['lxc_name', 'ssh_key_path', 'home_dir', 'user', 'external_path',
216 'target_dir', 'lp_source_deps', 'use_http']),
217- (finish_init_target_in_lxc,
218- ['lxc_name', 'ssh_key_path', 'home_dir', 'user', 'target_dir']),
219+ (finish_install_in_lxc,
220+ ['lxc_name', 'ssh_key_path', 'user', 'target_dir']),
221 # Run on host:
222 initlxc.SubCommand.stop_lxc_step,
223 )
224@@ -161,8 +170,9 @@
225 epilog = """`%(prog)s` sets up a complete Launchpad environment in an LXC \
226 container, creating the LXC, configuring the instance, retrieving the code.
227
228- This is basically the same of running `init-lxc` and then, inside the \
229- newly created container, `init-repo`, `update` and `finish-init-target`.
230+ This is basically the same as running `init-lxc` and then, inside the \
231+ newly created container, `lp-setup init-repo`, `lp-setup update`, and
232+ `make install`.
233
234 Set up Launchpad for the current user:
235
236
237=== modified file 'lpsetup/subcommands/update.py'
238--- lpsetup/subcommands/update.py 2012-08-23 08:45:40 +0000
239+++ lpsetup/subcommands/update.py 2012-08-24 11:57:42 +0000
240@@ -16,6 +16,7 @@
241
242 from shelltoolbox import (
243 cd,
244+ get_su_command,
245 mkdirs,
246 )
247
248@@ -78,6 +79,17 @@
249 """
250
251
252+def make_schema(user, target_dir):
253+ """Set up the Launchpad environment."""
254+
255+ # Make and install launchpad.
256+ with cd(target_dir):
257+ # Using real su because mailman make script uses uid.
258+ call(*get_su_command(user, ['make', 'schema']))
259+
260+make_schema.description = """Run 'make schema' within the Launchpad tree."""
261+
262+
263 class SubCommand(argparser.StepsBasedSubCommand):
264 """Updates an existing Launchpad development environment.
265
266@@ -90,6 +102,7 @@
267 (update_dependencies,
268 ['target_dir', 'external_path', 'use_http', 'lp_source_deps']),
269 (update_tree, ['target_dir']),
270+ (make_schema, ['user', 'target_dir']),
271 )
272 help = __doc__
273 handlers = (
274
275=== modified file 'lpsetup/tests/subcommands/test_smoke.py'
276--- lpsetup/tests/subcommands/test_smoke.py 2012-08-15 20:50:45 +0000
277+++ lpsetup/tests/subcommands/test_smoke.py 2012-08-24 11:57:42 +0000
278@@ -27,7 +27,6 @@
279 # and verify that a non-error exit code is returned.
280 required_args = ['-f', 'Example User', '-E', 'email@example.com']
281 name_args_map = {
282- 'finish-init-target': [],
283 'init-target': required_args,
284 'init-lxc': required_args,
285 'init-repo': [],
286
287=== modified file 'lpsetup/tests/test_utils.py'
288--- lpsetup/tests/test_utils.py 2012-08-10 09:16:56 +0000
289+++ lpsetup/tests/test_utils.py 2012-08-24 11:57:42 +0000
290@@ -348,3 +348,9 @@
291 # Ensure arguments are correctly quoted.
292 cmd = this_command(self.directory, ['-arg', 'quote me'])
293 self.check_command(cmd, "-arg 'quote me'")
294+
295+ def test_arbitrary_command(self):
296+ # Ensure the returned command can reference any arbitrary command.
297+ self.script_name = 'ls'
298+ cmd = this_command(self.directory, ['/tmp'], self.script_name)
299+ self.check_command(cmd, '/tmp')
300
301=== modified file 'lpsetup/utils.py'
302--- lpsetup/utils.py 2012-08-13 14:27:59 +0000
303+++ lpsetup/utils.py 2012-08-24 11:57:42 +0000
304@@ -428,22 +428,33 @@
305 return sshcall(cmd)
306
307
308-def this_command(directory, args):
309- """Return a command line to re-launch this script using given `args`.
310+def this_command(directory, args, cmd=None):
311+ """Return a command line to run a command using given `args`.
312
313- The returned command will execute this script from `directory`::
314+ The returned command will execute the command from `directory`.
315+ If cmd is not specified, the invoking script is used::
316
317 >>> script_name = sys.argv[0]
318-
319 >>> cmd = this_command('/home/user/lp/branches', ['install'])
320 >>> cmd == 'cd /home/user/lp/branches && ' + script_name + ' install'
321 True
322
323+ >>> script_name = 'ls'
324+ >>> cmd = this_command('/home/user/lp/branches',
325+ ... ['install'], script_name)
326+ >>> cmd == 'cd /home/user/lp/branches && ' + script_name + ' install'
327+ True
328+
329 Arguments are correctly quoted::
330
331+ >>> script_name = sys.argv[0]
332 >>> cmd = this_command('/path', ['-arg', 'quote me'])
333 >>> cmd == ('cd /path && ' + script_name + " -arg 'quote me'")
334 True
335 """
336- script = join_command(sys.argv[:1] + list(args))
337+ if cmd is None:
338+ cmd = sys.argv[:1]
339+ if isinstance(cmd, basestring):
340+ cmd = [cmd]
341+ script = join_command(cmd + list(args))
342 return join_command(['cd', directory]) + ' && ' + script

Subscribers

People subscribed via source and target branches