Merge lp:~flacoste/maas/buildout-site-packages into lp:~maas-committers/maas/trunk

Proposed by Francis J. Lacoste
Status: Merged
Approved by: Francis J. Lacoste
Approved revision: no longer in the source branch.
Merged at revision: 203
Proposed branch: lp:~flacoste/maas/buildout-site-packages
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 323 lines (+208/-44)
4 files modified
HACKING.txt (+37/-8)
buildout.cfg (+36/-5)
setup.py (+37/-4)
versions.cfg (+98/-27)
To merge this branch: bzr merge lp:~flacoste/maas/buildout-site-packages
Reviewer Review Type Date Requested Status
Dave Walker (community) Approve
Gavin Panella (community) Approve
Raphaël Badin Pending
Launchpad code reviewers Pending
Review via email: mp+94628@code.launchpad.net

Commit message

Add explicit versioning for the buildout dependencies. Integrate buildout-versions to manage versions.cfg. Load runtime dependencies from site packages.

Description of the change

This branch adds explicit versioning the the MaaS dependencies.

It adds buildout-versions which makes it easy to manage the versions.cfg
file.

All runtime dependencies are loaded from site packages (well, if they are
available, apart Django, there is not much harm done if you didn't install
the package, as it will still pull it from PyPI).

I turned off allow-picked-versions which will make buildout complain if any
new dependencies are introduced without adding the correct entry to
versions.cfg This should make us more mindful of introducing dep and make us
pause to see if this is a runtime dep (should be packaged and loaded from
site-packages) or a dev-only dep.

I also updated setup.py with the dependencies.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :
Download full text (3.1 KiB)

Looks good. Lots of comments, mostly trivial. However, setup.py is
broken, so Needs Fixing.

[1]

+You will need to manually install Postgres 9.1 (postgresql-9.1),
+, RabbitMQ (rabbitmq-server), python-dev and make::

s/^, //

[2]

+Additionally, you probably want to install the following python libraries
+for development convenience::

s/probably want/need/, at least for python-lxml.

[3]

+possible. You'll need to add the dependency to the
+``allowed-eggs-from-site-packages`` option in the ``buildout.cfg`` file. (And
+don't forget to add the version to ``versions.cfg`` as we run with
+``allowed-picked-version`` set to false.)

Might be worth mentioning that it also needs to be added to setup.py.

It would be nice if we could auto-generate versions.cfg from setup.py,
or vice-versa. Actually, doesn't buildout use dependency information
from setup.py?

[4]

+If it is a development-only depency (i.e. only needed for the test suite, or

s/depency/dependency/

[5]

+buildout_versions_file = versions.cfg

Grr, everything else uses hyphens. /me emails buildout-versions
author.

[6]

+download-cache = download-cache

/^download-cache/d

We've chosen to *not* define this in <branch>/buildout.cfg; we're
using ~/.buildout/default.cfg to use a shared cache. This is much
easier than following the Launchpad model while MaaS's deps are small
enough.

[7]

+allowed-eggs-from-site-packages =
+ Django
+ South
...

I know it's trivial, but the rest of the file uses 2 spaces for
indentation :)

[8]

+ # Convenient developer dependencies
+ Jinja2
+ Pygments

Are these dependencies of Sphinx? They're not direct dependencies I
think, so can they be left out here?

[9]

