Merge lp:~allenap/maas/repackage into lp:maas/trunk

Proposed by Gavin Panella
Status: Rejected
Rejected by: MAAS Lander
Proposed branch: lp:~allenap/maas/repackage
Merge into: lp:maas/trunk
Prerequisite: lp:~allenap/maas/repackage-prep
Diff against target: 5403 lines (+3060/-1035)
94 files modified
.bzrignore (+12/-1)
HACKING.txt (+5/-52)
MANIFEST.in (+0/-10)
Makefile (+111/-131)
buildout.cfg (+0/-232)
etc/maas_local_celeryconfig_cluster.py (+0/-4)
pkg/Makefile (+49/-0)
pkg/common/Makefile (+57/-0)
pkg/common/__init__.py (+194/-0)
pkg/common/checkarchive.py (+96/-0)
pkg/common/tox.ini (+11/-0)
pkg/maas-apiclient/Makefile (+9/-0)
pkg/maas-apiclient/README.rst (+5/-0)
pkg/maas-apiclient/apiclient/testing/settings.py (+18/-0)
pkg/maas-apiclient/configure.py (+19/-0)
pkg/maas-apiclient/packages.txt (+4/-0)
pkg/maas-apiclient/setup.py (+197/-0)
pkg/maas-client/Makefile (+3/-0)
pkg/maas-client/README.rst (+5/-0)
pkg/maas-client/configure.py (+26/-0)
pkg/maas-client/maascli/tests/test_integration.py (+16/-15)
pkg/maas-client/packages.txt (+7/-0)
pkg/maas-client/setup.py (+197/-0)
pkg/maas-cluster/MANIFEST.in (+4/-0)
pkg/maas-cluster/Makefile (+12/-0)
pkg/maas-cluster/README.rst (+6/-0)
pkg/maas-cluster/configure.py (+51/-0)
pkg/maas-cluster/maascluster/entrypoints.py (+61/-0)
pkg/maas-cluster/maascluster/worker/config.py (+2/-2)
pkg/maas-cluster/packages.txt (+36/-0)
pkg/maas-cluster/provisioningserver/dhcp/tests/test_writer.py (+8/-10)
pkg/maas-cluster/provisioningserver/testing/bindfixture.py (+5/-1)
pkg/maas-cluster/provisioningserver/testing/celeryconfig.py (+49/-0)
pkg/maas-cluster/provisioningserver/testing/djangosettings.py (+18/-0)
pkg/maas-cluster/provisioningserver/tests/test_config.py (+6/-1)
pkg/maas-cluster/provisioningserver/utils/tests/test_utils.py (+7/-5)
pkg/maas-cluster/setup.py (+197/-0)
pkg/maas-develop/MANIFEST.in (+2/-0)
pkg/maas-develop/Makefile (+6/-0)
pkg/maas-develop/README.rst (+5/-0)
pkg/maas-develop/configure.py (+47/-0)
pkg/maas-develop/maasdevelop/cluster/celeryconfig_demo.py (+7/-10)
pkg/maas-develop/maasdevelop/cluster/entrypoints.py (+61/-0)
pkg/maas-develop/maasdevelop/common/celeryconfig_demo.py (+8/-13)
pkg/maas-develop/maasdevelop/region/celeryconfig_demo.py (+6/-9)
pkg/maas-develop/maasdevelop/region/demo.py (+8/-6)
pkg/maas-develop/maasdevelop/region/development.py (+17/-23)
pkg/maas-develop/maasdevelop/region/entrypoints.py (+64/-0)
pkg/maas-develop/maasdevelop/region/maas_cluster.demo.conf (+8/-0)
pkg/maas-develop/maasdevelop/testing/entrypoints.py (+82/-0)
pkg/maas-develop/packages.txt (+17/-0)
pkg/maas-develop/setup.py (+197/-0)
pkg/maas-region/MANIFEST.in (+6/-0)
pkg/maas-region/Makefile (+38/-0)
pkg/maas-region/README.rst (+5/-0)
pkg/maas-region/configure.py (+70/-0)
pkg/maas-region/maas/entrypoints.py (+57/-0)
pkg/maas-region/maas/testing/celeryconfig.py (+45/-0)
pkg/maas-region/maas/testing/djangosettings.py (+112/-0)
pkg/maas-region/maasserver/components.py (+4/-1)
pkg/maas-region/maasserver/testing/testcase.py (+30/-28)
pkg/maas-region/maasserver/tests/test_js.py (+7/-9)
pkg/maas-region/maasserver/views/tests/test_nodes.py (+4/-0)
pkg/maas-region/maasserver/worker/config.py (+2/-2)
pkg/maas-region/metadataserver/commissioning/etctest/__init__.py (+15/-0)
pkg/maas-region/metadataserver/commissioning/etctest/test_maas_ipmi_autodetect.py (+3/-2)
pkg/maas-region/packages.txt (+48/-0)
pkg/maas-region/setup.py (+197/-0)
pkg/maas-testing/Makefile (+1/-0)
pkg/maas-testing/README.rst (+5/-0)
pkg/maas-testing/configure.py (+27/-0)
pkg/maas-testing/maastesting/__init__.py (+22/-9)
pkg/maas-testing/maastesting/djangoloader.py (+12/-46)
pkg/maas-testing/maastesting/fixtures.py (+37/-0)
pkg/maas-testing/maastesting/loader.py (+4/-0)
pkg/maas-testing/maastesting/testcase.py (+22/-0)
pkg/maas-testing/maastesting/tests/test_httpd.py (+6/-3)
pkg/maas-testing/packages.txt (+21/-0)
pkg/maas-testing/setup.py (+197/-0)
required-packages/base (+0/-56)
required-packages/build (+0/-3)
required-packages/dev (+0/-12)
required-packages/doc (+0/-3)
required-packages/forbidden (+0/-1)
required-packages/optional (+0/-1)
services/cluster-worker/run (+2/-5)
services/dns/run (+5/-3)
services/pserv/run (+4/-4)
services/region-worker/run (+2/-5)
services/txlongpoll/run (+2/-2)
services/web/run (+6/-2)
services/webapp/run (+4/-1)
setup.py (+0/-168)
versions.cfg (+0/-144)
To merge this branch: bzr merge lp:~allenap/maas/repackage
Reviewer Review Type Date Requested Status
MAAS Maintainers Pending
Review via email: mp+200935@code.launchpad.net

Description of the change

This changes a lot of stuff. It creates actually separate Python distribution packages for each subcomponent of MAAS, then unifies them into a single development environment. There's simply way more in this branch than I can hope to efficiently convey here, so I think this would be best reviewed as a pair. However, here it is anyway.

To post a comment you must log in.
lp:~allenap/maas/repackage updated
1924. By Gavin Panella

Merged repackage-prep into repackage, resolving a few conflicts.

1925. By Gavin Panella

Merged repackage-prep into repackage.

1926. By Gavin Panella

Merged trunk into repackage.

1927. By Gavin Panella

Remove required-packages; it's not used any more.

1928. By Gavin Panella

Merged trunk into repackage.

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

The Makefile still has a bunch of “Move to maas-develop?” comments. Maybe just add TODO markers for the time being?

lp:~allenap/maas/repackage updated
1929. By Gavin Panella

Change some comments to TODOs.

1930. By Gavin Panella

Correct test_loader setting.

1931. By Gavin Panella

Merged trunk into repackage.

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

> The Makefile still has a bunch of “Move to maas-develop?” comments. Maybe
> just add TODO markers for the time being?

Good idea, done.

lp:~allenap/maas/repackage updated
1932. By Gavin Panella

Merged trunk into repackage.

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Reading a bit further. Getting a bit lost with all the repetition! Is there really no way to share common definitions of __version__, envvar, check_settings, and so on? It's a lot of stuff to have both duplicated and untested, even if it is "meta" code.

.

I can see how it could be useful in the future for envvar to yield the environment variable's original value. But it's also a potential source of misunderstanding: "with environment variable set to X, its value is Y." I would just leave that feature out until we actually need it.

.

Much of the duplicated code needs documentation, and I can't help feeling that the duplication is the reason for not documenting it — which would be a poor state of affairs. I'm thinking of check_settings in particular: which settings does this check, for whose benefit, to serve what need?

.

Why doesn't install_deps follow our naming conventions?

.

I think the linter needs an update to check the pkg directory. The setup() calls are on insanely long lines.

.

Does pkg/common/checkarchive.py really compare contents of a tarball to a directory? Or only the file and directory names?

.

In pkg/maas-cluster/provisioningserver/testing/__init__.py you define "here" and "root" as global variables. Better upper-case them, as we have mostly been doing. Moreover "root" needs a more descriptive name and a bit of documentation. Root of what? And in a branch, in a package installation, or both?

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Plowing right on! Looking forward to getting this in.

In pkg/maas-region/maasserver/components.py, line 42 or so, you have a docstring, then a function call, and *then* an import that's there to avoid an import cycle. Would be more regular and obvious to have the import right below the docstring:

3328 :param error_message: Human-readable error text.
3329 """
3330 discard_persistent_error(component)
3331 + from maasserver.models import ComponentError # Avoid circular imports.
3332 ComponentError.objects.create(component=component, error=error_message)

.

The comment in MAASServerTestCase.setUp really doesn't need to have a TODO marker as far as I'm concerned. It's a great comment, but it does not instill a great sense of urgency. :-)

.

In pkg/maas-region/maasserver/tests/test_views_nodes.py, why does test_node_list_sorts_by_zone newly skip with an XXX message from gmb? It looks as if you were just porting over a previous skip() to a better format, but I don't see anything that would have made that test skip before.

.

The documentation for ClassSetup relies on knowledge of MAASTestCaseType in a different module. Can you explain it in such a way that people who aren't aware of MAASTestCaseType's relevance have a chance of understanding it? Can you also explain in docstrings *why* MAASTestCaseType forbids setUpClass if we then need ClassSetup to un-forbid it again?

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Here's one thing I really don't like: I ran a plain "make" just now and found it went and sudo'ed on me. I don't expect a build to mess with my global system configuration!

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Ran the test suite. Five maasserver tests failing, plus one error (but I'm not sure that counts — it's the old "Can't load the profile" error in test_YUI3_unit_tests).

lp:~allenap/maas/repackage updated
1933. By Gavin Panella

Merged trunk into repackage.

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

> Reading a bit further. Getting a bit lost with all the repetition! Is there
> really no way to share common definitions of __version__, envvar,
> check_settings, and so on? It's a lot of stuff to have both duplicated and
> untested, even if it is "meta" code.

Bugger, I didn't mention that in the description. That's one of the
reasons I wanted to do an interactive review. The setup.py files are all
auto-generated from the call to common.configure().

I tried using pprint to make the call to setup() format better, but that
has its own problems. Ideally I'd like to get rid of that hack, but I
did try several other ways to do it. I was trying to make it so that
each package would be installable from PyPI, for example, where the
common package would no longer be available, hence the need for bundling
things into setup.py.

>
> .
>
> I can see how it could be useful in the future for envvar to yield the
> environment variable's original value. But it's also a potential source of
> misunderstanding: "with environment variable set to X, its value is Y." I
> would just leave that feature out until we actually need it.

Done.

>
> .
>
> Much of the duplicated code needs documentation, and I can't help feeling that
> the duplication is the reason for not documenting it — which would be a poor
> state of affairs. I'm thinking of check_settings in particular: which
> settings does this check, for whose benefit, to serve what need?

I've added docstrings to pkg/common/__init__.py, which now means that
all the setup.pys are also documented.

>
> .
>
> Why doesn't install_deps follow our naming conventions?

It follows the distutils/setuptools naming convention for commands. I
don't know why it's that way :-/

>
> .
>
> I think the linter needs an update to check the pkg directory. The setup()
> calls are on insanely long lines.

pkg/common/__init__.py is lint-free, and there's not much I can do about
those setup() calls right now.

>
> .
>
> Does pkg/common/checkarchive.py really compare contents of a tarball to a
> directory? Or only the file and directory names?

Just names. It was useful when figuring out why data_files and
include_package_data were not doing as I expected (see check_settings).
I've updated its docstring.

>
> .
>
> In pkg/maas-cluster/provisioningserver/testing/__init__.py you define "here"
> and "root" as global variables. Better upper-case them, as we have mostly
> been doing. Moreover "root" needs a more descriptive name and a bit of
> documentation. Root of what? And in a branch, in a package installation, or
> both?

I totally want to get rid of those! I'll see if I can.

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

> Plowing right on!  Looking forward to getting this in.

Cheers, thank you for persisting :)

>
> In pkg/maas-region/maasserver/components.py, line 42 or so, you have a
> docstring, then a function call, and *then* an import that's there to avoid an
> import cycle.  Would be more regular and obvious to have the import right
> below the docstring:
>
> 3328         :param error_message: Human-readable error text.
> 3329         """
> 3330         discard_persistent_error(component)
> 3331    +    from maasserver.models import ComponentError  # Avoid circular
> imports.
> 3332         ComponentError.objects.create(component=component,
> error=error_message)

I've changed it.

>
> .
>
> The comment in MAASServerTestCase.setUp really doesn't need to have a TODO
> marker as far as I'm concerned.  It's a great comment, but it does not instill
> a great sense of urgency.  :-)

Fixed :)

>
> .
>
> In pkg/maas-region/maasserver/tests/test_views_nodes.py, why does
> test_node_list_sorts_by_zone newly skip with an XXX message from gmb?  It
> looks as if you were just porting over a previous skip() to a better format,
> but I don't see anything that would have made that test skip before.

Ah, I think you're right. I think I changed it from using `raise
SkipTest(...)` to using `self.skip(...)` thus avoiding the import of
SkipTest. Then Raffolo fixed it, I merged trunk, but no conflict (or
easily overlooked conflict) arose.

>
> .
>
> The documentation for ClassSetup relies on knowledge of MAASTestCaseType in a
> different module.  Can you explain it in such a way that people who aren't
> aware of MAASTestCaseType's relevance have a chance of understanding it?  Can
> you also explain in docstrings *why* MAASTestCaseType forbids setUpClass if we
> then need ClassSetup to un-forbid it again?

Docstring updated with:

    `MAASTestCaseType` forbids `setUpClass` and `tearDownClass` in new
    test classes, but sometimes they must be called in existing super
    classes, one example being :class:`django.test.LiveServerTestCase`.

lp:~allenap/maas/repackage updated
1934. By Gavin Panella

Docstrings for all functions in module common.

1935. By Gavin Panella

Don't yield the previous environment variable's value in envvar().

1936. By Gavin Panella

Make it clear that checkarchive.py only checks *names* in archives.

1937. By Gavin Panella

Remove obsolete XXX.

1938. By Gavin Panella

Couple of review fixes.

1939. By Gavin Panella

Explain the need for ClassSetup.

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

> Here's one thing I really don't like: I ran a plain "make" just now and found
> it went and sudo'ed on me.  I don't expect a build to mess with my global
> system configuration!

Something it could do, without needing root privileges, is to check if
all the dependencies are installed. If not, it can bail with a message
like:

    The following system dependencies are missing:
        ...
    To install them, run the following command:
        sudo apt-get install ...

Would that be better?

Fwiw, I like the automatic installation, but I can see that it's not
going to be to everyone's tastes.

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

> Ran the test suite. Five maasserver tests failing, plus one error (but I'm
> not sure that counts — it's the old "Can't load the profile" error in
> test_YUI3_unit_tests).

Those tests drive me nuts. I'm not sure wtf is going on with those;
they're failing in trunk for me too.

lp:~allenap/maas/repackage updated
1940. By Gavin Panella

Import the name required only; I think South is doing something 'clever' with the models package and subpackages.

1941. By Gavin Panella

Update some configs such that make harness works again.

1942. By Gavin Panella

Ignore .db.lock files.

1943. By Gavin Panella

Don't get the default zone at module import time.

1944. By Gavin Panella

Replace most uses of 'root' variables with pkg_resources.

1945. By Gavin Panella

Merge trunk, resolving lots of conflicts.

1946. By Gavin Panella

Merge trunk, resolving some conflicts, and migrating version requirements to the new layout.

1947. By Gavin Panella

ContainsAll is in testtools 0.9.32, and that's what's packaged in Ubuntu, so only require that.

1948. By Gavin Panella

Merge trunk.

1949. By Gavin Panella

Merge trunk.

1950. By Gavin Panella

Use load_entry_point() for celeryd so that it works on saucy and trusty.

1951. By Gavin Panella

Trusty's development Apache config is the same as saucy's.

1952. By Gavin Panella

bin/pip is no longer guaranteed to be made.

1953. By Gavin Panella

Merge trunk r1838. Discarded all changes, but reworked them into the New Way.

1954. By Gavin Panella

Merge trunk.

1955. By Gavin Panella

Merge trunk.

1956. By Gavin Panella

Merge trunk.

1957. By Gavin Panella

Merge trunk.

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

Running `make` was failing with "Error: pg_config executable not found." until I ran "sudo apt-get install libpq-dev python-dev".

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

`make test` fails with 'KeyError: "The cache has no package named u'python-selenium'"'
(http://paste.ubuntu.com/6825198/)

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

> Running `make` was failing with "Error: pg_config executable not found." until
> I ran "sudo apt-get install libpq-dev python-dev".

One of the things missing in this branch is the division between
production and development package dependencies: the Python packages
themselves (see pkg/*/package.txt and pkg/*/configure.py) arrange for
installation of package dependencies, but I've not added code to
distinguish between run-time and test-time.

I'll see what I can do.

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

> `make test` fails with 'KeyError: "The cache has no package named u'python-
> selenium'"'
> (http://paste.ubuntu.com/6825198/)

Ah, that'll be because python-selenium is in multiverse :-/

lp:~allenap/maas/repackage updated
1958. By Gavin Panella

Merge trunk, resolving a few small conflicts.

1959. By Gavin Panella

Merged trunk into repackage.

1960. By Gavin Panella

Merge trunk, resolving 1 minor conflict.

1961. By Gavin Panella

Merge trunk.

1962. By Gavin Panella

Merge trunk.

Revision history for this message
Graham Binns (gmb) wrote :

It would be lovely if we could prevent this from bitrotting... what still needs to happen?

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

> It would be lovely if we could prevent this from bitrotting... what still
> needs to happen?

It needs to land :)

I need to find time to split out some bits that can be merged separately, but I'm not sure what exactly that might be.

Also, when this lands it's going to break packaging and probably QA. It might be worth setting up a parallel PPA with new packages, and perhaps also a parallel QA process. However, it might be less work to land this, accept the breakage, then everyone fixes stuff.

lp:~allenap/maas/repackage updated
1963. By Gavin Panella

Merge trunk, resolving several small conflicts.

Revision history for this message
Andres Rodriguez (andreserl) wrote :

Gavin,

As previously discussed please check with doko and/or Barry about the
multiple setup.py's before you move forward with this.

And keep in mind that feature freeze is around the corner. I won't be
releasing these changes until after doko (on the packaging side) and Barry
(on the python side) sign this of. If this doesn't happen before feature
freeze i'll be hesitant on releasing this change at all.

Cheers
On Feb 10, 2014 8:58 AM, "Gavin Panella" <email address hidden>
wrote:

> > It would be lovely if we could prevent this from bitrotting... what still
> > needs to happen?
>
> It needs to land :)
>
> I need to find time to split out some bits that can be merged separately,
> but I'm not sure what exactly that might be.
>
> Also, when this lands it's going to break packaging and probably QA. It
> might be worth setting up a parallel PPA with new packages, and perhaps
> also a parallel QA process. However, it might be less work to land this,
> accept the breakage, then everyone fixes stuff.
>
> --
> https://code.launchpad.net/~allenap/maas/repackage/+merge/200935
> You are subscribed to branch lp:maas.
>

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

Okay, I've emailed doko and Barry (and maas-devel) to get their advice.

lp:~allenap/maas/repackage updated
1964. By Gavin Panella

Forgot to regenerate a setup.py.

Revision history for this message
Julian Edwards (julian-edwards) wrote :

I'm almost convinced that this should wait until after 14.04.

Revision history for this message
Andres Rodriguez (andreserl) wrote :

I agree with Julian!
On Feb 10, 2014 8:06 PM, "Julian Edwards" <email address hidden>
wrote:

> I'm almost convinced that this should wait until after 14.04.
>
> --
> https://code.launchpad.net/~allenap/maas/repackage/+merge/200935
> You are subscribed to branch lp:maas.
>

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

> I'm almost convinced that this should wait until after 14.04.

Sadly, I'm of that opinion too. There was a window shortly after it was done that it could have merged, but that's gone now. I understand the reluctance to swallow such a big change, but it's not an easy change to break up into pieces. Assuming this is an acceptable change, I think the best way to approach it is to JFDI and then fix whatever it breaks. We can do that early in the next cycle. The downside is that it'll make it harder to back-port changes to Trusty.

Revision history for this message
Julian Edwards (julian-edwards) wrote :

On Tuesday 11 Feb 2014 09:28:00 Gavin Panella wrote:
> > I'm almost convinced that this should wait until after 14.04.
>
> Sadly, I'm of that opinion too. There was a window shortly after it was done
> that it could have merged, but that's gone now. I understand the reluctance
> to swallow such a big change, but it's not an easy change to break up into
> pieces. Assuming this is an acceptable change, I think the best way to
> approach it is to JFDI and then fix whatever it breaks. We can do that
> early in the next cycle. The downside is that it'll make it harder to
> back-port changes to Trusty.

So a couple of things:

1. I think we should not backport anything to trusty, instead reply on the
cloud archive for up-to-date packages based on trunk. We have more leeway in
there to make this sort of change.

2. +1 to a huge land-and-fixorama post 14.04.

lp:~allenap/maas/repackage updated
1965. By Gavin Panella

Merge trunk, resolving many conflicts.

1966. By Gavin Panella

Add python-crochet as a dependency.

1967. By Gavin Panella

Some more maascli/maas-cli fixes.

1968. By Gavin Panella

Merge trunk.

1969. By Gavin Panella

Merge trunk r1944.

1970. By Gavin Panella

Merge trunk r1945.

1971. By Gavin Panella

Merge trunk r1946.

1972. By Gavin Panella

Merge trunk r1947.

1973. By Gavin Panella

Merge trunk r1948.

1974. By Gavin Panella

Merge trunk r1949.

1975. By Gavin Panella

Merge trunk r1950.

1976. By Gavin Panella

Merge trunk r1951.

1977. By Gavin Panella

Merge trunk r1952.

1978. By Gavin Panella

Merge trunk r1953, resolving minor conflicts.

1979. By Gavin Panella

Merge trunk r1954.

1980. By Gavin Panella

Merge trunk r1955, resolving minor conflicts.

1981. By Gavin Panella

Merge trunk r1956.

1982. By Gavin Panella

Merge trunk r1957.

1983. By Gavin Panella

Merge trunk r1958.

1984. By Gavin Panella

Merge trunk r1959.

1985. By Gavin Panella

Merge trunk r1960.

1986. By Gavin Panella

Merge trunk r1961.

1987. By Gavin Panella

Merge trunk r1962.

1988. By Gavin Panella

Merge trunk r1963.

1989. By Gavin Panella

Merge trunk r1964.

1990. By Gavin Panella

Merge trunk r1965.

1991. By Gavin Panella

Merge trunk r1966.

1992. By Gavin Panella

Merge trunk r1967.

1993. By Gavin Panella

Merge trunk r1968.

1994. By Gavin Panella

Merge trunk r1969.

1995. By Gavin Panella

Merge trunk r1970, resolving minor conflicts.

1996. By Gavin Panella

Merge trunk r1971.

1997. By Gavin Panella

Merge trunk r1972.

1998. By Gavin Panella

Merge trunk r1973.

1999. By Gavin Panella

Merge trunk r1974.

2000. By Gavin Panella

Merge trunk r1975.

2001. By Gavin Panella

Merge trunk r1976.

2002. By Gavin Panella

Merge trunk r1977, resolving minor conflicts.

2003. By Gavin Panella

Merge trunk r1978.

2004. By Gavin Panella

Merge trunk r1979.

2005. By Gavin Panella

Merge trunk r1980.

2006. By Gavin Panella

Merge trunk r1981.

2007. By Gavin Panella

Merge trunk r1982.

2008. By Gavin Panella

Merge trunk r1983.

2009. By Gavin Panella

Merge trunk r1984.

2010. By Gavin Panella

Merge trunk r1985.

2011. By Gavin Panella

Merge trunk r1986.

2012. By Gavin Panella

Merge trunk r1987.

2013. By Gavin Panella

Merge trunk r1988.

2014. By Gavin Panella

Merge trunk r1989.

2015. By Gavin Panella

Merge trunk r1990.

2016. By Gavin Panella

Merge trunk r1991.

2017. By Gavin Panella

Merge trunk r1992.

2018. By Gavin Panella

Merge trunk r1993.

2019. By Gavin Panella

Merge trunk r1994.

2020. By Gavin Panella

Merge trunk r1995.

2021. By Gavin Panella

Merge trunk r1996.

2022. By Gavin Panella

Merge trunk r1997.

2023. By Gavin Panella

Merge trunk r1998.

2024. By Gavin Panella

Merge trunk r1999.

2025. By Gavin Panella

Merge trunk r2000.

2026. By Gavin Panella

Merge trunk r2001, resolving minor conflicts.

2027. By Gavin Panella

Merge trunk r2002.

2028. By Gavin Panella

Merge trunk r2003.

2029. By Gavin Panella

Merge trunk r2004.

2030. By Gavin Panella

Merge trunk r2005.

2031. By Gavin Panella

Merge trunk r2006.

2032. By Gavin Panella

Merge trunk r2007.

2033. By Gavin Panella

Merge trunk r2008.

2034. By Gavin Panella

Merge trunk r2009.

2035. By Gavin Panella

Merge trunk r2010.

2036. By Gavin Panella

Merge trunk r2011, resolving minor conflicts.

2037. By Gavin Panella

Merge trunk r2012.

2038. By Gavin Panella

Merge trunk r2013.

2039. By Gavin Panella

Merge trunk r2014, resolving minor conflicts.

2040. By Gavin Panella

Merge trunk r2015.

2041. By Gavin Panella

Merge trunk r2016.

2042. By Gavin Panella

Merge trunk r2017.

2043. By Gavin Panella

Merge trunk r2018.

2044. By Gavin Panella

Merge trunk r2019.

2045. By Gavin Panella

Merge trunk r2020.

2046. By Gavin Panella

Merge trunk r2021, resolving minor conflicts.

2047. By Gavin Panella

Merge trunk r2022.

2048. By Gavin Panella

Merge trunk r2023.

2049. By Gavin Panella

Merge trunk r2024.

2050. By Gavin Panella

Merge trunk r2025.

2051. By Gavin Panella

Merge trunk r2026.

2052. By Gavin Panella

Merge trunk r2027.

2053. By Gavin Panella

Merge trunk r2028.

2054. By Gavin Panella

Merge trunk r2029.

2055. By Gavin Panella

Merge trunk r2030.

2056. By Gavin Panella

Merge trunk r2031.

2057. By Gavin Panella

Merge trunk r2032.

2058. By Gavin Panella

Merge trunk r2033.

2059. By Gavin Panella

Merge trunk r2034.

2060. By Gavin Panella

Merge trunk r2035.

2061. By Gavin Panella

Merge trunk r2036.

2062. By Gavin Panella

Merge trunk r2037.

2063. By Gavin Panella

Merge trunk r2038.

2064. By Gavin Panella

Merge trunk r2039.

2065. By Gavin Panella

Merge trunk r2040.

2066. By Gavin Panella

Merge trunk r2041.

2067. By Gavin Panella

Merge trunk r2042.

2068. By Gavin Panella

Merge trunk r2043.

2069. By Gavin Panella

Merge trunk r2044.

2070. By Gavin Panella

Merge trunk r2045.

2071. By Gavin Panella

Merge trunk r2046, resolving minor conflicts.

2072. By Gavin Panella

Merge trunk r2047.

2073. By Gavin Panella

Merge trunk r2048.

2074. By Gavin Panella

Merge trunk r2049.

2075. By Gavin Panella

Merge trunk r2050.

2076. By Gavin Panella

Merge trunk r2051.

2077. By Gavin Panella

Merge trunk r2052.

2078. By Gavin Panella

Merge trunk r2053.

2079. By Gavin Panella

Merge trunk r2054.

2080. By Gavin Panella

Merge trunk r2055.

2081. By Gavin Panella

Merge trunk r2056.

2082. By Gavin Panella

Merge trunk r2057.

2083. By Gavin Panella

Merge trunk r2058.

2084. By Gavin Panella

Merge trunk r2059.

2085. By Gavin Panella

Merge trunk r2060.

2086. By Gavin Panella

Merge trunk r2061.

2087. By Gavin Panella

Merge trunk r2062, resolving minor conflicts.

2088. By Gavin Panella

Merge trunk r2063.

2089. By Gavin Panella

Merge trunk r2064.

2090. By Gavin Panella

Merge trunk r2065.

2091. By Gavin Panella

Merge trunk r2066.

2092. By Gavin Panella

Merge trunk r2067.

2093. By Gavin Panella

Merge trunk r2068.

2094. By Gavin Panella

Merge trunk r2069.

2095. By Gavin Panella

Merge trunk r2070.

2096. By Gavin Panella

Merge trunk r2071.

2097. By Gavin Panella

Merge trunk r2072.

2098. By Gavin Panella

Merge trunk r2073.

2099. By Gavin Panella

Merge trunk r2074.

2100. By Gavin Panella

Merge trunk r2075.

2101. By Gavin Panella

Merge trunk r2076.

2102. By Gavin Panella

Merge trunk r2077.

2103. By Gavin Panella

Merge trunk r2078.

2104. By Gavin Panella

Merge trunk r2079.

2105. By Gavin Panella

Merge trunk r2080.

2106. By Gavin Panella

Merge trunk r2081.

2107. By Gavin Panella

Merge trunk r2082.

2108. By Gavin Panella

Merge trunk r2083, resolving minor conflicts.

2109. By Gavin Panella

Merge trunk r2084.

2110. By Gavin Panella

Merge trunk r2085.

2111. By Gavin Panella

Merge trunk r2086.

2112. By Gavin Panella

Merge trunk r2087.

2113. By Gavin Panella

Merge trunk r2088.

2114. By Gavin Panella

Merge trunk r2089.

2115. By Gavin Panella

Merge trunk r2090.

2116. By Gavin Panella

Merge trunk r2091.

2117. By Gavin Panella

Merge trunk r2092.

2118. By Gavin Panella

Merge trunk r2093.

2119. By Gavin Panella

Merge trunk r2094.

2120. By Gavin Panella

Merge trunk r2095.

2121. By Gavin Panella

Merge trunk r2096.

2122. By Gavin Panella

Merge trunk r2097.

2123. By Gavin Panella

Merge trunk r2098.

2124. By Gavin Panella

Merge trunk r2099.

2125. By Gavin Panella

Merge trunk r2100.

2126. By Gavin Panella

Merge trunk r2101.

2127. By Gavin Panella

Merge trunk r2102.

2128. By Gavin Panella

Merge trunk r2103.

2129. By Gavin Panella

Merge trunk r2104.

2130. By Gavin Panella

Merge trunk r2105.

2131. By Gavin Panella

Merge trunk r2106.

2132. By Gavin Panella

Merge trunk r2107.

2133. By Gavin Panella

Merge trunk r2108.

2134. By Gavin Panella

Merge trunk r2109.

2135. By Gavin Panella

Merge trunk r2110.

2136. By Gavin Panella

Merge trunk r2111.

2137. By Gavin Panella

Merge trunk r2112.

2138. By Gavin Panella

Merge trunk r2113.

2139. By Gavin Panella

Merge trunk r2114.

2140. By Gavin Panella

Merge trunk r2115.

2141. By Gavin Panella

Merge trunk r2116.

2142. By Gavin Panella

Merge trunk r2117.

2143. By Gavin Panella

Merge trunk r2118.

2144. By Gavin Panella

Merge trunk r2119.

2145. By Gavin Panella

Merge trunk r2120.

2146. By Gavin Panella

Merge trunk r2121.

2147. By Gavin Panella

Merge trunk r2122.

2148. By Gavin Panella

Merge trunk r2123.

2149. By Gavin Panella

Merge trunk r2124.

2150. By Gavin Panella

Merge trunk r2125.

2151. By Gavin Panella

Merge trunk r2126.

2152. By Gavin Panella

Merge trunk r2127.

2153. By Gavin Panella

Merge trunk r2128.

2154. By Gavin Panella

Merge trunk r2129.

2155. By Gavin Panella

Merge trunk r2130.

2156. By Gavin Panella

Merge trunk r2131.

2157. By Gavin Panella

Merge trunk r2132.

2158. By Gavin Panella

Merge trunk r2133.

2159. By Gavin Panella

Merge trunk r2134.

2160. By Gavin Panella

Merge trunk r2135.

2161. By Gavin Panella

Merge trunk r2136.

2162. By Gavin Panella

Merge trunk r2137.

2163. By Gavin Panella

Merge trunk r2138.

2164. By Gavin Panella

Merge trunk r2139.

2165. By Gavin Panella

Merge trunk r2140, resolving minor conflicts.

2166. By Gavin Panella

Missing dependency, subunit.

2167. By Gavin Panella

Merge r2141, changing things quite a lot.

2168. By Gavin Panella

Merge trunk r2142.

2169. By Gavin Panella

Merge trunk r2143.

2170. By Gavin Panella

Merge trunk r2144.

2171. By Gavin Panella

Merge trunk r2145.

2172. By Gavin Panella

Merge r2146, resolving conflicts.

2173. By Gavin Panella

Merge trunk r2147.

2174. By Gavin Panella

Merge trunk r2148.

2175. By Gavin Panella

Merge trunk r2149.

2176. By Gavin Panella

Merge r2150, resolving minor conflicts.

2177. By Gavin Panella

Merge r2151, resolving minor conflicts.

2178. By Gavin Panella

Merge trunk r2152.

2179. By Gavin Panella

Merge trunk r2153, resolving several conflicts.

2180. By Gavin Panella

Merge trunk r2154, discarding all changes.

2181. By Gavin Panella

Work with - and + suffixes in packages.txt.

2182. By Gavin Panella

Purge python-librabbitmq; it breaks stuff.

2183. By Gavin Panella

Update setup.pys.

2184. By Gavin Panella

Merge r2155, discarding all changes.

2185. By Gavin Panella

Merge trunk r2156.

2186. By Gavin Panella

Merge trunk r2157, resolving minor conflicts.

2187. By Gavin Panella

Merge trunk r2158, discarding most changes.

2188. By Gavin Panella

Merge trunk r2159.

2189. By Gavin Panella

Merge trunk r2160.

2190. By Gavin Panella

Merge trunk r2161.

2191. By Gavin Panella

Merge trunk r2162.

2192. By Gavin Panella

Merge trunk r2163.

2193. By Gavin Panella

Merge trunk r2164.

2194. By Gavin Panella

Merge trunk r2165.

2195. By Gavin Panella

Merge trunk r2166.

2196. By Gavin Panella

Merge trunk r2167.

2197. By Gavin Panella

Merge trunk r2168.

2198. By Gavin Panella

Merge trunk r2169.

2199. By Gavin Panella

Merge trunk r2170, resolving conflicts.

2200. By Gavin Panella

Merge trunk r2171.

2201. By Gavin Panella

Merge trunk r2172, resolving minor conflicts.

2202. By Gavin Panella

Merge trunk r2173.

2203. By Gavin Panella

Merge trunk r2174.

2204. By Gavin Panella

Merge trunk r2175.

2205. By Gavin Panella

Merge trunk r2176.

2206. By Gavin Panella

Merge trunk r2177.

2207. By Gavin Panella

Merge trunk r2178.

2208. By Gavin Panella

Merge trunk r2179.

2209. By Gavin Panella

Merge trunk r2180, resolving minor conflicts.

2210. By Gavin Panella

Merge trunk r2181, resolving minor conflicts.

2211. By Gavin Panella

Merge trunk r2182.

2212. By Gavin Panella

Merge trunk r2183.

2213. By Gavin Panella

Merge trunk r2184.

2214. By Gavin Panella

Merge trunk r2185, resolving minor conflicts.

2215. By Gavin Panella

Merge trunk r2186.

2216. By Gavin Panella

Merge trunk r2187.

2217. By Gavin Panella

Merge trunk r2188.

2218. By Gavin Panella

Merge trunk r2189.

2219. By Gavin Panella

Merge trunk r2190.

2220. By Gavin Panella

Merge trunk r2191.

2221. By Gavin Panella

Merge trunk r2192, resolving minor conflicts.

2222. By Gavin Panella

Merge trunk r2193.

2223. By Gavin Panella

Merge trunk r2194.

2224. By Gavin Panella

Merge trunk r2195.

2225. By Gavin Panella

Merge trunk r2196.

2226. By Gavin Panella

Merge trunk r2197, resolving minor conflicts.

2227. By Gavin Panella

Merge trunk r2198.

2228. By Gavin Panella

Merge trunk r2199.

2229. By Gavin Panella

Merge trunk r2200.

2230. By Gavin Panella

Merge trunk r2201.

2231. By Gavin Panella

Merge trunk r2202.

2232. By Gavin Panella

Merge trunk r2203, discarding all changes.

2233. By Gavin Panella

Merge trunk r2204.

2234. By Gavin Panella

Merge trunk r2205.

2235. By Gavin Panella

Merge trunk r2206.

2236. By Gavin Panella

Merge trunk r2207.

2237. By Gavin Panella

Merge trunk r2208.

2238. By Gavin Panella

Merge trunk r2209.

2239. By Gavin Panella

Merge trunk r2210.

2240. By Gavin Panella

Merge trunk r2211.

2241. By Gavin Panella

Merge trunk r2212.

2242. By Gavin Panella

Merge trunk r2213, resolving minor conflicts.

2243. By Gavin Panella

Merge trunk r2214.

2244. By Gavin Panella

Merge trunk r2215.

2245. By Gavin Panella

Merge trunk r2216.

2246. By Gavin Panella

Merge trunk r2217.

2247. By Gavin Panella

Merge trunk r2218.

2248. By Gavin Panella

Merge trunk r2219.

2249. By Gavin Panella

Merge trunk r2220.

2250. By Gavin Panella

Merge trunk r2221.

2251. By Gavin Panella

Merge trunk r2222.

2252. By Gavin Panella

Merge trunk r2223.

2253. By Gavin Panella

Merge trunk r2224.

2254. By Gavin Panella

Merge trunk r2225.

2255. By Gavin Panella

Merge trunk r2226.

2256. By Gavin Panella

Merge trunk r2227.

2257. By Gavin Panella

Merge trunk r2228.

2258. By Gavin Panella

Merge trunk r2229.

2259. By Gavin Panella

Merge trunk r2230.

2260. By Gavin Panella

Merge trunk r2231.

2261. By Gavin Panella

Merge trunk r2232.

2262. By Gavin Panella

Merge trunk r2233.

2263. By Gavin Panella

Merge trunk r2234.

2264. By Gavin Panella

Merge trunk r2235.

2265. By Gavin Panella

Merge trunk r2236.

2266. By Gavin Panella

Merge trunk r2237.

2267. By Gavin Panella

Merge trunk r2238, resolving 1 minor conflict.

2268. By Gavin Panella

Merge trunk r2239.

2269. By Gavin Panella

Merge trunk r2240.

2270. By Gavin Panella

Merge trunk r2241.

2271. By Gavin Panella

Merge trunk r2242.

2272. By Gavin Panella

Merge trunk r2243.

2273. By Gavin Panella

Merge trunk r2244.

2274. By Gavin Panella

Merge trunk r2245.

2275. By Gavin Panella

Merge trunk r2246.

2276. By Gavin Panella

Merge trunk r2247.

2277. By Gavin Panella

Merge trunk r2248.

2278. By Gavin Panella

Merge trunk r2249.

2279. By Gavin Panella

Merge trunk r2250.

2280. By Gavin Panella

Merge trunk r2251.

2281. By Gavin Panella

Merge trunk r2252.

2282. By Gavin Panella

Merge trunk r2253, resolving conflicts.

2283. By Gavin Panella

Merge trunk r2254.

2284. By Gavin Panella

Merge trunk r2255.

2285. By Gavin Panella

Merge trunk r2256.

2286. By Gavin Panella

Merge trunk r2257.

2287. By Gavin Panella

Merge trunk r2258.

2288. By Gavin Panella

Merge trunk r2259.

2289. By Gavin Panella

Merge trunk r2260.

2290. By Gavin Panella

Merge trunk r2261.

2291. By Gavin Panella

Merge trunk r2262.

2292. By Gavin Panella

Merge trunk r2263.

2293. By Gavin Panella

Merge trunk r2264.

2294. By Gavin Panella

Merge trunk r2265.

2295. By Gavin Panella

Merge trunk r2266.

2296. By Gavin Panella

Merge trunk r2267.

2297. By Gavin Panella

Merge trunk r2268, resolving 1 minor conflict.

2298. By Gavin Panella

Merge trunk r2269.

2299. By Gavin Panella

Merge trunk r2270.

2300. By Gavin Panella

Merge trunk r2271.

2301. By Gavin Panella

Merge trunk r2272.

2302. By Gavin Panella

Merge trunk r2273.

2303. By Gavin Panella

Merge trunk r2274.

2304. By Gavin Panella

Merge trunk r2275.

2305. By Gavin Panella

Merge trunk r2276.

2306. By Gavin Panella

Merge trunk r2277.

2307. By Gavin Panella

Merge trunk r2278.

2308. By Gavin Panella

Merge trunk r2279.

2309. By Gavin Panella

Merge trunk r2280.

2310. By Gavin Panella

Merge trunk r2281.

2311. By Gavin Panella

Merge trunk r2282.

2312. By Gavin Panella

Merge trunk r2283.

2313. By Gavin Panella

Merge trunk r2284.

2314. By Gavin Panella

Merge trunk r2285.

2315. By Gavin Panella

Merge trunk r2286.

2316. By Gavin Panella

Merge trunk r2287, resolving 1 minor conflict.

2317. By Gavin Panella

Merge trunk r2288.

2318. By Gavin Panella

Merge trunk r2289.

2319. By Gavin Panella

Merge trunk r2290.

2320. By Gavin Panella

Merge trunk r2291.

2321. By Gavin Panella

Merge trunk r2292.

2322. By Gavin Panella

Merge trunk r2293.

2323. By Gavin Panella

Merge trunk r2294.

2324. By Gavin Panella

Merge trunk r2295.

2325. By Gavin Panella

Merge trunk r2296.

2326. By Gavin Panella

Merge trunk r2297.

2327. By Gavin Panella

Merge trunk r2298.

2328. By Gavin Panella

Merge trunk r2299.

2329. By Gavin Panella

Merge trunk r2300.

2330. By Gavin Panella

Merge trunk r2301.

2331. By Gavin Panella

Merge trunk r2302.

2332. By Gavin Panella

Merge trunk r2303.

2333. By Gavin Panella

Merge trunk r2304.

2334. By Gavin Panella

Merge trunk r2305.

2335. By Gavin Panella

Merge trunk r2306.

2336. By Gavin Panella

Merge trunk r2307.

2337. By Gavin Panella

Merge trunk r2308.

2338. By Gavin Panella

Merge trunk r2309.

2339. By Gavin Panella

Merge trunk r2310.

2340. By Gavin Panella

Merge trunk r2311.

2341. By Gavin Panella

Merge trunk r2312.

2342. By Gavin Panella

Merge trunk r2313.

2343. By Gavin Panella

Merge trunk r2314.

2344. By Gavin Panella

Merge trunk r2315.

2345. By Gavin Panella

Merge trunk r2316.

2346. By Gavin Panella

Merge trunk r2317.

2347. By Gavin Panella

Merge trunk r2318.

2348. By Gavin Panella

Merge trunk r2319.

2349. By Gavin Panella

Merge trunk r2320.

2350. By Gavin Panella

Merge trunk r2321.

2351. By Gavin Panella

Merge trunk r2322.

2352. By Gavin Panella

Merge trunk r2323.

2353. By Gavin Panella

Merge trunk r2324.

2354. By Gavin Panella

Merge trunk r2325.

2355. By Gavin Panella

Merge trunk r2326.

2356. By Gavin Panella

Merge trunk r2327.

2357. By Gavin Panella

Merge trunk r2328.

2358. By Gavin Panella

Merge trunk r2329.

2359. By Gavin Panella

Merge trunk r2330.

2360. By Gavin Panella

Merge trunk r2331.

2361. By Gavin Panella

Merge trunk r2332.

2362. By Gavin Panella

Merge trunk r2333.

2363. By Gavin Panella

Merge trunk r2334.

2364. By Gavin Panella

Merge trunk r2335.

2365. By Gavin Panella

Merge trunk r2336.

2366. By Gavin Panella

Merge trunk r2337.

2367. By Gavin Panella

Merge trunk r2338.

2368. By Gavin Panella

Merge trunk r2339.

2369. By Gavin Panella

Merge trunk r2340.

2370. By Gavin Panella

Merge trunk r2341.

2371. By Gavin Panella

Merge trunk r2342.

2372. By Gavin Panella

Merge trunk r2343.

2373. By Gavin Panella

Merge trunk r2344, resolving 1 minor conflict.

2374. By Gavin Panella

Merge trunk r2345.

2375. By Gavin Panella

Merge trunk r2346.

2376. By Gavin Panella

Merge trunk r2347.

2377. By Gavin Panella

Merge trunk r2348.

2378. By Gavin Panella

Merge trunk r2349.

2379. By Gavin Panella

Merge trunk r2350.

2380. By Gavin Panella

Merge trunk r2351.

2381. By Gavin Panella

Merge trunk r2352.

2382. By Gavin Panella

Merge trunk r2353, resolving minor conflicts.

2383. By Gavin Panella

Merge trunk r2354.

2384. By Gavin Panella

Merge trunk r2355.

2385. By Gavin Panella

Merge trunk r2356.

2386. By Gavin Panella

Merge trunk r2357.

2387. By Gavin Panella

Merge trunk r2358.

2388. By Gavin Panella

Merge trunk r2359.

2389. By Gavin Panella

Merge trunk r2360.

2390. By Gavin Panella

Merge trunk r2361.

2391. By Gavin Panella

Merge trunk r2362.

2392. By Gavin Panella

Merge trunk r2363.

2393. By Gavin Panella

Merge trunk r2364.

2394. By Gavin Panella

Merge trunk r2365.

2395. By Gavin Panella

Merge trunk r2366.

2396. By Gavin Panella

Merge trunk r2367.

2397. By Gavin Panella

Merge trunk r2368.

2398. By Gavin Panella

Merge trunk r2369.

2399. By Gavin Panella

Merge trunk r2370.

2400. By Gavin Panella

Merge trunk r2371.

2401. By Gavin Panella

Merge trunk r2372.

2402. By Gavin Panella

Merge trunk r2373.

2403. By Gavin Panella

Merge trunk r2374.

2404. By Gavin Panella

Merge trunk r2375.

2405. By Gavin Panella

Merge trunk r2376.

2406. By Gavin Panella

Merge trunk r2377, resolving minor conflicts.

2407. By Gavin Panella

Merge trunk r2378.

2408. By Gavin Panella

Merge trunk r2379.

2409. By Gavin Panella

Merge trunk r2380.

2410. By Gavin Panella

Merge trunk r2381.

2411. By Gavin Panella

Merge trunk r2382.

2412. By Gavin Panella

Merge trunk r2383.

2413. By Gavin Panella

Merge trunk r2384.

2414. By Gavin Panella

Merge trunk r2385.

2415. By Gavin Panella

Merge trunk r2386.

2416. By Gavin Panella

Merge trunk r2387.

2417. By Gavin Panella

Merge trunk r2388.

2418. By Gavin Panella

Merge trunk r2389.

2419. By Gavin Panella

Merge trunk r2390.

2420. By Gavin Panella

Merge trunk r2391.

2421. By Gavin Panella

Merge trunk r2392.

2422. By Gavin Panella

Merge trunk r2393.

2423. By Gavin Panella

Merge trunk r2394.

2424. By Gavin Panella

Merge trunk r2395.

2425. By Gavin Panella

Merge trunk r2396, resolving minor conflicts.

2426. By Gavin Panella

Merge trunk r2397.

2427. By Gavin Panella

Merge trunk r2398.

2428. By Gavin Panella

Merge trunk r2399.

2429. By Gavin Panella

Merge trunk r2400.

2430. By Gavin Panella

Merge trunk r2401.

2431. By Gavin Panella

Merge trunk r2402.

2432. By Gavin Panella

Merge trunk r2403.

2433. By Gavin Panella

Merge trunk r2404.

2434. By Gavin Panella

Merge trunk r2405.

2435. By Gavin Panella

Merge trunk r2406, resolving minor conflicts.

2436. By Gavin Panella

Merge trunk r2407.

2437. By Gavin Panella

Merge trunk r2408.

2438. By Gavin Panella

Merge trunk r2409.

2439. By Gavin Panella

Merge trunk r2410.

2440. By Gavin Panella

Merge trunk r2411.

2441. By Gavin Panella

Merge trunk r2412, resolving minor conflicts.

2442. By Gavin Panella

Merge trunk r2413.

2443. By Gavin Panella

Merge trunk r2414.

2444. By Gavin Panella

Merge trunk r2415.

2445. By Gavin Panella

Merge trunk r2416.

2446. By Gavin Panella

Merge trunk r2417.

2447. By Gavin Panella

Merge trunk r2418.

2448. By Gavin Panella

Merge trunk r2419.

2449. By Gavin Panella

Merge trunk r2420.

2450. By Gavin Panella

Merge trunk r2421.

2451. By Gavin Panella

Merge trunk r2422.

2452. By Gavin Panella

Merge trunk r2423.

2453. By Gavin Panella

Merge trunk r2424.

2454. By Gavin Panella

Merge trunk r2425.

2455. By Gavin Panella

Merge trunk r2426.

2456. By Gavin Panella

Merge trunk r2427.

2457. By Gavin Panella

Merge trunk r2428.

2458. By Gavin Panella

Merge trunk r2429.

2459. By Gavin Panella

Merge trunk r2430, resolving minor conflicts.

2460. By Gavin Panella

Merge trunk r2431.

2461. By Gavin Panella

Merge trunk r2432.

2462. By Gavin Panella

Merge trunk r2433.

2463. By Gavin Panella

Merge trunk r2434.

2464. By Gavin Panella

Merge trunk r2435.

2465. By Gavin Panella

Merge trunk r2436.

2466. By Gavin Panella

Merge trunk r2437.

2467. By Gavin Panella

Merge trunk r2438.

2468. By Gavin Panella

Merge trunk r2439.

2469. By Gavin Panella

Merge trunk r2440.

2470. By Gavin Panella

Merge trunk r2441.

2471. By Gavin Panella

Merge trunk r2442.

2472. By Gavin Panella

Merge trunk r2443.

2473. By Gavin Panella

Merge trunk r2444.

2474. By Gavin Panella

Merge trunk r2445.

2475. By Gavin Panella

Merge trunk r2446.

2476. By Gavin Panella

Merge trunk r2447.

2477. By Gavin Panella

Merge trunk r2448, resolving minor conflicts.

2478. By Gavin Panella

Merge trunk r2449, resolving minor conflicts.

2479. By Gavin Panella

Merge trunk r2450, resolving minor conflicts.

2480. By Gavin Panella

Merge trunk r2451.

2481. By Gavin Panella

Merge trunk r2452.

2482. By Gavin Panella

Merge trunk r2453.

2483. By Gavin Panella

Merge trunk r2454.

2484. By Gavin Panella

Merge trunk r2455.

2485. By Gavin Panella

Merge trunk r2456.

2486. By Gavin Panella

Merge trunk r2457.

2487. By Gavin Panella

Merge trunk r2458.

2488. By Gavin Panella

Merge trunk r2459.

2489. By Gavin Panella

Merge trunk r2460.

2490. By Gavin Panella

Merge trunk r2461.

2491. By Gavin Panella

Merge trunk r2462, resolving minor conflicts.

2492. By Gavin Panella

Merge trunk r2463.

2493. By Gavin Panella

Merge trunk r2464.

2494. By Gavin Panella

Merge trunk r2465, resolving minor conflicts.

2495. By Gavin Panella

Merge trunk r2466.

2496. By Gavin Panella

Merge trunk r2467.

2497. By Gavin Panella

Merge trunk r2468.

2498. By Gavin Panella

Merge trunk r2469.

2499. By Gavin Panella

Merge trunk r2470.

2500. By Gavin Panella

Merge trunk r2471.

2501. By Gavin Panella

Merge trunk r2472.

2502. By Gavin Panella

Merge trunk r2473, resolving minor conflicts.

2503. By Gavin Panella

Merge trunk r2474.

2504. By Gavin Panella

Merge trunk r2475.

2505. By Gavin Panella

Merge trunk r2476.

2506. By Gavin Panella

Merge trunk r2477.

2507. By Gavin Panella

Merge trunk r2478.

2508. By Gavin Panella

Merge trunk r2479.

2509. By Gavin Panella

Merge trunk r2480.

2510. By Gavin Panella

Merge trunk r2481.

2511. By Gavin Panella

Merge trunk r2482.

2512. By Gavin Panella

Merge trunk r2483.

2513. By Gavin Panella

Merge trunk r2484.

2514. By Gavin Panella

Merge trunk r2485.

2515. By Gavin Panella

Merge trunk r2486.

2516. By Gavin Panella

Merge trunk r2487.

2517. By Gavin Panella

Merge trunk r2488.

2518. By Gavin Panella

Merge trunk r2489.

2519. By Gavin Panella

Merge trunk r2490.

2520. By Gavin Panella

Merge trunk r2491.

2521. By Gavin Panella

Merge trunk r2492.

2522. By Gavin Panella

Merge trunk r2493.

2523. By Gavin Panella

Merge trunk r2494.

2524. By Gavin Panella

Merge trunk r2495.

2525. By Gavin Panella

Merge trunk r2496.

2526. By Gavin Panella

Merge trunk r2497.

2527. By Gavin Panella

Merge trunk r2498.

2528. By Gavin Panella

Merge trunk r2499.

2529. By Gavin Panella

Merge trunk r2500.

2530. By Gavin Panella

Merge trunk r2501.

2531. By Gavin Panella

Merge trunk r2502.

2532. By Gavin Panella

Merge trunk r2503.

2533. By Gavin Panella

Merge trunk r2504.

2534. By Gavin Panella

Merge trunk r2505.

2535. By Gavin Panella

Merge trunk r2506.

2536. By Gavin Panella

Merge trunk r2507.

2537. By Gavin Panella

Merge trunk r2508.

2538. By Gavin Panella

Merge trunk r2509.

2539. By Gavin Panella

Merge trunk r2510.

2540. By Gavin Panella

Merge trunk r2511.

2541. By Gavin Panella

Merge trunk r2512.

2542. By Gavin Panella

Merge trunk r2513.

2543. By Gavin Panella

Merge trunk r2514.

2544. By Gavin Panella

Merge trunk r2515.

2545. By Gavin Panella

Merge trunk r2516.

2546. By Gavin Panella

Merge trunk r2517.

2547. By Gavin Panella

Merge trunk r2518.

2548. By Gavin Panella

Merge trunk r2519.

2549. By Gavin Panella

Merge trunk r2520.

2550. By Gavin Panella

Merge trunk r2521.

2551. By Gavin Panella

Merge trunk r2522.

2552. By Gavin Panella

Merge trunk r2523.

2553. By Gavin Panella

Merge trunk r2524.

2554. By Gavin Panella

Merge trunk r2525.

2555. By Gavin Panella

Merge trunk r2526.

2556. By Gavin Panella

Merge trunk r2527.

2557. By Gavin Panella

Merge trunk r2528.

2558. By Gavin Panella

Merge trunk r2529.

2559. By Gavin Panella

Merge trunk r2530.

2560. By Gavin Panella

Merge trunk r2531.

2561. By Gavin Panella

Merge trunk r2532.

2562. By Gavin Panella

Merge trunk r2533.

2563. By Gavin Panella

Merge trunk r2534.

2564. By Gavin Panella

Merge trunk r2535.

2565. By Gavin Panella

Merge trunk r2536.

2566. By Gavin Panella

Merge trunk r2537.

2567. By Gavin Panella

Merge trunk r2538.

2568. By Gavin Panella

Merge trunk r2539.

2569. By Gavin Panella

Merge trunk r2540.

2570. By Gavin Panella

Merge trunk r2541.

2571. By Gavin Panella

Merge trunk r2542.

2572. By Gavin Panella

Merge trunk r2543.

2573. By Gavin Panella

Merge trunk r2544.

2574. By Gavin Panella

Merge trunk r2545.

2575. By Gavin Panella

Merge trunk r2546.

2576. By Gavin Panella

Merge trunk r2547.

2577. By Gavin Panella

Merge trunk r2548.

2578. By Gavin Panella

Merge trunk r2549.

2579. By Gavin Panella

Merge trunk r2550.

2580. By Gavin Panella

Merge trunk r2551.

2581. By Gavin Panella

Merge trunk r2552.

2582. By Gavin Panella

Merge trunk r2553.

2583. By Gavin Panella

Merge trunk r2554.

2584. By Gavin Panella

Merge trunk r2555.

2585. By Gavin Panella

Merge trunk r2556.

2586. By Gavin Panella

Merge trunk r2557.

2587. By Gavin Panella

Merge trunk r2558.

2588. By Gavin Panella

Merge trunk r2559.

2589. By Gavin Panella

Merge trunk r2560.

2590. By Gavin Panella

Merge trunk r2561.

2591. By Gavin Panella

Merge trunk r2562.

2592. By Gavin Panella

call_capture_and_check was removed a while back.

2593. By Gavin Panella

Merge trunk r2563.

2594. By Gavin Panella

Merge trunk r2564.

2595. By Gavin Panella

Merge trunk r2565.

2596. By Gavin Panella

Merge trunk r2566.

2597. By Gavin Panella

Merge trunk r2567.

2598. By Gavin Panella

Merge trunk r2568.

2599. By Gavin Panella

Merge trunk r2569.

2600. By Gavin Panella

Merge trunk r2570.

2601. By Gavin Panella

Merge trunk r2571.

2602. By Gavin Panella

Merge trunk r2572.

2603. By Gavin Panella

Merge trunk r2573.

2604. By Gavin Panella

Merge trunk r2574.

2605. By Gavin Panella

Merge trunk r2575.

2606. By Gavin Panella

Merge trunk r2576.

2607. By Gavin Panella

Merge trunk r2577.

2608. By Gavin Panella

Merge trunk r2578.

2609. By Gavin Panella

Merge trunk r2579.

2610. By Gavin Panella

Merge trunk r2580.

2611. By Gavin Panella

Merge trunk r2581.

2612. By Gavin Panella

Merge trunk r2582.

2613. By Gavin Panella

Merge trunk r2583.

2614. By Gavin Panella

Merge trunk r2584.

2615. By Gavin Panella

Merge trunk r2585.

2616. By Gavin Panella

Merge trunk r2586.

2617. By Gavin Panella

Merge trunk r2587.

2618. By Gavin Panella

Merge trunk r2588.

2619. By Gavin Panella

Merge trunk r2589.

2620. By Gavin Panella

Merge trunk r2590.

2621. By Gavin Panella

Merge trunk r2591.

2622. By Gavin Panella

Merge trunk r2592.

2623. By Gavin Panella

Merge trunk r2593.

2624. By Gavin Panella

Merge trunk r2594.

2625. By Gavin Panella

Merge trunk r2595.

2626. By Gavin Panella

Merge trunk r2596.

2627. By Gavin Panella

Merge trunk r2597.

2628. By Gavin Panella

Merge trunk r2598.

2629. By Gavin Panella

Merge trunk r2599.

2630. By Gavin Panella

Merge trunk r2600.

Revision history for this message
MAAS Lander (maas-lander) wrote :

Transitioned to Git.

lp:maas has now moved from Bzr to Git.
Please propose your branches with Launchpad using Git.

git clone https://git.launchpad.net/maas

Unmerged revisions

2630. By Gavin Panella

Merge trunk r2600.

2629. By Gavin Panella

Merge trunk r2599.

2628. By Gavin Panella

Merge trunk r2598.

2627. By Gavin Panella

Merge trunk r2597.

2626. By Gavin Panella

Merge trunk r2596.

2625. By Gavin Panella

Merge trunk r2595.

2624. By Gavin Panella

Merge trunk r2594.

2623. By Gavin Panella

Merge trunk r2593.

2622. By Gavin Panella

Merge trunk r2592.

2621. By Gavin Panella

Merge trunk r2591.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2014-01-17 18:19:37 +0000
+++ .bzrignore 2014-07-28 15:42:36 +0000
@@ -27,9 +27,20 @@
27./media/demo/*27./media/demo/*
28./media/development28./media/development
29./parts29./parts
30./pkg/*/.db.lock
31./pkg/*/.tox
32./pkg/*/bin
33./pkg/*/db
34./pkg/*/dist
35./pkg/*/include
36./pkg/*/lib
37./pkg/*/local
38./pkg/*/man
39./pkg/*/share
40./pkg/dist
41./pkg/maas-region/maasserver/static/js/enums.js
30./run/*42./run/*
31./services/*/supervise43./services/*/supervise
32./src/maasserver/static/js/enums.js
33./TAGS44./TAGS
34./tags45./tags
35dropin.cache46dropin.cache
3647
=== added file '.root'
=== modified file 'HACKING.txt'
--- HACKING.txt 2014-05-05 16:20:18 +0000
+++ HACKING.txt 2014-07-28 15:42:36 +0000
@@ -38,6 +38,8 @@
3838
39 $ bzr branch lp:maas maas && cd maas39 $ bzr branch lp:maas maas && cd maas
4040
41TODO: Some of the following is obsolete or has changed.
42
41MAAS depends on Postgres 9.1, RabbitMQ, Apache 2, daemontools,43MAAS depends on Postgres 9.1, RabbitMQ, Apache 2, daemontools,
42pyinotify, and many other packages. To install everything that's needed44pyinotify, and many other packages. To install everything that's needed
43for running and developing MAAS, run::45for running and developing MAAS, run::
@@ -58,54 +60,16 @@
58suite.60suite.
5961
60All other development dependencies are pulled automatically from62All other development dependencies are pulled automatically from
61`PyPI`_ when ``buildout`` runs. See `First time using buildout?`_ and63`PyPI`_.
62`Running tests`_.
6364
64.. _PyPI:65.. _PyPI:
65 http://pypi.python.org/66 http://pypi.python.org/
6667
6768
68First time using buildout?
69==========================
70
71Buildout_ is used to develop MAAS. Buildout, if configured so, can
72cache downloaded files and built eggs. If you've not already done
73something similar, the following snippet will massively improve build
74times::
75
76 [buildout]
77 download-cache = /home/<your-user-name>/.buildout/cache
78 eggs-directory = /home/<your-user-name>/.buildout/eggs
79
80Put this in ``~/.buildout/default.cfg`` and create the ``cache``
81directory::
82
83 $ mkdir /home/<your-user-name>/.buildout/cache
84
85The ``eggs`` directory will be created automatically.
86
87.. _Buildout:
88 http://www.buildout.org/
89
90
91Running tests69Running tests
92=============70=============
9371
94To run the whole suite::72TODO: Describe how to run tests in a post-``buildout`` world.
95
96 $ make test
97
98To run tests at a lower level of granularity::
99
100 $ ./bin/test.maas test src/maasserver/tests/test_api.py
101 $ ./bin/test.maas test src/maasserver/tests/test_api.py:AnonymousEnlistmentAPITest
102
103The test runner is `nose`_, so you can pass in options like
104``--with-coverage`` and ``--nocapture`` (short option: ``-s``). The
105latter is essential when using ``pdb`` so that stdout is not
106adulterated.
107
108.. _nose: http://readthedocs.org/docs/nose/en/latest/
10973
11074
111Running JavaScript tests75Running JavaScript tests
@@ -395,18 +359,7 @@
395Adding new dependencies359Adding new dependencies
396=======================360=======================
397361
398Since MAAS is distributed mainly as an Ubuntu package, all runtime362TODO: Describe how to add new dependencies in a post-``buildout`` world.
399dependencies should be packaged, and we should develop with the
400packaged version if possible. All dependencies, from a package or not,
401need to be added to ``setup.py`` and ``buildout.cfg``, and the version
402specified in ``versions.cfg`` (``allowed-picked-version`` is disabled,
403hence ``buildout`` must be given precise version information).
404
405If it is a development-only dependency (i.e. only needed for the test suite, or
406for developers' convenience), simply running ``buildout`` like this will make
407the necessary updates to ``versions.cfg``::
408
409 $ ./bin/buildout -v buildout:allow-picked-versions=true
410363
411364
412Adding new source files365Adding new source files
413366
=== removed file 'MANIFEST.in'
--- MANIFEST.in 2013-06-05 10:44:25 +0000
+++ MANIFEST.in 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
1graft src/*/static
2graft src/*/templates
3graft src/*/fixtures
4graft src/*/specs
5graft src/provisioningserver/*
6graft src/metadataserver/commissioning
7prune src/*/testing
8prune src/*/tests
9prune src/maastesting
10prune src/provisioningserver/*/tests
110
=== modified file 'Makefile'
--- Makefile 2014-06-10 14:45:14 +0000
+++ Makefile 2014-07-28 15:42:36 +0000
@@ -3,10 +3,8 @@
3# Network activity can be suppressed by setting offline=true (or any3# Network activity can be suppressed by setting offline=true (or any
4# non-empty string) at the command-line.4# non-empty string) at the command-line.
5ifeq ($(offline),)5ifeq ($(offline),)
6buildout := bin/buildout
7virtualenv := virtualenv6virtualenv := virtualenv
8else7else
9buildout := bin/buildout buildout:offline=true
10virtualenv := virtualenv --never-download8virtualenv := virtualenv --never-download
11endif9endif
1210
@@ -17,11 +15,6 @@
17export https_proxy := broken15export https_proxy := broken
18endif16endif
1917
20# Python enum modules.
21py_enums := $(wildcard src/*/enum.py)
22# JavaScript enum module (not modules).
23js_enums := src/maasserver/static/js/enums.js
24
25# Prefix commands with this when they need access to the database.18# Prefix commands with this when they need access to the database.
26# Remember to add a dependency on bin/database from the targets in19# Remember to add a dependency on bin/database from the targets in
27# which those commands appear.20# which those commands appear.
@@ -31,100 +24,56 @@
31# use the "maas" databases.24# use the "maas" databases.
32export PGDATABASE := maas25export PGDATABASE := maas
3326
34build: \27# Executables that are usual for a development environment.
35 bin/buildout \28define executables
36 bin/database \29 bin/database
37 bin/maas-region-admin bin/test.maas \30 bin/flake8
38 bin/maas bin/test.maascli \31 bin/ipython
39 bin/test.maastesting \32 bin/sphinx
40 bin/twistd.pserv bin/test.pserv \33
41 bin/test.config \34 bin/maas-dns-server
42 bin/maas-probe-dhcp \35 bin/maas-region-admin
43 bin/twistd.txlongpoll \36 bin/maas-region-twistd
44 bin/celeryd.cluster bin/celeryd.region \37 bin/maas-region-worker
45 bin/py bin/ipy \38
46 $(js_enums)39 bin/maas-cluster-twistd
40 bin/maas-cluster-worker
41 bin/maas-probe-dhcp
42 bin/maas-provision
43
44 bin/maas
45endef
46executables := $(strip $(executables))
47
48# The Python packages that form MAAS, in order of installation (pip is
49# not great at resolving dependencies in the correct order).
50define python-packages
51 maas-apiclient
52 maas-client
53 maas-cluster
54 maas-region
55 maas-testing
56 maas-develop
57endef
58python-packages := $(strip $(python-packages))
59
60build: $(executables) enums
4761
48all: build doc62all: build doc
4963
50# Install all packages required for MAAS development & operation on
51# the system. This may prompt for a password.
52install-dependencies:
53 sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
54 --no-install-recommends install $(shell sort -u \
55 $(addprefix required-packages/,base build dev doc))
56 sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
57 purge $(shell sort -u required-packages/forbidden)
58
59bin/python:64bin/python:
60 $(virtualenv) --python=$(python) --system-site-packages $(CURDIR)65 $(virtualenv) --python=$(python) --system-site-packages $(CURDIR)
6166
62bin/buildout: bin/python bootstrap/zc.buildout-1.5.2.tar.gz67$(executables): bin/python
63 bin/python -m pip --quiet install --ignore-installed \68 $(MAKE) -C pkg
64 --no-dependencies bootstrap/zc.buildout-1.5.2.tar.gz69 @for dep in $(python-packages); do \
65 $(RM) -f README.txt # zc.buildout installs an annoying README.txt.70 (cd pkg/$${dep} && python setup.py install_deps); done
66 @touch --no-create $@ # Ensure it's newer than its dependencies.71 bin/python -m pip install \
6772 $(addprefix --editable pkg/,$(python-packages))
68bin/database: bin/buildout buildout.cfg versions.cfg setup.py73 @touch --no-create $@
69 $(buildout) install database74
70 @touch --no-create $@75test:
7176 $(MAKE) -C pkg test
72bin/maas-region-admin bin/celeryd.region: \
73 bin/buildout buildout.cfg versions.cfg setup.py $(js_enums)
74 $(buildout) install maas
75 @touch --no-create $@
76
77bin/test.maas: bin/buildout buildout.cfg versions.cfg setup.py $(js_enums)
78 $(buildout) install maas-test
79 @touch --no-create $@
80
81bin/maas: bin/buildout buildout.cfg versions.cfg setup.py
82 $(buildout) install maascli
83 @touch --no-create $@
84
85bin/test.maascli: bin/buildout buildout.cfg versions.cfg setup.py
86 $(buildout) install maascli-test
87 @touch --no-create $@
88
89bin/test.maastesting: bin/buildout buildout.cfg versions.cfg setup.py
90 $(buildout) install maastesting-test
91 @touch --no-create $@
92
93bin/maas-provision bin/twistd.pserv bin/celeryd.cluster: \
94 bin/buildout buildout.cfg versions.cfg setup.py
95 $(buildout) install pserv
96 @touch --no-create $@
97
98bin/test.pserv: bin/buildout buildout.cfg versions.cfg setup.py
99 $(buildout) install pserv-test
100 @touch --no-create $@
101
102bin/test.config: bin/buildout buildout.cfg versions.cfg setup.py
103 $(buildout) install config-test
104 @touch --no-create $@
105
106bin/maas-probe-dhcp: bin/buildout buildout.cfg versions.cfg setup.py
107 $(buildout) install maas-probe-dhcp
108 @touch --no-create $@
109
110bin/twistd.txlongpoll: bin/buildout buildout.cfg versions.cfg setup.py
111 $(buildout) install txlongpoll
112 @touch --no-create $@
113
114bin/flake8: bin/buildout buildout.cfg versions.cfg setup.py
115 $(buildout) install flake8
116 @touch --no-create $@
117
118bin/sphinx bin/sphinx-build: bin/buildout buildout.cfg versions.cfg setup.py
119 $(buildout) install sphinx
120 @touch --no-create $@
121
122bin/py bin/ipy: bin/buildout buildout.cfg versions.cfg setup.py
123 $(buildout) install repl
124 @touch --no-create bin/py bin/ipy
125
126test: build
127 echo $(wildcard bin/test.*) | xargs -n1 env
12877
129lint: lint-py lint-js lint-doc78lint: lint-py lint-js lint-doc
13079
@@ -133,57 +82,69 @@
133# XXX jtv 2014-02-25: Clean up this lint, then make it part of "make lint".82# XXX jtv 2014-02-25: Clean up this lint, then make it part of "make lint".
134lint-css: sources = src/maasserver/static/css83lint-css: sources = src/maasserver/static/css
135lint-css:84lint-css:
136 @find $(sources) -type f \85 @find . -type f -name '*.css' -print0 | \
137 -print0 | xargs -r0 $(pocketlint) --max-length=12086 xargs -r0 $(pocketlint) --max-length=120
13887
139lint-py: sources = $(wildcard *.py contrib/*.py) src templates twisted utilities etc88lint-py: sources = src/*/ templates utilities pkg/common
89lint-py: sources += pkg/*/contrib pkg/*/etc pkg/*/*.py pkg/*/twisted
140lint-py: bin/flake890lint-py: bin/flake8
141 @find $(sources) -name '*.py' ! -path '*/migrations/*' \91 @find $(sources) -type f -name '*.py' \
142 -print0 | xargs -r0 bin/flake8 --ignore=E123 --config=/dev/null92 ! -path '*/migrations/*' ! -path '*/setup.py' -print0 | \
93 xargs -r0 bin/flake8 --ignore=E123 --config=/dev/null
14394
144lint-doc:95lint-doc:
145 @./utilities/doc-lint96 @utilities/doc-lint
14697
147lint-js: sources = src/maasserver/static/js98lint-js: sources = src/maasserver/static/js
148lint-js:99lint-js:
149 @find $(sources) -type f -print0 '(' -name '*.html' -o -name '*.js' ')' | xargs -r0 $(pocketlint)100 @find $(sources) -type f -print0 \
101 '(' -name '*.html' -o -name '*.js' ')' | \
102 xargs -r0 $(pocketlint) --max-length=120
150103
151# Apply automated formatting to all Python files.104# Apply automated formatting to all Python files.
152format: sources = $(wildcard *.py contrib/*.py) src templates twisted utilities etc105format: sources = src/*/ templates utilities pkg/common
106format: sources += pkg/*/contrib pkg/*/etc pkg/*/*.py pkg/*/twisted
153format:107format:
154 @find $(sources) -name '*.py' -print0 | xargs -r0 ./utilities/format-imports108 @find $(sources) -name '*.py' -print0 | \
109 xargs -r0 utilities/format-imports
155110
156check: clean test111check: clean test
157112
113# TODO: Move to maas-develop? Or maas-region. Generating documentation
114# may even be better contained in a separate subproject.
158docs/api.rst: bin/maas-region-admin src/maasserver/api.py syncdb115docs/api.rst: bin/maas-region-admin src/maasserver/api.py syncdb
159 bin/maas-region-admin generate_api_doc > $@116 bin/maas-region-admin generate_api_doc > $@
160117
161sampledata: bin/maas-region-admin bin/database syncdb118# TODO: Move to maas-develop? Or maas-region. Generating documentation
162 $(dbrun) bin/maas-region-admin loaddata src/maasserver/fixtures/dev_fixture.yaml119# may even be better contained in a separate subproject.
163
164doc: bin/sphinx docs/api.rst120doc: bin/sphinx docs/api.rst
165 bin/sphinx121 bin/sphinx docs docs/_build/html
166122
123# TODO: Move to maas-develop? Or maas-region. Generating documentation
124# may even be better contained in a separate subproject.
167doc-with-versions: bin/sphinx docs/api.rst125doc-with-versions: bin/sphinx docs/api.rst
168 cd docs/_build; make SPHINXOPTS="-A add_version_switcher=true" html126 cd docs/_build; make SPHINXOPTS="-A add_version_switcher=true" html
169127
128# TODO: Move to maas-develop? Or maas-region. Generating documentation
129# may even be better contained in a separate subproject.
170man: $(patsubst docs/man/%.rst,man/%,$(wildcard docs/man/*.rst))130man: $(patsubst docs/man/%.rst,man/%,$(wildcard docs/man/*.rst))
171131
172man/%: docs/man/%.rst | bin/sphinx-build132# TODO: Move to maas-develop? Or maas-region. Generating documentation
173 bin/sphinx-build -b man docs man $^133# may even be better contained in a separate subproject.
174134man/%: docs/man/%.rst | bin/sphinx
175enums: $(js_enums)135 bin/sphinx -b man docs man $^
176136
177$(js_enums): bin/py src/maasserver/utils/jsenums.py $(py_enums)137# TODO: Dynamically serve enums JavaScript to clients. This build step
178 bin/py -m src/maasserver/utils/jsenums $(py_enums) > $@138# complicates packaging, and introduces some fragility.
139enums:
140 $(MAKE) -C pkg/maas-region enums
179141
180clean:142clean:
181 $(MAKE) -C acceptance $@143 $(MAKE) -C acceptance $@
144 $(MAKE) -C pkg $@
182 find . -type f -name '*.py[co]' -print0 | xargs -r0 $(RM)145 find . -type f -name '*.py[co]' -print0 | xargs -r0 $(RM)
183 find . -type f -name '*~' -print0 | xargs -r0 $(RM)146 find . -type f -name '*~' -print0 | xargs -r0 $(RM)
184 find . -type f -name dropin.cache -print0 | xargs -r0 $(RM)147 find . -type f -name dropin.cache -print0 | xargs -r0 $(RM)
185 $(RM) -r media/demo/* media/development
186 $(RM) $(js_enums)
187 $(RM) *.log148 $(RM) *.log
188 $(RM) docs/api.rst149 $(RM) docs/api.rst
189 $(RM) -r docs/_autosummary docs/_build150 $(RM) -r docs/_autosummary docs/_build
@@ -191,23 +152,31 @@
191152
192distclean: clean stop153distclean: clean stop
193 $(RM) -r bin include lib local154 $(RM) -r bin include lib local
194 $(RM) -r eggs develop-eggs155 $(RM) -r build dist logs/*
195 $(RM) -r build dist logs/* parts156 $(RM) tags TAGS
196 $(RM) tags TAGS .installed.cfg157 $(RM) -r *.egg *.egg-info
197 $(RM) -r *.egg *.egg-info src/*.egg-info
198 $(RM) -r run/* services/*/supervise158 $(RM) -r run/* services/*/supervise
199159
160# TODO: Move to maas-develop? This is a development-only target.
200harness: bin/maas-region-admin bin/database161harness: bin/maas-region-admin bin/database
201 $(dbrun) bin/maas-region-admin shell --settings=maas.demo162 $(dbrun) bin/maas-region-admin shell
202163
164# TODO: Move to maas-develop? This is a development-only target.
203dbharness: bin/database165dbharness: bin/database
204 bin/database --preserve shell166 bin/database --preserve shell
205167
168# TODO: Move to maas-develop? This is a development-only target.
206syncdb: bin/maas-region-admin bin/database169syncdb: bin/maas-region-admin bin/database
207 $(dbrun) bin/maas-region-admin syncdb --noinput170 $(dbrun) bin/maas-region-admin syncdb --noinput
208 $(dbrun) bin/maas-region-admin migrate maasserver --noinput171 $(dbrun) bin/maas-region-admin migrate maasserver --noinput
209 $(dbrun) bin/maas-region-admin migrate metadataserver --noinput172 $(dbrun) bin/maas-region-admin migrate metadataserver --noinput
210173
174# TODO: Move to maas-develop, along with dev_fixture.yaml? This is a
175# development-only target.
176sampledata: bin/maas-region-admin bin/database syncdb
177 $(dbrun) bin/maas-region-admin loaddata \
178 src/maasserver/fixtures/dev_fixture.yaml
179
211define phony_targets180define phony_targets
212 build181 build
213 check182 check
@@ -218,7 +187,6 @@
218 enums187 enums
219 format188 format
220 harness189 harness
221 install-dependencies
222 lint190 lint
223 lint-css191 lint-css
224 lint-doc192 lint-doc
@@ -262,12 +230,19 @@
262$(eval $(call service_template,stop))230$(eval $(call service_template,stop))
263$(eval $(call service_template,supervise))231$(eval $(call service_template,supervise))
264232
265# The `run` targets do not fit into the mould of the others.233# The `run` targets do not fit into the mould of the others. Note: logs
234# directories shouldn't be needed for `run` targets, but some config
235# seems to still require it, so we create them. Ideally the configs used
236# for running services should log to stdout/stderr, then we could get
237# rid of these.
266run-region:238run-region:
239 @mkdir -p $(addprefix logs/,$(service_names_region))
267 @services/run $(service_names_region)240 @services/run $(service_names_region)
268run-cluster:241run-cluster:
242 @mkdir -p $(addprefix logs/,$(service_names_cluster))
269 @services/run $(service_names_cluster)243 @services/run $(service_names_cluster)
270run:244run:
245 @mkdir -p $(addprefix logs/,$(service_names_all))
271 @services/run $(service_names_all)246 @services/run $(service_names_all)
272247
273phony_services_targets += run-region run-cluster run248phony_services_targets += run-region run-cluster run
@@ -290,7 +265,12 @@
290265
291# Pseudo-magic targets for controlling individual services.266# Pseudo-magic targets for controlling individual services.
292267
268# Note: log directories shouldn't be needed for `@run` targets, but some
269# config seems to still require it, so we create them. Ideally the
270# configs used for running services should log to stdout/stderr, then we
271# could get rid of this.
293services/%/@run: services/%/@stop services/%/@deps272services/%/@run: services/%/@stop services/%/@deps
273 @mkdir -p logs/$*
294 @$(call service_lock, $*) services/$*/run274 @$(call service_lock, $*) services/$*/run
295275
296services/%/@start: services/%/@supervise276services/%/@start: services/%/@supervise
@@ -319,19 +299,19 @@
319299
320# Dependencies for individual services.300# Dependencies for individual services.
321301
322services/dns/@deps: bin/py302services/dns/@deps: bin/maas-dns-server
323303
324services/cluster-worker/@deps: bin/celeryd.cluster304services/cluster-worker/@deps: bin/maas-cluster-worker
325305
326services/region-worker/@deps: bin/celeryd.region306services/region-worker/@deps: bin/maas-region-worker
327307
328services/database/@deps: bin/database308services/database/@deps: bin/database
329309
330services/pserv/@deps: bin/twistd.pserv310services/pserv/@deps: bin/maas-cluster-twistd
331311
332services/reloader/@deps:312services/reloader/@deps:
333313
334services/txlongpoll/@deps: bin/twistd.txlongpoll314services/txlongpoll/@deps: bin/maas-region-twistd
335315
336services/web/@deps:316services/web/@deps:
337317
338318
=== removed directory 'bootstrap'
=== removed file 'bootstrap/zc.buildout-1.5.2.tar.gz'
339Binary files bootstrap/zc.buildout-1.5.2.tar.gz 2012-06-14 11:21:10 +0000 and bootstrap/zc.buildout-1.5.2.tar.gz 1970-01-01 00:00:00 +0000 differ319Binary files bootstrap/zc.buildout-1.5.2.tar.gz 2012-06-14 11:21:10 +0000 and bootstrap/zc.buildout-1.5.2.tar.gz 1970-01-01 00:00:00 +0000 differ
=== removed file 'buildout.cfg'
--- buildout.cfg 2014-03-18 14:35:22 +0000
+++ buildout.cfg 1970-01-01 00:00:00 +0000
@@ -1,232 +0,0 @@
1[buildout]
2parts =
3 flake8
4 maas
5 maas-test
6 maascli
7 maascli-test
8 maas-probe-dhcp
9 maastesting-test
10 pserv
11 pserv-test
12 config-test
13 repl
14 sphinx
15 txlongpoll
16extensions = buildout-versions
17buildout_versions_file = versions.cfg
18versions = versions
19extends = versions.cfg
20offline = false
21newest = false
22
23# Since MAAS's main deployment target is Ubuntu, all runtime
24# dependencies should come from python packages. However, it's okay
25# for development-time dependencies to come from eggs.
26include-site-packages = true
27
28prefer-final = true
29allow-picked-versions = false
30
31[common]
32extra-paths =
33 ${buildout:directory}/etc
34 ${buildout:directory}/src
35 ${buildout:directory}
36test-eggs =
37 coverage
38 fixtures
39 mock
40 nose
41 nose-subunit
42 postgresfixture
43 python-subunit
44 rabbitfixture
45 saucelabsfixture
46 sst
47 testresources
48 testscenarios
49 testtools
50initialization =
51 from os import environ
52 environ.setdefault("MAAS_CONFIG_DIR", "${buildout:directory}/etc/maas")
53
54[database]
55recipe = z3c.recipe.scripts
56eggs = postgresfixture
57extra-paths = ${common:extra-paths}
58interpreter =
59entry-points = database=postgresfixture.main:main
60scripts = database
61
62[maas]
63recipe = zc.recipe.egg
64dev-eggs =
65 django-debug-toolbar
66test-eggs =
67 ${common:test-eggs}
68 django-nose
69eggs =
70 ${maas:dev-eggs}
71 ${maas:test-eggs}
72 djorm-ext-pgarray
73 docutils
74 crochet
75 iscpy
76entry-points =
77 celeryd.region=celery.bin.worker:main
78 maas-region-admin=django.core.management:execute_from_command_line
79initialization =
80 ${common:initialization}
81 environ.setdefault("DJANGO_SETTINGS_MODULE", "maas.development")
82scripts =
83 celeryd.region
84 maas-region-admin
85extra-paths =
86 ${common:extra-paths}
87
88[maas-test]
89recipe = zc.recipe.egg
90eggs =
91 ${maas:eggs}
92entry-points =
93 test.maas=django.core.management:execute_from_command_line
94initialization =
95 ${maas:initialization}
96 sys.argv[1:1] = [
97 "test", "--noinput", "--exclude=provisioningserver",
98 "--exclude=maastesting", "--exclude=maascli"]
99scripts = test.maas
100extra-paths =
101 ${maas:extra-paths}
102
103[maas-probe-dhcp]
104recipe = zc.recipe.egg
105eggs =
106 ${maas:eggs}
107entry-points =
108 maas-probe-dhcp=provisioningserver.dhcp.probe:main
109scripts =
110 maas-probe-dhcp
111extra-paths =
112 ${maas:extra-paths}
113initialization =
114 ${common:initialization}
115
116[maascli]
117recipe = zc.recipe.egg
118eggs =
119entry-points =
120 maas=maascli:main
121extra-paths =
122 ${common:extra-paths}
123scripts =
124 maas
125
126[maascli-test]
127recipe = zc.recipe.egg
128eggs =
129 ${maascli:eggs}
130 ${common:test-eggs}
131entry-points =
132 test.maascli=nose.core:TestProgram
133initialization =
134 sys.argv[1:1] = ["--where=src/maascli"]
135extra-paths = ${maascli:extra-paths}
136scripts =
137 test.maascli
138
139[maastesting-test]
140recipe = zc.recipe.egg
141eggs =
142 ${common:test-eggs}
143entry-points =
144 test.maastesting=nose.core:TestProgram
145initialization =
146 sys.argv[1:1] = ["--where=src/maastesting"]
147extra-paths = ${common:extra-paths}
148scripts =
149 test.maastesting
150scripts = test.maastesting
151extra-paths =
152 ${maas:extra-paths}
153
154[pserv]
155recipe = zc.recipe.egg
156eggs =
157 crochet
158entry-points =
159 celeryd.cluster=celery.bin.worker:main
160 maas-provision=provisioningserver.__main__:main
161 twistd.pserv=twisted.scripts.twistd:run
162extra-paths =
163 ${common:extra-paths}
164scripts =
165 celeryd.cluster
166 maas-provision
167 twistd.pserv
168initialization =
169 ${common:initialization}
170
171[pserv-test]
172recipe = zc.recipe.egg
173eggs =
174 ${pserv:eggs}
175 ${common:test-eggs}
176entry-points =
177 test.pserv=nose.core:TestProgram
178initialization =
179 ${pserv:initialization}
180 sys.argv[1:1] = ["--where=src/provisioningserver"]
181extra-paths = ${pserv:extra-paths}
182scripts =
183 test.pserv
184
185[config-test]
186recipe = zc.recipe.egg
187eggs =
188 ${common:test-eggs}
189entry-points =
190 test.config=nose.core:TestProgram
191initialization =
192 ${pserv:initialization}
193 sys.argv[1:1] = ["--where=etc/maas/templates/commissioning-user-data"]
194extra-paths = ${common:extra-paths}
195scripts =
196 test.config
197
198[flake8]
199recipe = zc.recipe.egg
200eggs =
201 flake8
202entry-points =
203 flake8=flake8.run:main
204
205[sphinx]
206recipe = collective.recipe.sphinxbuilder
207source = ${buildout:directory}/docs
208build = ${buildout:directory}/docs/_build
209extra-paths = ${common:extra-paths}
210eggs =
211 ${maas:eggs}
212 ${pserv:eggs}
213
214# Convenient REPLs with all eggs available.
215[repl]
216recipe = z3c.recipe.scripts
217eggs =
218 ${maas:eggs}
219 ${pserv:eggs}
220 ${common:test-eggs}
221extra-paths = ${common:extra-paths}
222interpreter = py
223scripts = ipy
224entry-points =
225 ipy=IPython.frontend.terminal.ipapp:launch_new_instance
226
227[txlongpoll]
228recipe = z3c.recipe.scripts
229eggs =
230extra-paths = /buildout/creates/an/invalid/list/literal/without/this
231entry-points = twistd.txlongpoll=twisted.scripts.twistd:run
232scripts = twistd.txlongpoll
2330
=== removed directory 'contrib'
=== removed directory 'etc'
=== removed symlink 'etc/apache.trusty.conf'
=== target was u'apache.saucy.conf'
=== removed directory 'etc/maas'
=== removed directory 'etc/maas/templates'
=== removed file 'etc/maas_local_celeryconfig_cluster.py'
--- etc/maas_local_celeryconfig_cluster.py 2013-12-03 13:06:17 +0000
+++ etc/maas_local_celeryconfig_cluster.py 1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
1# This is the version of maas_local_celeryconfig_cluster.py that's used
2# when running from a branch. The master cluster controller (running on
3# the same development machine) has a fixed UUID.
4CLUSTER_UUID = "adfd3977-f251-4f2c-8d61-745dbd690bf2"
50
=== added directory 'pkg'
=== added file 'pkg/Makefile'
--- pkg/Makefile 1970-01-01 00:00:00 +0000
+++ pkg/Makefile 2014-07-28 15:42:36 +0000
@@ -0,0 +1,49 @@
1# Copyright 2013 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4PYTHON := python
5
6define sdist
7$(PYTHON) setup.py --quiet \
8 egg_info sdist --dist-dir $(CURDIR)/dist
9endef
10
11define make-dist-for
12cd $(1) && $(sdist)
13endef
14
15setups := $(patsubst %/configure.py,%/setup.py,$(wildcard */configure.py))
16
17# ---
18
19all: $(setups)
20
21dists: $(setups)
22 $(call make-dist-for,maas-apiclient)
23 $(call make-dist-for,maas-client)
24 $(call make-dist-for,maas-cluster)
25 $(call make-dist-for,maas-develop)
26 $(call make-dist-for,maas-region)
27 $(call make-dist-for,maas-testing)
28
29test: $(setups)
30 @ls -1d maas-* | xargs --verbose -I {} make -C {} $@
31
32clean:
33 @ls -1d common maas-* | xargs --verbose -I {} make -C {} $@
34 find . -name '*~' -print0 | xargs -r0 $(RM)
35 $(RM) -r dist
36
37%/setup.py: %/configure.py common/*.py
38 $(MAKE) -C $(@D) $(@F)
39
40# ---
41
42define phony
43 all
44 clean
45 dists
46 test
47endef
48
49.PHONY: $(strip $(phony))
050
=== added directory 'pkg/common'
=== added file 'pkg/common/Makefile'
--- pkg/common/Makefile 1970-01-01 00:00:00 +0000
+++ pkg/common/Makefile 2014-07-28 15:42:36 +0000
@@ -0,0 +1,57 @@
1# Copyright 2013, 2014 Canonical Ltd. This software is licensed under
2# the GNU Affero General Public License version 3 (see the file LICENSE).
3
4PYTHON := python
5
6define virtualenv
7virtualenv --python=$(PYTHON) --quiet
8endef
9
10# ---
11
12all: build
13
14ifneq ($(localdeps),)
15build:: bin/python
16 @for dep in $(localdeps); do \
17 (cd ../$${dep} && python setup.py install_deps); done
18 bin/python -m pip install $(addprefix --editable ../,$(localdeps))
19endif
20
21build:: bin/python setup.py
22 bin/python setup.py --quiet install_deps develop
23
24dist:: bin/python setup.py
25 bin/python setup.py --quiet egg_info sdist
26
27test:: build bin/python setup.py
28 PATH="$$PWD/bin:$$PATH" bin/python setup.py install_deps test
29
30clean::
31 $(RM) -r bin build dist include lib local man share
32 find . -name '*.py[co]' -print0 | xargs -r0 $(RM) -r
33 find . -name '__pycache__' -print0 | xargs -r0 $(RM) -r
34 find . -name '*.egg' -print0 | xargs -r0 $(RM) -r
35 find . -name '*.egg-info' -print0 | xargs -r0 $(RM) -r
36 find . -name '*~' -print0 | xargs -r0 $(RM)
37 $(RM) -r .tox TAGS tags
38
39# ---
40
41bin/python:
42 $(virtualenv) --system-site-packages $(CURDIR)
43
44setup.py: configure.py common/*.py
45 $(PYTHON) $<
46
47# ---
48
49define phony
50 all
51 build
52 clean
53 dist
54 test
55endef
56
57.PHONY: $(strip $(phony))
058
=== added file 'pkg/common/__init__.py'
--- pkg/common/__init__.py 1970-01-01 00:00:00 +0000
+++ pkg/common/__init__.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,194 @@
1#!/usr/bin/env python
2# Copyright 2013 Canonical Ltd. This software is licensed under the
3# GNU Affero General Public License version 3 (see the file LICENSE).
4
5"""Distutils installer for MAAS."""
6
7# unicode_literals is *not* included here to *better* support setup
8# scripts that work on both Python 2 and 3. Both expect their default
9# string type, and are fussy about it.
10from __future__ import (
11 absolute_import,
12 print_function,
13 )
14
15__version__ = "1.4"
16__metaclass__ = type
17
18
19from codecs import open
20from contextlib import contextmanager
21from distutils import (
22 errors,
23 log,
24 )
25from inspect import getsourcefile
26from operator import methodcaller
27from os import environ
28
29import setuptools
30
31
32@contextmanager
33def envvar(name, value):
34 """Context manager for temporarily setting an environment variable."""
35 original = environ.get(name)
36 environ[name] = value
37 try:
38 yield
39 finally:
40 if original is None:
41 environ.pop(name, None)
42 else:
43 environ[name] = original
44
45
46class install_deps(setuptools.Command):
47 """Distutils/setuptools command to install package dependencies."""
48
49 user_options = [
50 ('list-from=', None,
51 "file from which to read packages to install"),
52 ]
53
54 def initialize_options(self):
55 self.list_from = "packages.txt"
56
57 def gen_package_ops(self, package_lines):
58 install = methodcaller("mark_install")
59 delete = methodcaller("mark_delete", purge=True)
60 for line in package_lines:
61 if len(line) == 0:
62 pass # Ignore blank lines.
63 elif line.startswith("#"):
64 pass # Ignore whole-line comments.
65 elif line.endswith("-"):
66 package_name = line.rstrip("-")
67 yield package_name, delete
68 else:
69 package_name = line.rstrip("+")
70 yield package_name, install
71
72 def finalize_options(self):
73 self.ensure_filename("list_from")
74 self.packages = set()
75 with open(self.list_from, "r", encoding="utf-8") as fd:
76 lines = (line.strip() for line in fd)
77 self.package_ops = dict(self.gen_package_ops(lines))
78 self.packages = set(self.package_ops)
79
80 def run(self):
81 self.calculate_changes()
82 if len(self.changes) > 0:
83 self.apply_changes()
84
85 def calculate_changes(self):
86 from apt import Cache
87 cache = Cache()
88 for package_name, op in self.package_ops.iteritems():
89 op(cache[package_name])
90 self.changes = cache.get_changes()
91
92 def get_packages_to_install(self):
93 return self.packages.intersection(
94 package.name for package in self.changes
95 if package.marked_install or package.marked_upgrade)
96
97 def get_packages_to_delete(self):
98 return self.packages.intersection(
99 package.name for package in self.changes
100 if package.marked_delete)
101
102 def apply_changes(self):
103 """Use ``apt`` to check for package installs.
104
105 Spawns ``apt-get`` if necessary.
106 """
107 to_install = {
108 "%s+" % package
109 for package in self.get_packages_to_install()
110 }
111 if len(to_install) == 0:
112 log.info("system dependencies are all in place")
113
114 to_delete = {
115 "%s-" % package
116 for package in self.get_packages_to_delete()
117 }
118 if len(to_delete) == 0:
119 log.info("no forbidden system dependencies are installed")
120
121 to_do = sorted(to_install | to_delete)
122 if len(to_do) > 0:
123 install = [
124 "sudo", "apt-get", "--assume-yes",
125 "--no-install-recommends", "--purge",
126 "install",
127 ]
128 with envvar("DEBIAN_FRONTEND", "noninteractive"):
129 self.spawn(install + to_do)
130
131
132def check_settings(settings):
133 """Check setup settings for obvious issues.
134
135 - ``data_files`` should not be specified; setuptools ignores it.
136
137 - ``include_package_data`` should not be specified; it has weird
138 behaviour in setuptools.
139 """
140 if "data_files" in settings:
141 raise errors.DistutilsOptionError(
142 "data_files is ignored by setuptools")
143 if "include_package_data" in settings:
144 raise errors.DistutilsOptionError(
145 "include_package_data does not work as you "
146 "might expect with setuptools")
147
148
149def setup(**kwargs):
150 """MAAS-specific setup function.
151
152 Determines sensible defaults for many parameters.
153 """
154 command_classes = {}
155
156 try:
157 import apt
158 except ImportError:
159 log.warn("apt not available (install 'python-apt'?)")
160 else:
161 command_classes["install_deps"] = install_deps
162 apt # Silence lint.
163
164 settings = {
165 "cmdclass": command_classes,
166 "packages": setuptools.find_packages(".", exclude={"common"}),
167 "version": __version__,
168 "maintainer": "Canonical",
169 "maintainer_email": "maas-devel@lists.launchpad.net",
170 "url": "https://launchpad.net/maas",
171 "license": "AGPLv3",
172 "test_loader": "maastesting.loader:MAASTestLoader",
173 "test_suite": ".",
174 "tests_require": {"maas-testing >= %s" % __version__},
175 }
176 settings.update(kwargs)
177 check_settings(settings)
178
179 return setuptools.setup(**settings)
180
181
182def configure(**settings):
183 """Create a new ``setup.py`` file in the currnet directory.
184
185 Uses the file in which this function is originally defined as a
186 template, adding on a call to ``setup`` with the given ``settings``.
187 """
188 check_settings(settings)
189 thisfile = getsourcefile(configure)
190 with open(thisfile, "r", encoding="utf-8") as fin:
191 template = fin.read()
192 with open("setup.py", "w", encoding="utf-8") as fout:
193 fout.write(template)
194 fout.write(b"\n\nsetup(**%r)\n" % settings)
0195
=== added file 'pkg/common/checkarchive.py'
--- pkg/common/checkarchive.py 1970-01-01 00:00:00 +0000
+++ pkg/common/checkarchive.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,96 @@
1#!/usr/bin/env python2.7
2# Copyright 2013 Canonical Ltd. This software is licensed under the
3# GNU Affero General Public License version 3 (see the file LICENSE).
4
5"""Helper to compare the names in an archive with the filesystem.
6
7More specifically, the names of - and contained within - one or more
8directories. Typically these would be top-level Python package
9directories, and the archive would be a source distribution of the
10aforementioned archive.
11
12"""
13
14from __future__ import (
15 absolute_import,
16 print_function,
17 unicode_literals,
18 )
19
20str = None
21
22__metaclass__ = type
23
24import argparse
25from fnmatch import fnmatchcase
26from itertools import (
27 chain,
28 imap,
29 )
30import os
31from os.path import join
32import tarfile
33
34
35ignore = [
36 "*.egg-info",
37 "*.egg-info/*",
38 "*.py[co]",
39 "MANIFEST.in",
40 "PKG-INFO",
41 "README.*",
42 "setup.cfg",
43 "setup.py",
44]
45
46
47# See http://docs.python.org/release/2.7/library/argparse.html.
48argument_parser = argparse.ArgumentParser(description=__doc__)
49argument_parser.add_argument(
50 "archive", type=bytes, help="The archive to compare.")
51argument_parser.add_argument(
52 "directories", metavar="directory", nargs="+", type=bytes,
53 help="Directories to compare.")
54argument_parser.add_argument(
55 "--ignore", action="append", type=bytes, default=ignore,
56 help="Full-path patterns to ignore (default: %s)." % ", ".join(ignore))
57
58
59def walk_tarball(filename):
60 for name in tarfile.open(args.archive, "r").getnames():
61 parts = name.split(b"/")
62 if len(parts) > 1:
63 yield b"/".join(parts[1:])
64
65
66def walk_directory(directory):
67 yield directory
68 for root, dirnames, filenames in os.walk(directory):
69 for dirname in dirnames:
70 yield join(root, dirname)
71 for filename in filenames:
72 yield join(root, filename)
73
74
75def filter_matching_paths(paths, ignore):
76 for path in paths:
77 for pattern in ignore:
78 if fnmatchcase(path, pattern):
79 break
80 else:
81 yield path
82
83
84if __name__ == "__main__":
85 args = argument_parser.parse_args()
86 names_from_dist = walk_tarball(args.archive)
87 names_from_dist = filter_matching_paths(names_from_dist, args.ignore)
88 names_from_dist = set(names_from_dist)
89 names_from_fs = imap(walk_directory, args.directories)
90 names_from_fs = chain.from_iterable(names_from_fs)
91 names_from_fs = filter_matching_paths(names_from_fs, args.ignore)
92 names_from_fs = set(names_from_fs)
93 for name in sorted(names_from_dist - names_from_fs):
94 print("+", name)
95 for name in sorted(names_from_fs - names_from_dist):
96 print("-", name)
097
=== added file 'pkg/common/tox.ini'
--- pkg/common/tox.ini 1970-01-01 00:00:00 +0000
+++ pkg/common/tox.ini 2014-07-28 15:42:36 +0000
@@ -0,0 +1,11 @@
1[tox]
2minversion = 1.6
3# envlist = py27, py33
4envlist = py27
5
6[testenv]
7commands = {envpython} setup.py test
8install_command = pip install --find-links ../dist {opts} {packages}
9sitepackages = True
10usedevelop = True
11deps =
012
=== added directory 'pkg/maas-apiclient'
=== added file 'pkg/maas-apiclient/Makefile'
--- pkg/maas-apiclient/Makefile 1970-01-01 00:00:00 +0000
+++ pkg/maas-apiclient/Makefile 2014-07-28 15:42:36 +0000
@@ -0,0 +1,9 @@
1localdeps := maas-testing
2
3# TODO: This duplicates what's in maas-develop.testing.entrypoints. The
4# latter is a better approach to ensuring that environment variables are
5# set for the test suite as a whole, but there's probably a better way
6# than either.
7test:: export DJANGO_SETTINGS_MODULE := apiclient.testing.settings
8
9include ../common/Makefile
010
=== added file 'pkg/maas-apiclient/README.rst'
--- pkg/maas-apiclient/README.rst 1970-01-01 00:00:00 +0000
+++ pkg/maas-apiclient/README.rst 2014-07-28 15:42:36 +0000
@@ -0,0 +1,5 @@
1--------------
2maas-apiclient
3--------------
4
5API client library for MAAS.
06
=== renamed directory 'src/apiclient' => 'pkg/maas-apiclient/apiclient'
=== added file 'pkg/maas-apiclient/apiclient/testing/settings.py'
--- pkg/maas-apiclient/apiclient/testing/settings.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-apiclient/apiclient/testing/settings.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,18 @@
1# Copyright 2012-2013 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Django settings for testing apiclient."""
5
6from __future__ import (
7 absolute_import,
8 print_function,
9 unicode_literals,
10 )
11
12str = None
13
14__metaclass__ = type
15
16
17SECRET_KEY = 'bogus secret key'
18DEBUG = True
019
=== added symlink 'pkg/maas-apiclient/common'
=== target is u'../common'
=== added file 'pkg/maas-apiclient/configure.py'
--- pkg/maas-apiclient/configure.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-apiclient/configure.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,19 @@
1from common import (
2 __version__,
3 configure,
4 )
5
6
7configure(
8 name='maas-apiclient',
9 description="MAAS API client library.",
10 install_requires=[
11 "oauth >= 1.0.1",
12 ],
13 tests_require=[
14 "django >= 1.5.4",
15 "django-piston >= 0.2.3",
16 "maas-testing >= %s" % __version__,
17 "testtools >= 0.9.32",
18 ],
19)
020
=== added file 'pkg/maas-apiclient/packages.txt'
--- pkg/maas-apiclient/packages.txt 1970-01-01 00:00:00 +0000
+++ pkg/maas-apiclient/packages.txt 2014-07-28 15:42:36 +0000
@@ -0,0 +1,4 @@
1python-django
2python-django-piston
3python-oauth
4python-testtools
05
=== added file 'pkg/maas-apiclient/setup.py'
--- pkg/maas-apiclient/setup.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-apiclient/setup.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,197 @@
1#!/usr/bin/env python
2# Copyright 2013 Canonical Ltd. This software is licensed under the
3# GNU Affero General Public License version 3 (see the file LICENSE).
4
5"""Distutils installer for MAAS."""
6
7# unicode_literals is *not* included here to *better* support setup
8# scripts that work on both Python 2 and 3. Both expect their default
9# string type, and are fussy about it.
10from __future__ import (
11 absolute_import,
12 print_function,
13 )
14
15__version__ = "1.4"
16__metaclass__ = type
17
18
19from codecs import open
20from contextlib import contextmanager
21from distutils import (
22 errors,
23 log,
24 )
25from inspect import getsourcefile
26from operator import methodcaller
27from os import environ
28
29import setuptools
30
31
32@contextmanager
33def envvar(name, value):
34 """Context manager for temporarily setting an environment variable."""
35 original = environ.get(name)
36 environ[name] = value
37 try:
38 yield
39 finally:
40 if original is None:
41 environ.pop(name, None)
42 else:
43 environ[name] = original
44
45
46class install_deps(setuptools.Command):
47 """Distutils/setuptools command to install package dependencies."""
48
49 user_options = [
50 ('list-from=', None,
51 "file from which to read packages to install"),
52 ]
53
54 def initialize_options(self):
55 self.list_from = "packages.txt"
56
57 def gen_package_ops(self, package_lines):
58 install = methodcaller("mark_install")
59 delete = methodcaller("mark_delete", purge=True)
60 for line in package_lines:
61 if len(line) == 0:
62 pass # Ignore blank lines.
63 elif line.startswith("#"):
64 pass # Ignore whole-line comments.
65 elif line.endswith("-"):
66 package_name = line.rstrip("-")
67 yield package_name, delete
68 else:
69 package_name = line.rstrip("+")
70 yield package_name, install
71
72 def finalize_options(self):
73 self.ensure_filename("list_from")
74 self.packages = set()
75 with open(self.list_from, "r", encoding="utf-8") as fd:
76 lines = (line.strip() for line in fd)
77 self.package_ops = dict(self.gen_package_ops(lines))
78 self.packages = set(self.package_ops)
79
80 def run(self):
81 self.calculate_changes()
82 if len(self.changes) > 0:
83 self.apply_changes()
84
85 def calculate_changes(self):
86 from apt import Cache
87 cache = Cache()
88 for package_name, op in self.package_ops.iteritems():
89 op(cache[package_name])
90 self.changes = cache.get_changes()
91
92 def get_packages_to_install(self):
93 return self.packages.intersection(
94 package.name for package in self.changes
95 if package.marked_install or package.marked_upgrade)
96
97 def get_packages_to_delete(self):
98 return self.packages.intersection(
99 package.name for package in self.changes
100 if package.marked_delete)
101
102 def apply_changes(self):
103 """Use ``apt`` to check for package installs.
104
105 Spawns ``apt-get`` if necessary.
106 """
107 to_install = {
108 "%s+" % package
109 for package in self.get_packages_to_install()
110 }
111 if len(to_install) == 0:
112 log.info("system dependencies are all in place")
113
114 to_delete = {
115 "%s-" % package
116 for package in self.get_packages_to_delete()
117 }
118 if len(to_delete) == 0:
119 log.info("no forbidden system dependencies are installed")
120
121 to_do = sorted(to_install | to_delete)
122 if len(to_do) > 0:
123 install = [
124 "sudo", "apt-get", "--assume-yes",
125 "--no-install-recommends", "--purge",
126 "install",
127 ]
128 with envvar("DEBIAN_FRONTEND", "noninteractive"):
129 self.spawn(install + to_do)
130
131
132def check_settings(settings):
133 """Check setup settings for obvious issues.
134
135 - ``data_files`` should not be specified; setuptools ignores it.
136
137 - ``include_package_data`` should not be specified; it has weird
138 behaviour in setuptools.
139 """
140 if "data_files" in settings:
141 raise errors.DistutilsOptionError(
142 "data_files is ignored by setuptools")
143 if "include_package_data" in settings:
144 raise errors.DistutilsOptionError(
145 "include_package_data does not work as you "
146 "might expect with setuptools")
147
148
149def setup(**kwargs):
150 """MAAS-specific setup function.
151
152 Determines sensible defaults for many parameters.
153 """
154 command_classes = {}
155
156 try:
157 import apt
158 except ImportError:
159 log.warn("apt not available (install 'python-apt'?)")
160 else:
161 command_classes["install_deps"] = install_deps
162 apt # Silence lint.
163
164 settings = {
165 "cmdclass": command_classes,
166 "packages": setuptools.find_packages(".", exclude={"common"}),
167 "version": __version__,
168 "maintainer": "Canonical",
169 "maintainer_email": "maas-devel@lists.launchpad.net",
170 "url": "https://launchpad.net/maas",
171 "license": "AGPLv3",
172 "test_loader": "maastesting.loader:MAASTestLoader",
173 "test_suite": ".",
174 "tests_require": {"maas-testing >= %s" % __version__},
175 }
176 settings.update(kwargs)
177 check_settings(settings)
178
179 return setuptools.setup(**settings)
180
181
182def configure(**settings):
183 """Create a new ``setup.py`` file in the currnet directory.
184
185 Uses the file in which this function is originally defined as a
186 template, adding on a call to ``setup`` with the given ``settings``.
187 """
188 check_settings(settings)
189 thisfile = getsourcefile(configure)
190 with open(thisfile, "r", encoding="utf-8") as fin:
191 template = fin.read()
192 with open("setup.py", "w", encoding="utf-8") as fout:
193 fout.write(template)
194 fout.write(b"\n\nsetup(**%r)\n" % settings)
195
196
197setup(**{'install_requires': ['oauth >= 1.0.1'], 'name': 'maas-apiclient', 'tests_require': ['django >= 1.5.4', 'django-piston >= 0.2.3', 'maas-testing >= 1.4', 'testtools >= 0.9.32'], 'description': 'MAAS API client library.'})
0198
=== added directory 'pkg/maas-client'
=== added file 'pkg/maas-client/Makefile'
--- pkg/maas-client/Makefile 1970-01-01 00:00:00 +0000
+++ pkg/maas-client/Makefile 2014-07-28 15:42:36 +0000
@@ -0,0 +1,3 @@
1localdeps := maas-apiclient maas-testing
2
3include ../common/Makefile
04
=== added file 'pkg/maas-client/README.rst'
--- pkg/maas-client/README.rst 1970-01-01 00:00:00 +0000
+++ pkg/maas-client/README.rst 2014-07-28 15:42:36 +0000
@@ -0,0 +1,5 @@
1------------
2maas-testing
3------------
4
5Testing utilities for MAAS.
06
=== added symlink 'pkg/maas-client/common'
=== target is u'../common'
=== added file 'pkg/maas-client/configure.py'
--- pkg/maas-client/configure.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-client/configure.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,26 @@
1from common import (
2 __version__,
3 configure,
4 )
5
6
7configure(
8 name='maas-client',
9 description="MAAS command-line client.",
10 install_requires=[
11 "bzr >= 2.6.0",
12 "httplib2 >= 0.8",
13 "maas-apiclient >= %s" % __version__,
14 ],
15 tests_require=[
16 "maas-testing >= %s" % __version__,
17 "mock >= 1.0.1",
18 "testtools >= 0.9.32",
19 "twisted >= 13.0.0",
20 ],
21 entry_points={
22 "console_scripts": {
23 "maas = maascli:main",
24 },
25 }
26)
027
=== renamed directory 'src/maascli' => 'pkg/maas-client/maascli'
=== modified file 'pkg/maas-client/maascli/tests/test_integration.py'
--- src/maascli/tests/test_integration.py 2014-02-12 04:50:36 +0000
+++ pkg/maas-client/maascli/tests/test_integration.py 2014-07-28 15:42:36 +0000
@@ -1,7 +1,7 @@
1# Copyright 2012, 2013 Canonical Ltd. This software is licensed under the1# Copyright 2012-2014 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Integration-test the `maascli` command."""4"""Integration-test the `maas` command."""
55
6from __future__ import (6from __future__ import (
7 absolute_import,7 absolute_import,
@@ -14,37 +14,38 @@
14__metaclass__ = type14__metaclass__ = type
15__all__ = []15__all__ = []
1616
17import os.path17from os import (
18 environ,
19 path,
20 )
18from subprocess import (21from subprocess import (
19 CalledProcessError,22 CalledProcessError,
20 check_output,23 check_output,
21 STDOUT,24 STDOUT,
22 )25 )
26import sys
2327
24from maastesting import root28import maascli
25from maastesting.testcase import MAASTestCase29from maastesting.testcase import MAASTestCase
2630
2731
28def locate_maascli():
29 return os.path.join(root, 'bin', 'maas')
30
31
32class TestMAASCli(MAASTestCase):32class TestMAASCli(MAASTestCase):
3333
34 def run_command(self, *args):34 def run_command(self, *args):
35 check_output([locate_maascli()] + list(args), stderr=STDOUT)35 command = [sys.executable, "-m", "maascli"]
36 command.extend(args)
37 check_output(command, stderr=STDOUT, env=dict(
38 environ, PYTHONPATH=path.pathsep.join(sys.path)))
3639
37 def test_run_without_args_fails(self):40 def test_run_without_args_fails(self):
38 self.assertRaises(CalledProcessError, self.run_command)41 self.assertRaises(CalledProcessError, self.run_command)
3942
40 def test_run_without_args_shows_help_reminder(self):43 def test_run_without_args_shows_help_reminder(self):
41 self.output_file = self.make_file('output')44 script = path.realpath(maascli.__file__)
42 try:45 e = self.assertRaises(CalledProcessError, self.run_command)
43 self.run_command()
44 except CalledProcessError as e:
45 pass
46 self.assertIn(46 self.assertIn(
47 "Run %s --help for usage details." % locate_maascli(),47 "Run %s --help for usage details." % path.join(
48 path.dirname(script), "__main__.py"),
48 e.output)49 e.output)
4950
50 def test_help_option_succeeds(self):51 def test_help_option_succeeds(self):
5152
=== added file 'pkg/maas-client/packages.txt'
--- pkg/maas-client/packages.txt 1970-01-01 00:00:00 +0000
+++ pkg/maas-client/packages.txt 2014-07-28 15:42:36 +0000
@@ -0,0 +1,7 @@
1python-bzrlib
2python-django
3python-django-piston
4python-httplib2
5python-mock
6python-testtools
7python-twisted
08
=== added file 'pkg/maas-client/setup.py'
--- pkg/maas-client/setup.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-client/setup.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,197 @@
1#!/usr/bin/env python
2# Copyright 2013 Canonical Ltd. This software is licensed under the
3# GNU Affero General Public License version 3 (see the file LICENSE).
4
5"""Distutils installer for MAAS."""
6
7# unicode_literals is *not* included here to *better* support setup
8# scripts that work on both Python 2 and 3. Both expect their default
9# string type, and are fussy about it.
10from __future__ import (
11 absolute_import,
12 print_function,
13 )
14
15__version__ = "1.4"
16__metaclass__ = type
17
18
19from codecs import open
20from contextlib import contextmanager
21from distutils import (
22 errors,
23 log,
24 )
25from inspect import getsourcefile
26from operator import methodcaller
27from os import environ
28
29import setuptools
30
31
32@contextmanager
33def envvar(name, value):
34 """Context manager for temporarily setting an environment variable."""
35 original = environ.get(name)
36 environ[name] = value
37 try:
38 yield
39 finally:
40 if original is None:
41 environ.pop(name, None)
42 else:
43 environ[name] = original
44
45
46class install_deps(setuptools.Command):
47 """Distutils/setuptools command to install package dependencies."""
48
49 user_options = [
50 ('list-from=', None,
51 "file from which to read packages to install"),
52 ]
53
54 def initialize_options(self):
55 self.list_from = "packages.txt"
56
57 def gen_package_ops(self, package_lines):
58 install = methodcaller("mark_install")
59 delete = methodcaller("mark_delete", purge=True)
60 for line in package_lines:
61 if len(line) == 0:
62 pass # Ignore blank lines.
63 elif line.startswith("#"):
64 pass # Ignore whole-line comments.
65 elif line.endswith("-"):
66 package_name = line.rstrip("-")
67 yield package_name, delete
68 else:
69 package_name = line.rstrip("+")
70 yield package_name, install
71
72 def finalize_options(self):
73 self.ensure_filename("list_from")
74 self.packages = set()
75 with open(self.list_from, "r", encoding="utf-8") as fd:
76 lines = (line.strip() for line in fd)
77 self.package_ops = dict(self.gen_package_ops(lines))
78 self.packages = set(self.package_ops)
79
80 def run(self):
81 self.calculate_changes()
82 if len(self.changes) > 0:
83 self.apply_changes()
84
85 def calculate_changes(self):
86 from apt import Cache
87 cache = Cache()
88 for package_name, op in self.package_ops.iteritems():
89 op(cache[package_name])
90 self.changes = cache.get_changes()
91
92 def get_packages_to_install(self):
93 return self.packages.intersection(
94 package.name for package in self.changes
95 if package.marked_install or package.marked_upgrade)
96
97 def get_packages_to_delete(self):
98 return self.packages.intersection(
99 package.name for package in self.changes
100 if package.marked_delete)
101
102 def apply_changes(self):
103 """Use ``apt`` to check for package installs.
104
105 Spawns ``apt-get`` if necessary.
106 """
107 to_install = {
108 "%s+" % package
109 for package in self.get_packages_to_install()
110 }
111 if len(to_install) == 0:
112 log.info("system dependencies are all in place")
113
114 to_delete = {
115 "%s-" % package
116 for package in self.get_packages_to_delete()
117 }
118 if len(to_delete) == 0:
119 log.info("no forbidden system dependencies are installed")
120
121 to_do = sorted(to_install | to_delete)
122 if len(to_do) > 0:
123 install = [
124 "sudo", "apt-get", "--assume-yes",
125 "--no-install-recommends", "--purge",
126 "install",
127 ]
128 with envvar("DEBIAN_FRONTEND", "noninteractive"):
129 self.spawn(install + to_do)
130
131
132def check_settings(settings):
133 """Check setup settings for obvious issues.
134
135 - ``data_files`` should not be specified; setuptools ignores it.
136
137 - ``include_package_data`` should not be specified; it has weird
138 behaviour in setuptools.
139 """
140 if "data_files" in settings:
141 raise errors.DistutilsOptionError(
142 "data_files is ignored by setuptools")
143 if "include_package_data" in settings:
144 raise errors.DistutilsOptionError(
145 "include_package_data does not work as you "
146 "might expect with setuptools")
147
148
149def setup(**kwargs):
150 """MAAS-specific setup function.
151
152 Determines sensible defaults for many parameters.
153 """
154 command_classes = {}
155
156 try:
157 import apt
158 except ImportError:
159 log.warn("apt not available (install 'python-apt'?)")
160 else:
161 command_classes["install_deps"] = install_deps
162 apt # Silence lint.
163
164 settings = {
165 "cmdclass": command_classes,
166 "packages": setuptools.find_packages(".", exclude={"common"}),
167 "version": __version__,
168 "maintainer": "Canonical",
169 "maintainer_email": "maas-devel@lists.launchpad.net",
170 "url": "https://launchpad.net/maas",
171 "license": "AGPLv3",
172 "test_loader": "maastesting.loader:MAASTestLoader",
173 "test_suite": ".",
174 "tests_require": {"maas-testing >= %s" % __version__},
175 }
176 settings.update(kwargs)
177 check_settings(settings)
178
179 return setuptools.setup(**settings)
180
181
182def configure(**settings):
183 """Create a new ``setup.py`` file in the currnet directory.
184
185 Uses the file in which this function is originally defined as a
186 template, adding on a call to ``setup`` with the given ``settings``.
187 """
188 check_settings(settings)
189 thisfile = getsourcefile(configure)
190 with open(thisfile, "r", encoding="utf-8") as fin:
191 template = fin.read()
192 with open("setup.py", "w", encoding="utf-8") as fout:
193 fout.write(template)
194 fout.write(b"\n\nsetup(**%r)\n" % settings)
195
196
197setup(**{'install_requires': ['bzr >= 2.6.0', 'httplib2 >= 0.8', 'maas-apiclient >= 1.4'], 'entry_points': {'console_scripts': set(['maas = maascli:main'])}, 'name': 'maas-client', 'tests_require': ['maas-testing >= 1.4', 'mock >= 1.0.1', 'testtools >= 0.9.32', 'twisted >= 13.0.0'], 'description': 'MAAS command-line client.'})
0198
=== added directory 'pkg/maas-cluster'
=== added file 'pkg/maas-cluster/MANIFEST.in'
--- pkg/maas-cluster/MANIFEST.in 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/MANIFEST.in 2014-07-28 15:42:36 +0000
@@ -0,0 +1,4 @@
1graft etc
2graft provisioningserver/specs
3graft scripts
4graft twisted
05
=== added file 'pkg/maas-cluster/Makefile'
--- pkg/maas-cluster/Makefile 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/Makefile 2014-07-28 15:42:36 +0000
@@ -0,0 +1,12 @@
1localdeps := maas-apiclient maas-testing
2
3# TODO: This duplicates what's in maas-develop.testing.entrypoints. The
4# latter is a better approach to ensuring that environment variables are
5# set for the test suite as a whole, but there's probably a better way
6# than either.
7test:: export DJANGO_SETTINGS_MODULE := provisioningserver.testing.djangosettings
8test:: export CELERY_CONFIG_MODULE := provisioningserver.testing.celeryconfig
9test:: export MAAS_CONFIG_DIR := $(abspath etc/maas)
10test:: export PYTHONPATH := $(MAAS_CONFIG_DIR):$(PYTHONPATH)
11
12include ../common/Makefile
013
=== added file 'pkg/maas-cluster/README.rst'
--- pkg/maas-cluster/README.rst 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/README.rst 2014-07-28 15:42:36 +0000
@@ -0,0 +1,6 @@
1-----------------------
2maas-cluster
3-----------------------
4
5Provisioning Server for MAAS Cluster Controllers, incorportating a TFTP
6server.
07
=== added symlink 'pkg/maas-cluster/common'
=== target is u'../common'
=== added file 'pkg/maas-cluster/configure.py'
--- pkg/maas-cluster/configure.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/configure.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,51 @@
1from common import (
2 __version__,
3 configure,
4 )
5
6
7configure(
8 name='maas-cluster',
9 description="MAAS Provisioning Server (part of a Cluster Controller).",
10 install_requires=[
11 "celery >= 2.5.3",
12 "crochet >= 1.0.0",
13 "formencode >= 1.2.4",
14 # "hivex >= 1.3.9", # Needs distutils packaging.
15 "lxml >= 3.2.0",
16 "maas-apiclient >= %s" % __version__,
17 "netaddr >= 0.7.7",
18 "netifaces >= 0.8",
19 "oops >= 0.0.10",
20 "oops-datedir-repo >= 0.0.15",
21 "oops-twisted >= 0.0.6",
22 "paramiko >= 1.10.1",
23 "pexpect >= 3.1",
24 # "pkg_resources >= 0.6.37", # Implicit.
25 # "pymongo >= 2.6", # Or bson >= 2.6 ???
26 "python-seamicroclient >= 0.1",
27 # "python-tx-tftp >= 0.1", # Needs distutils packaging.
28 "PyYAML >= 3.1.0",
29 "simplejson >= 3.3.0",
30 # "simplestreams >= 0.1.0", # Needs distutils packaging.
31 "tempita >= 0.5.1",
32 "twisted >= 13.0.0",
33 "txamqp >= 0.6.1",
34 "zope.interface >= 4.0.5",
35 ],
36 tests_require=[
37 "fixtures >= 0.3.8",
38 "maas-testing >= %s" % __version__,
39 "mock >= 1.0b1",
40 "rabbitfixture >= 0.3.5",
41 "testtools >= 0.9.32",
42 ],
43 entry_points={
44 "console_scripts": {
45 "maas-cluster-twistd = maascluster.entrypoints:twistd",
46 "maas-cluster-worker = maascluster.entrypoints:celeryd",
47 "maas-probe-dhcp = maascluster.entrypoints:probe_dhcp",
48 "maas-provision = maascluster.entrypoints:provision",
49 },
50 },
51)
052
=== added directory 'pkg/maas-cluster/etc'
=== added directory 'pkg/maas-cluster/etc/maas'
=== renamed file 'contrib/maas-cluster-http.conf' => 'pkg/maas-cluster/etc/maas/maas-cluster-http.conf'
=== renamed file 'etc/maas_cluster.conf' => 'pkg/maas-cluster/etc/maas/maas_cluster.conf'
=== renamed file 'contrib/maas_local_celeryconfig_cluster.py' => 'pkg/maas-cluster/etc/maas/maas_local_celeryconfig_cluster.py'
=== renamed file 'etc/maas/pserv.yaml' => 'pkg/maas-cluster/etc/maas/pserv.yaml'
=== added directory 'pkg/maas-cluster/etc/maas/templates'
=== renamed directory 'etc/maas/templates/dhcp' => 'pkg/maas-cluster/etc/maas/templates/dhcp'
=== renamed directory 'etc/maas/templates/dns' => 'pkg/maas-cluster/etc/maas/templates/dns'
=== renamed directory 'etc/maas/templates/power' => 'pkg/maas-cluster/etc/maas/templates/power'
=== renamed directory 'etc/maas/templates/pxe' => 'pkg/maas-cluster/etc/maas/templates/pxe'
=== renamed directory 'etc/maas/templates/uefi' => 'pkg/maas-cluster/etc/maas/templates/uefi'
=== renamed directory 'etc/maas/templates/windows' => 'pkg/maas-cluster/etc/maas/templates/windows'
=== added directory 'pkg/maas-cluster/maascluster'
=== added file 'pkg/maas-cluster/maascluster/__init__.py'
=== added file 'pkg/maas-cluster/maascluster/entrypoints.py'
--- pkg/maas-cluster/maascluster/entrypoints.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/maascluster/entrypoints.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,61 @@
1# Copyright 2014 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Entry-points for the MAAS Cluster."""
5
6from __future__ import (
7 absolute_import,
8 print_function,
9 unicode_literals,
10 )
11
12str = None
13
14__metaclass__ = type
15__all__ = [
16 "celeryd",
17 "probe_dhcp",
18 "provision",
19 "twistd",
20]
21
22from os import environ
23
24from pkg_resources import (
25 load_entry_point,
26 Requirement,
27 resource_filename,
28 )
29
30
31def set_environment():
32 environ.setdefault(
33 "CELERY_CONFIG_MODULE",
34 "maascluster.worker.config")
35 environ.setdefault(
36 "MAAS_CONFIG_DIR", resource_filename(
37 Requirement.parse("maas-cluster"), "etc/maas"))
38
39
40def celeryd():
41 set_environment()
42 main = load_entry_point("celery", "console_scripts", "celeryd")
43 return main()
44
45
46def probe_dhcp():
47 set_environment()
48 from provisioningserver.dhcp.probe import main
49 return main()
50
51
52def provision():
53 set_environment()
54 from provisioningserver.__main__ import main
55 return main()
56
57
58def twistd():
59 set_environment()
60 from twisted.scripts.twistd import run
61 return run()
062
=== added directory 'pkg/maas-cluster/maascluster/worker'
=== added file 'pkg/maas-cluster/maascluster/worker/__init__.py'
=== renamed file 'etc/celeryconfig_cluster.py' => 'pkg/maas-cluster/maascluster/worker/config.py'
--- etc/celeryconfig_cluster.py 2014-02-25 13:38:27 +0000
+++ pkg/maas-cluster/maascluster/worker/config.py 2014-07-28 15:42:36 +0000
@@ -19,14 +19,14 @@
1919
20from datetime import timedelta20from datetime import timedelta
2121
22import celeryconfig_common22import maascluster.worker.config_base
23from provisioningserver.utils import import_settings23from provisioningserver.utils import import_settings
2424
25# Cluster UUID. Will be overridden by the customized setting in the25# Cluster UUID. Will be overridden by the customized setting in the
26# local MAAS Celery config.26# local MAAS Celery config.
27CLUSTER_UUID = None27CLUSTER_UUID = None
2828
29import_settings(celeryconfig_common)29import_settings(maascluster.worker.config_base)
3030
31try:31try:
32 import maas_local_celeryconfig_cluster32 import maas_local_celeryconfig_cluster
3333
=== renamed file 'etc/celeryconfig_common.py' => 'pkg/maas-cluster/maascluster/worker/config_base.py'
=== added file 'pkg/maas-cluster/packages.txt'
--- pkg/maas-cluster/packages.txt 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/packages.txt 2014-07-28 15:42:36 +0000
@@ -0,0 +1,36 @@
1distro-info
2dnsutils
3freeipmi-tools
4isc-dhcp-common
5isc-dhcp-server
6python-bson
7python-celery
8python-crochet
9python-fixtures
10python-formencode
11python-hivex
12python-librabbitmq-
13python-lxml
14python-mock
15python-netaddr
16python-netifaces
17python-oops
18python-oops-datedir-repo
19python-oops-twisted
20python-paramiko
21python-pexpect
22python-pkg-resources
23python-seamicroclient
24python-simplejson
25python-simplestreams
26python-tempita
27python-testtools
28python-twisted
29python-txamqp
30python-txtftp
31python-yaml
32python-zope.interface
33syslinux-common
34tgt
35ubuntu-cloudimage-keyring
36wget
037
=== renamed directory 'src/provisioningserver' => 'pkg/maas-cluster/provisioningserver'
=== modified file 'pkg/maas-cluster/provisioningserver/dhcp/tests/test_writer.py'
--- src/provisioningserver/dhcp/tests/test_writer.py 2014-03-28 04:36:31 +0000
+++ pkg/maas-cluster/provisioningserver/dhcp/tests/test_writer.py 2014-07-28 15:42:36 +0000
@@ -17,15 +17,12 @@
17from argparse import ArgumentParser17from argparse import ArgumentParser
18from io import BytesIO18from io import BytesIO
19import os19import os
20from subprocess import (20from subprocess import STDOUT
21 PIPE,
22 Popen,
23 )
24import sys21import sys
2522
26from maastesting import root
27from maastesting.testcase import MAASTestCase23from maastesting.testcase import MAASTestCase
28from provisioningserver.dhcp import writer24from provisioningserver.dhcp import writer
25from provisioningserver.utils import call_and_check
29from testtools.matchers import (26from testtools.matchers import (
30 ContainsAll,27 ContainsAll,
31 MatchesStructure,28 MatchesStructure,
@@ -50,12 +47,13 @@
50 )47 )
5148
52 def test_script_executable(self):49 def test_script_executable(self):
53 script = ["%s/bin/maas-provision" % root, "generate-dhcp-config"]50 script = [
51 sys.executable, "-m", "provisioningserver",
52 "generate-dhcp-config",
53 ]
54 script.extend(self.test_args)54 script.extend(self.test_args)
55 cmd = Popen(55 output = call_and_check(script, env=dict(
56 script, stdout=PIPE, env=dict(PYTHONPATH=":".join(sys.path)))56 os.environ, PYTHONPATH=os.path.pathsep.join(sys.path)))
57 output, err = cmd.communicate()
58 self.assertEqual(0, cmd.returncode, err)
59 contains_all_params = ContainsAll(57 contains_all_params = ContainsAll(
60 ['subnet', 'subnet-mask', 'broadcast-ip',58 ['subnet', 'subnet-mask', 'broadcast-ip',
61 'omapi-key', 'dns-servers', 'ntp-server', 'domain-name',59 'omapi-key', 'dns-servers', 'ntp-server', 'domain-name',
6260
=== modified file 'pkg/maas-cluster/provisioningserver/testing/bindfixture.py'
--- src/provisioningserver/testing/bindfixture.py 2014-06-30 14:08:34 +0000
+++ pkg/maas-cluster/provisioningserver/testing/bindfixture.py 2014-07-28 15:42:36 +0000
@@ -298,7 +298,7 @@
298 self.useFixture(self.runner)298 self.useFixture(self.runner)
299299
300300
301if __name__ == "__main__":301def main():
302 parser = argparse.ArgumentParser(description='Run a BIND server.')302 parser = argparse.ArgumentParser(description='Run a BIND server.')
303 parser.add_argument(303 parser.add_argument(
304 '--homedir',304 '--homedir',
@@ -338,3 +338,7 @@
338 os.execlp(338 os.execlp(
339 resources.named_file, resources.named_file, "-g", "-c",339 resources.named_file, resources.named_file, "-g", "-c",
340 resources.conf_file)340 resources.conf_file)
341
342
343if __name__ == "__main__":
344 main()
341345
=== added file 'pkg/maas-cluster/provisioningserver/testing/celeryconfig.py'
--- pkg/maas-cluster/provisioningserver/testing/celeryconfig.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/provisioningserver/testing/celeryconfig.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,49 @@
1# Copyright 2012 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Celery demo settings for the maas project: cluster settings."""
5
6from __future__ import (
7 absolute_import,
8 print_function,
9 unicode_literals,
10)
11
12str = None
13
14__metaclass__ = type
15
16
17import os
18
19import maascluster.worker.config
20from maastesting import root
21from pkg_resources import (
22 Requirement,
23 resource_filename,
24 )
25from provisioningserver.utils import import_settings
26
27# Extend base settings.
28import_settings(maascluster.worker.config)
29
30DNS_CONFIG_DIR = resource_filename(
31 Requirement.parse("maas-cluster"), "run/named")
32
33DNS_RNDC_PORT = 9154
34
35# In configuring RNDC, do not include the default "controls" statement that,
36# on a production system, would allow the init scripts to control the DNS
37# daemon. It would try to listen on port 953, which causes conflicts. (The
38# similar "controls" statement for the benefit of MAAS itself, on port 954,
39# will still be there).
40DNS_DEFAULT_CONTROLS = False
41
42DHCP_CONFIG_FILE = os.path.join(root, 'run/dhcpd.conf')
43
44DHCP_LEASES_FILE = os.path.join(root, 'run/dhcpd.leases')
45
46CELERYD_LOG_FILE = os.path.join(root, 'logs/cluster-worker/current')
47
48CELERYBEAT_SCHEDULE_FILENAME = os.path.join(
49 root, 'run/celerybeat-cluster-schedule')
050
=== added file 'pkg/maas-cluster/provisioningserver/testing/djangosettings.py'
--- pkg/maas-cluster/provisioningserver/testing/djangosettings.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/provisioningserver/testing/djangosettings.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,18 @@
1# Copyright 2012-2013 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Django settings for testing provisioningserver."""
5
6from __future__ import (
7 absolute_import,
8 print_function,
9 unicode_literals,
10 )
11
12str = None
13
14__metaclass__ = type
15
16
17SECRET_KEY = 'bogus secret key'
18DEBUG = True
019
=== modified file 'pkg/maas-cluster/provisioningserver/tests/test_config.py'
--- src/provisioningserver/tests/test_config.py 2014-07-16 14:12:13 +0000
+++ pkg/maas-cluster/provisioningserver/tests/test_config.py 2014-07-28 15:42:36 +0000
@@ -28,6 +28,10 @@
28from maastesting import root28from maastesting import root
29from maastesting.factory import factory29from maastesting.factory import factory
30from maastesting.testcase import MAASTestCase30from maastesting.testcase import MAASTestCase
31from pkg_resources import (
32 Requirement,
33 resource_filename,
34 )
31from provisioningserver.config import (35from provisioningserver.config import (
32 BootSources,36 BootSources,
33 Config,37 Config,
@@ -379,7 +383,8 @@
379383
380 def test_load_example(self):384 def test_load_example(self):
381 # The example configuration is designed for development.385 # The example configuration is designed for development.
382 filename = os.path.join(root, "etc", "maas", "pserv.yaml")386 filename = resource_filename(
387 Requirement.parse("maas-cluster"), "etc/maas/pserv.yaml")
383 self.assertEqual(388 self.assertEqual(
384 self.default_development_config,389 self.default_development_config,
385 Config.load(filename))390 Config.load(filename))
386391
=== modified file 'pkg/maas-cluster/provisioningserver/utils/tests/test_utils.py'
--- src/provisioningserver/utils/tests/test_utils.py 2014-07-18 15:44:55 +0000
+++ pkg/maas-cluster/provisioningserver/utils/tests/test_utils.py 2014-07-28 15:42:36 +0000
@@ -47,10 +47,7 @@
47 FakeLogger,47 FakeLogger,
48 )48 )
49from lxml import etree49from lxml import etree
50from maastesting import (50from maastesting import bindir
51 bindir,
52 root,
53 )
54from maastesting.factory import factory51from maastesting.factory import factory
55from maastesting.fakemethod import FakeMethod52from maastesting.fakemethod import FakeMethod
56from maastesting.matchers import (53from maastesting.matchers import (
@@ -62,6 +59,10 @@
62 Mock,59 Mock,
63 sentinel,60 sentinel,
64 )61 )
62from pkg_resources import (
63 Requirement,
64 resource_filename,
65 )
65import provisioningserver66import provisioningserver
66from provisioningserver.testing.testcase import PservTestCase67from provisioningserver.testing.testcase import PservTestCase
67import provisioningserver.utils68import provisioningserver.utils
@@ -134,7 +135,8 @@
134135
135def get_branch_dir(*path):136def get_branch_dir(*path):
136 """Locate a file or directory relative to this branch."""137 """Locate a file or directory relative to this branch."""
137 return os.path.abspath(os.path.join(root, *path))138 return resource_filename(
139 Requirement.parse("maas-cluster"), "/".join(path))
138140
139141
140class TestLocateConfig(MAASTestCase):142class TestLocateConfig(MAASTestCase):
141143
=== renamed directory 'scripts' => 'pkg/maas-cluster/scripts'
=== added file 'pkg/maas-cluster/setup.py'
--- pkg/maas-cluster/setup.py 1970-01-01 00:00:00 +0000
+++ pkg/maas-cluster/setup.py 2014-07-28 15:42:36 +0000
@@ -0,0 +1,197 @@
1#!/usr/bin/env python
2# Copyright 2013 Canonical Ltd. This software is licensed under the
3# GNU Affero General Public License version 3 (see the file LICENSE).
4
5"""Distutils installer for MAAS."""
6
7# unicode_literals is *not* included here to *better* support setup
8# scripts that work on both Python 2 and 3. Both expect their default
9# string type, and are fussy about it.
10from __future__ import (
11 absolute_import,
12 print_function,
13 )
14
15__version__ = "1.4"
16__metaclass__ = type
17
18
19from codecs import open
20from contextlib import contextmanager
21from distutils import (
22 errors,
23 log,
24 )
25from inspect import getsourcefile
26from operator import methodcaller
27from os import environ
28
29import setuptools
30
31
32@contextmanager
33def envvar(name, value):
34 """Context manager for temporarily setting an environment variable."""
35 original = environ.get(name)
36 environ[name] = value
37 try:
38 yield
39 finally:
40 if original is None:
41 environ.pop(name, None)
42 else:
43 environ[name] = original
44
45
46class install_deps(setuptools.Command):