+ install_requires=[
+ 'setuptools',
+ 'Django' = 1.3.1,

This doesn't work. This does:

        'Django == 1.3.1',

[10]

+ extra_requires=dict(

s/extra_requires/extras_require/

Also, there's a missing brace at the end of setup.py.

[11]

+# Automatic versions in Precise

Is this something that buildout-versions provides?

[12]

We could structure versions.cfg like so:

  [versions]
  <= versions-run
     versions-dev
     versions-doc
     versions-auto

  [versions-run]
  Django = ...

  [versions-dev]
  lxml = ...

  [version-doc]
  Sphinx = ...

  [versions-auto]
  buildout-versions = ...

Then we could pull these out in setup.py:

  versions = ConfigParser.ConfigParser()
  versions.read("versions.cfg")

  def gen_deps(section):
      for option in versions.options(section):
          value = versions.get(section, option)
          if options[-1] in "<!>":
              yield b"%s=%s" % (option, value)
          else:
              yield b"%s==%s" % (option, value)

  deps = lambda section: list(gen_deps(section))

  ...
      install_requires=(
          deps("versions-run") +
          deps("versions-auto")),
  ...
      extras_require={
          b'doc': deps("versions-doc"),
          b'tests': deps("versions-run"),
          },

And, after using buildout-versions to update versions.cfg, we should
probably merge the automatically added things into their appropriate
section in versions.cfg.

[13]

Does buildout-versions help us notice depende...

Read more...

review: Needs Fixing
Revision history for this message
Francis J. Lacoste (flacoste) wrote :
Download full text (3.9 KiB)

On 12-02-24 06:41 PM, Gavin Panella wrote:
> Review: Needs Fixing
>
> Looks good. Lots of comments, mostly trivial. However, setup.py is
> broken, so Needs Fixing.

Thanks for the review, I've fixed everything you asked for.

>
> It would be nice if we could auto-generate versions.cfg from setup.py,
> or vice-versa. Actually, doesn't buildout use dependency information
> from setup.py?

It does, but versions.cfg is applied on top of those. The general rule
of setup.py is that you don't pin version unless your package won't work
with any other version, whereas we use version pinning in buildout for
repeatable builds.

>
> [5]
>
> +buildout_versions_file = versions.cfg
>
> Grr, everything else uses hyphens. /me emails buildout-versions
> author.

:-)

>
>
> [6]
>
> +download-cache = download-cache
>
> /^download-cache/d
>
> We've chosen to *not* define this in <branch>/buildout.cfg; we're
> using ~/.buildout/default.cfg to use a shared cache. This is much
> easier than following the Launchpad model while MaaS's deps are small
> enough.

Well, ok. But I disagree, it's not easier than the Launchpad model if
you have a lot of different projects managed by buildout. In which case,
you end up with a massive eggs and download-cache where it's very hard
to know what comes from where.

>
> [8]
>
> + # Convenient developer dependencies
> + Jinja2
> + Pygments
>
> Are these dependencies of Sphinx? They're not direct dependencies I
> think, so can they be left out here?

They are, but they still need to be added here otherwise buildout will
install them from PyPI.

>
>
> [11]
>
> +# Automatic versions in Precise
>
> Is this something that buildout-versions provides?
>

Unfortunately, no, buildout-versions doesn't pick up the dependency
coming from system python. I need to report a bug (probably submit a
fix) upstream. The future version of buildout (2.0) actually drop the
system eggs support that Gary added. It seems that nobody but us is
using that and supporting it requires isn't trivial, so upstream decided
to drop it.

>
> [12]
>
> We could structure versions.cfg like so:
>
> [versions]
> <= versions-run
> versions-dev
> versions-doc
> versions-auto
>
> [versions-run]
> Django = ...
>
> [versions-dev]
> lxml = ...
>
> [version-doc]
> Sphinx = ...
>
> [versions-auto]
> buildout-versions = ...
>
> Then we could pull these out in setup.py:
>
> versions = ConfigParser.ConfigParser()
> versions.read("versions.cfg")
>
> def gen_deps(section):
> for option in versions.options(section):
> value = versions.get(section, option)
> if options[-1] in "<!>":
> yield b"%s=%s" % (option, value)
> else:
> yield b"%s==%s" % (option, value)
>
> deps = lambda section: list(gen_deps(section))
>
> ...
> install_requires=(
> deps("versions-run") +
> deps("versions-auto")),
> ...
> extras_require={
> b'doc': deps("versions-doc"),
> b'tests': deps("versions-run"),
> },
>
> And, after using buildout-versions to update versions.cfg, we should
> probably merge the au...

Read more...

Revision history for this message
Gavin Panella (allenap) wrote :

> Thanks for the review, I've fixed everything you asked for.

I'm very sorry I didn't reply yesterday; I had forgotten I marked it
Needs Fixing (and I obviously can't read email).

> > [6]
> >
> > +download-cache = download-cache
> >
> > /^download-cache/d
> >
> > We've chosen to *not* define this in <branch>/buildout.cfg; we're
> > using ~/.buildout/default.cfg to use a shared cache. This is much
> > easier than following the Launchpad model while MaaS's deps are small
> > enough.
>
> Well, ok. But I disagree, it's not easier than the Launchpad model if
> you have a lot of different projects managed by buildout. In which case,
> you end up with a massive eggs and download-cache where it's very hard
> to know what comes from where.

I agree with having a separate download-cache and eggs directory when
deploying from a tree built using buildout, like Launchpad. Then you
can't go and nuke the shared caches because you'll break things. But
for MaaS, buildout is only for development, so using a shared cache -
so that all branches build quickly without having to think about it -
is a win.

> > [12]
...
> I've reordered the file versions.cfg file as you suggested, but I'm not
> sure that generating the setup.py dependency from versions.cfg is such a
> good idea. This will basically mean that the version will be pinned like
> in buildout, which is good for repeatable builds, but not so much for
> general use. Given that we are not going to release that package on
> PyPI, maybe that's kind of moot (and mean that setup.py isn't that
> interesting either).

Why no release on PyPI?

Looks good to go, +1.

review: Approve
Revision history for this message
Francis J. Lacoste (flacoste) wrote :

On 12-02-28 08:39 AM, Gavin Panella wrote:
> Review: Approve
>
>> Thanks for the review, I've fixed everything you asked for.
>
> I'm very sorry I didn't reply yesterday; I had forgotten I marked it
> Needs Fixing (and I obviously can't read email).
>
>>> [6]
>>>
>>> +download-cache = download-cache
>>>
>>> /^download-cache/d
>>>
>>> We've chosen to *not* define this in <branch>/buildout.cfg; we're
>>> using ~/.buildout/default.cfg to use a shared cache. This is much
>>> easier than following the Launchpad model while MaaS's deps are small
>>> enough.
>>
>> Well, ok. But I disagree, it's not easier than the Launchpad model if
>> you have a lot of different projects managed by buildout. In which case,
>> you end up with a massive eggs and download-cache where it's very hard
>> to know what comes from where.
>
> I agree with having a separate download-cache and eggs directory when
> deploying from a tree built using buildout, like Launchpad. Then you
> can't go and nuke the shared caches because you'll break things. But
> for MaaS, buildout is only for development, so using a shared cache -
> so that all branches build quickly without having to think about it -
> is a win.

Right, I'm all for using a shared cache, and I symlink download-cache to
that shared cache. My beef is just that if the way you set your shared
cache is ~/.buildout/defaults.cfg then that's shared cache is actually
used for all of your buildout-managed development projects (which don't
override it locally). And that's what I personally don't like. But like
I said, it's more a personal preferences than anything else.

>
>>> [12]
> ...
>> I've reordered the file versions.cfg file as you suggested, but I'm not
>> sure that generating the setup.py dependency from versions.cfg is such a
>> good idea. This will basically mean that the version will be pinned like
>> in buildout, which is good for repeatable builds, but not so much for
>> general use. Given that we are not going to release that package on
>> PyPI, maybe that's kind of moot (and mean that setup.py isn't that
>> interesting either).
>
> Why no release on PyPI?
>

Well, that's not a binding decision. We could upload it to PyPI I guess,
but given that this is more an application than a library and that it's
targeted at deployment in Ubuntu... why bother?

> Looks good to go, +1.
>

Thanks!

--
Francis J. Lacoste
<email address hidden>

Revision history for this message
Dave Walker (davewalker) wrote :

Bouncing approved status to see if tarmac catches it.

review: Approve
Revision history for this message
Raphaël Badin (rvb) wrote :

Sorry but this broke the build so after a discussion with the team we decided to revert this change.

See: https://code.launchpad.net/~rvb/maas/maas-revert-buildout-chang/+merge/95140 for details.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'HACKING.txt'
2--- HACKING.txt 2012-02-24 11:16:36 +0000
3+++ HACKING.txt 2012-02-27 21:22:17 +0000
4@@ -23,20 +23,32 @@
5
6 Prerequisites
7 =============
8-You will need to manually install Postgres 9.1 (postgresql-9.1 and
9-libpq-dev), RabbitMQ (rabbitmq-server), python-dev and make::
10-
11- $ sudo apt-get install postgresql-9.1 libpq-dev rabbitmq-server python-dev make
12+You will need to manually install Postgres 9.1 (postgresql-9.1),
13+RabbitMQ (rabbitmq-server), python-dev and make::
14+
15+ $ sudo apt-get install postgresql-9.1 rabbitmq-server python-dev make
16+
17
18 Also, you might want to install Bazaar (bzr) to grab the source code directly
19 from Launchpad::
20
21 $ sudo apt-get install bzr
22
23-If you intend to run the test suite, you also need libxslt1-dev, libxml2-dev,
24-xvfb and firefox::
25-
26- $ sudo apt-get install libxslt1-dev libxml2-dev xvfb firefox
27+This is the list of runtime dependencies that you'll need to install::
28+
29+ $ sudo apt-get install python-django python-django-piston \
30+ python-django-south python-twisted python-txamqp python-amqplib \
31+ python-formencode python-oauth python-oops python-oops-datedir-repo \
32+ python-twisted python-oops-wsgi python-psycopg2 python-yaml
33+
34+Additionally, you need to install the following python libraries
35+for development convenience::
36+
37+ $ sudo apt-get install python-sphinx python-lxml
38+
39+If you intend to run the test suite, you also need xvfb and firefox::
40+
41+ $ sudo apt-get install xvfb firefox
42
43 All other development dependencies are pulled automatically from `PyPI`_
44 when buildout runs.
45@@ -107,6 +119,22 @@
46
47 $ make distclean
48
49+Adding new dependencies
50+=======================
51+
52+Since MaaS is distributed mainly as Ubuntu package, all runtime dependencies
53+should be packaged and we should develop with the packaged version if
54+possible. You'll need to add the dependency to the
55+``allowed-eggs-from-site-packages`` option in the ``buildout.cfg`` file. You
56+also need to add it to setup.py (And don't forget to add the version to
57+``versions.cfg`` as we run with ``allowed-picked-version`` set to false.)
58+
59+If it is a development-only dependency (i.e. only needed for the test suite, or
60+for developers' convenience), simply running ``buildout`` like this will make
61+the necessary updates to ``versions.cfg``::
62+
63+ $ ./bin/buildout -v buildout:allow-picked-versions=true
64+
65
66 Adding new source files
67 =======================
68@@ -126,3 +154,4 @@
69
70 .. _convention for headings as used in the Python documentation:
71 http://sphinx.pocoo.org/rest.html#sections
72+
73
74=== modified file 'buildout.cfg'
75--- buildout.cfg 2012-02-24 10:54:15 +0000
76+++ buildout.cfg 2012-02-27 21:22:17 +0000
77@@ -7,12 +7,43 @@
78 pserv-test
79 repl
80 sphinx
81+extensions = buildout-versions
82+buildout_versions_file = versions.cfg
83+versions = versions
84 extends = versions.cfg
85-versions = versions
86-include-site-packages = false
87-# Don't always check for newer packages; use `bin/buildout -n` to
88-# override this and check explicitly.
89-newest = false
90+install-from-cache = false
91+
92+# Since MaaS's main deployment target is Ubuntu, all
93+# runtime dependencies should come from python packages.
94+# Only development-time dependencies should come from eggs.
95+# For convenience, we allow some of those to come from site-packages,
96+# mainly those which contains C extensions like lxml
97+include-site-packages = true
98+allowed-eggs-from-site-packages =
99+ Django
100+ South
101+ amqplib
102+ django-piston
103+ FormEncode
104+ oauth
105+ oops
106+ oops-datedir-repo
107+ oops-twisted
108+ oops-wsgi
109+ psycopg2
110+ PyYAML
111+ Twisted
112+ txAMQP
113+ # Convenient developer dependencies
114+ Jinja2
115+ Pygments
116+ Sphinx
117+ docutils
118+ lxml
119+ ipython
120+
121+prefer-final = true
122+allow-picked-versions = false
123
124 [common]
125 extra-paths =
126
127=== modified file 'setup.py'
128--- setup.py 2012-01-24 12:53:05 +0000
129+++ setup.py 2012-02-27 21:22:17 +0000
130@@ -40,7 +40,7 @@
131 name="maas",
132 version=__version__,
133 url="https://launchpad.net/maas",
134- license="GPL",
135+ license="AGPLv3",
136 description="Metal as as Service",
137 long_description=read('README.txt'),
138
139@@ -56,8 +56,22 @@
140 ),
141 package_dir={'': b'src'},
142
143- install_requires=['setuptools'],
144-
145+ install_requires=[
146+ 'setuptools',
147+ 'Django == 1.3.1',
148+ 'psycopg2',
149+ 'amqplib',
150+ 'django-piston',
151+ 'FormEncode',
152+ 'oauth',
153+ 'oops',
154+ 'oops-datedir-repo',
155+ 'oops-twisted',
156+ 'PyYAML',
157+ 'South',
158+ 'Twisted',
159+ 'txAMQP',
160+ ],
161 classifiers=[
162 'Development Status :: 4 - Beta',
163 'Framework :: Django',
164@@ -67,5 +81,24 @@
165 'Operating System :: OS Independent',
166 'Programming Language :: Python',
167 'Topic :: Internet :: WWW/HTTP',
168- ]
169+ ],
170+ extras_require=dict(
171+ doc=[
172+ 'collective.recipe.sphinxbuilder',
173+ 'Sphinx',
174+ ],
175+ tests=[
176+ 'coverage',
177+ 'django-nose',
178+ 'lxml',
179+ 'sst',
180+ 'fixtures',
181+ 'nose',
182+ 'nose-subunit',
183+ 'python-subunit',
184+ 'rabbitfixture',
185+ 'testresources',
186+ 'testtools',
187+ ],
188 )
189+)
190
191=== modified file 'versions.cfg'
192--- versions.cfg 2012-02-24 10:54:15 +0000
193+++ versions.cfg 2012-02-27 21:22:17 +0000
194@@ -1,31 +1,102 @@
195 [versions]
196-coverage =
197-django = 1.3.1
198+<= versions-run
199+ versions-dev
200+ versions-doc
201+ versions-auto
202+
203+[versions-run]
204+# Actually, we depend on the version of django in Ubuntu precise
205+# which contains the backported fix for
206+# https://code.djangoproject.com/ticket/16250
207+# Otherwise, psycopg2 > 2.4.1 is problematic with Django 1.3.1.
208+Django = 1.3.1
209+# psycopg2 = 2.4.1
210+psycopg2 = 2.4.4
211+
212+# Versions in Precise
213+amqplib = 1.0.0
214+django-piston = 0.2.3
215+FormEncode = 1.2.4
216+oauth = 1.0.1
217+oops = 0.0.10
218+oops-datedir-repo = 0.0.15
219+oops-twisted = 0.0.6
220+oops-wsgi = 0.0.9
221+PyYAML = 3.10
222+South = 0.7.3
223+Twisted = 11.1.0
224+txAMQP = 0.5
225+
226+[versions-doc]
227+# Versions in Precise
228+docutils = 0.8.1
229+Jinja2 = 2.6
230+Pygments = 1.4
231+Sphinx = 1.0.8
232+lxml = 2.3.2
233+
234+[versions-dev]
235+ipython = 0.12
236 # Bug 251 is problematic in 0.9.2.
237 django-debug-toolbar = 0.9.1
238-django-nose =
239-django-piston =
240-docutils =
241-fixtures =
242-formencode = 1.2.4
243-ipython =
244-lxml =
245-nose =
246-nose-subunit =
247-oauth =
248-oops =
249-oops-datedir-repo =
250-oops-twisted =
251-oops-wsgi =
252-# psycopg2 > 2.4.1 is problematic with Django 1.3.1; see
253-# https://code.djangoproject.com/ticket/16250
254-psycopg2 = 2.4.1
255-python-subunit =
256-pyyaml = 3.10
257+
258+[versions-auto]
259+# Added by Buildout Versions at 2012-02-24 15:51:04.865203
260+buildout-versions = 1.7
261+collective.recipe.sphinxbuilder = 0.7.0
262+coverage = 3.5.1
263+distribute = 0.6.24
264+django-nose = 0.1.3
265+fixtures = 0.3.8
266+flake8 = 1.1
267+nose = 1.1.2
268+nose-subunit = 0.2
269+python-subunit = 0.0.7
270 rabbitfixture = 0.3.2
271-South =
272-sst =
273-testresources >= 0.2.4-r58
274-testtools =
275-twisted =
276-txamqp =
277+testresources = 0.2.5
278+testtools = 0.9.14
279+z3c.recipe.scripts = 1.0.1
280+
281+# Required by:
282+# collective.recipe.sphinxbuilder==0.7.0
283+zc.buildout = 1.5.2
284+
285+# Required by:
286+# collective.recipe.sphinxbuilder==0.7.0
287+zc.recipe.egg = 1.3.2
288+
289+# Added by Buildout Versions at 2012-02-24 16:56:06.100791
290+PyVirtualDisplay = 0.0.9
291+sst = 0.1.0
292+
293+# Required by:
294+# PyVirtualDisplay==0.0.9
295+EasyProcess = 0.1.3
296+
297+# Required by:
298+# entrypoint2==0.0.4
299+argparse = 1.2.1
300+
301+# Required by:
302+# entrypoint2==0.0.4
303+decorator = 3.3.2
304+
305+# Required by:
306+# PyVirtualDisplay==0.0.9
307+entrypoint2 = 0.0.4
308+
309+# Required by:
310+# sst==0.1.0
311+junitxml = 0.6
312+
313+# Required by:
314+# PyVirtualDisplay==0.0.9
315+path.py = 2.2.2
316+
317+# Required by:
318+# sst==0.1.0
319+selenium = 2.19.1
320+
321+# Required by:
322+# sst==0.1.0
323+unittest2 = 0.5.1