Merge lp:~bloodearnest/canonical-identity-provider/sso-dev into lp:canonical-identity-provider/release

Proposed by Simon Davy
Status: Work in progress
Proposed branch: lp:~bloodearnest/canonical-identity-provider/sso-dev
Merge into: lp:canonical-identity-provider/release
Diff against target: 1052 lines (+803/-37)
16 files modified
.bzrignore (+5/-1)
Makefile (+162/-0)
Makefile.common (+35/-28)
Makefile.juju (+120/-0)
README.juju (+220/-0)
django_project/deploy.yaml (+25/-0)
django_project/paths.py (+3/-1)
django_project/settings_base.py (+1/-1)
django_project/settings_devel_juju.py (+54/-0)
django_project/ssh_config (+8/-0)
requirements_devel.txt (+1/-1)
run-tests-juju (+52/-0)
scripts/acceptance-dev-juju.sh (+66/-0)
scripts/setup-localmail.sh (+47/-0)
src/identityprovider/tests/test_command_cleanup.py (+4/-4)
src/webui/tests/test_views_ui.py (+0/-1)
To merge this branch: bzr merge lp:~bloodearnest/canonical-identity-provider/sso-dev
Reviewer Review Type Date Requested Status
Daniel Manrique (community) Approve
Review via email: mp+277474@code.launchpad.net

Description of the change

Merge juju dev work
Notes:

1) This MP supports side-by-side dev envs. The juju one is enabled with
   I_CAN_HAZ_JUJU=yes env var.

The following files are forks specific to juju dev env. When the juju dev
env becomes default, these will replace/merge with their original files.

./django_project/settings_acceptance_juju.py
./django_project/settings_devel_juju.py
./scripts/acceptance-dev-juju.sh
./run-tests-juju
./Makefile.juju
./README.juju

2) The charm is checked out into ../sso-charm, and then used to deploy.
   You can deploy a custom charm branch by specifying CHARM_BRANCH. The
   following directories are bind mounted into the container

   $PWD -> /srv/login.ubuntu.com/devel/code/devel
   $PWD/logs -> /srv/login.ubuntu.com/devel/logs
   $PWD/django_project -> /srv/login.ubuntu.com/devel/etc
   $HOME -> $HOME

   This means all logs will be available in ./logs, and the charm will
   generate it's config into ./django_project, for easy inspection. $HOME
   mounting is mainly for convienince.

3) bootstrap: this now effectively does two things, both separate make
   targets in their own right.

   make dependencies - this is what the old bootstrap did (venv, cfgmgr,
                       wheels, install), plus it now also installs system
                       packages.

   make deploy - this will setup juju repo and envoronemtn and deploy
                       sso, and is idempotent. If you are already deployed,
                       it's pretty fast.

   So, for getting set up first time, we still use make bootstrap. But once
   we're set up, we probably want to use make dependencies/deploy as needed,
   but bootstrap will still work.

   We shouldn't need to teardown the juju env often. If we do, make
   juju-destroy will do that, and deploy will create it again and deploy.

4) config has changed quite a bit to support developing with the charm, but
   has also simplified a lot in the process, for both the charm and sso
   trunk.

   - We use explicit DJANGO_SETTINGS_MODULE values, which is more in-line
     with normal django usage.

     e.g. DJANGO_SETTINGS_MODULE=django_project.settings_devel_juju

     This is exposed on the charm, and allows for explicit staging/prod
     settings (in other projects, anyway - sso doesn't use them because it's
     open source)

   - all these modules import from 'settings', which are the charm generated
     settings.

   - the symlink from django_project/settings.py to ../../local_settings is
     gone (along with related issues)

   - A developer can create and modify django_project/settings_local.py to
     modify settings in development - this file is bzrignored.

5) DB: postgres now runs as system postgres in the container, configured via
   the charm and very close to the old db dev config. The big difference is
   that it's not running on /dev/shm, as this added significant complexity
   for little benefit. Happy to revisit this if people find it an issue.

   So:

   - start-db/stop-db are gone as now obsolete
   - reset-db/setup-db are preserved, but are the same command - drop the db
     and recreate it, run migrations
   - have proposed db-setup/db-reset as better tab-completion friendly
     names, but kept old names too

6) gunicorn: now runs constantly as charm configured service in the
   container, on port 8080, like prod, but with code reloading enabled.

   - gunicorn logs are in ./logs dir
   - For debugging, use make run as before, It stops the system gunicorn,
     and then runs it manually in the foreground on the same port. It uses
     the same config, but timeout is increased and logging is directed to
     stdout. When you've finished debugging, it will start gunicorn again
     in the container.

7) localmail: this is now installed by default in the container, and the dev
   configuration uses it by default. No more need to manually start up an
   smtp server.

   - logs will be in ./logs/localmail.log
   - mbox file at ./logs/localmail.mbox
   - simple web view at port 8880 on container

8) acceptance tests have been simplified a lot in the process

 - in dev, we no longer need to run sso/localmail in screen - they are
   always running

 - all server and client side config for dev acceptance tests was moved to
   the default development config. This means no config changes are need
   to run acceptance tests against a local dev server. This involved changing the default test emails, so as not to leak it, and couple of test changes to match

   No need to juggle files or change the server config at all :)

 - For staging prod, we use an explicit config to run the tests

   DJANGO_SETTINGS_MOD=django_project.settings_acceptace_juju

 - the acceptance db setup was moved into the Makefile

9) The Makefiles has seen a lot of work. It is more complex that it needs to
   be, in order to support side-by-side dev envs, but that should only be
   temporary.

  - Makefile.common - the tasks that do sso stuff, shared between old and
    new dev environments.

  - Makefile.db - old env db tasks

  - Makefile - new entrypoint that sshs into container if needed, and houses
    the commands to manage the lxc. If using old env, it just includes
    Makefile.common and Makefile.db, and the old env's definition of run and
    bootstrap.

  - Makefile.juju - the new juju specific commands, mainly about charms and
    deploying.

  Once this work has fully landed, it is anticipated that we will return to
  just a single Makefile, which will include a base common ols Makefile as
  a dependency.

  I also added a make help command, since we'd discussed the idea before, and I was adding a whole bunch of new commands, so it seemed like a good plan

To post a comment you must log in.
Revision history for this message
Daniel Manrique (roadmr) wrote :

Awesome, thanks for this.

Maybe you want review by someone more familiar with all the makefile wizardry. In general it looks OK to me, the code looks sensible and the thing works very nicely (and I tried some uncommon scenarios). I made some minor comments below, mainly typos. There's one thing that may need clarification so I didn't "Approve" outright.

review: Needs Information
Revision history for this message
Simon Davy (bloodearnest) wrote :

Yeah, some of the makefile stuff is more complex that I'd like. Make is so good at many things, but it has some rough edges. I'm pretty comfortable with make, but I know not every one is. I'm hoping vila might spot some improvements I can make.

Are there any specific bits which look too much like magic?

Revision history for this message
Simon Davy (bloodearnest) wrote :

I've fixed the various typos too.

Revision history for this message
Daniel Manrique (roadmr) wrote :

+1 from me but don't forget to add a commit message :)

As for the makefile, nothing looks *too* magical, it's just unfamiliar due to rustiness with Makefiles. Maybe the way targets.mk is generated, but tbh I haven't looked at it too closely and it works anyway \o/.

review: Approve
Revision history for this message
Simon Davy (bloodearnest) wrote :
1366. By Simon Davy

add comment about order-only make pre-requisites

Revision history for this message
Ricardo Kirkner (ricardokirkner) :
Revision history for this message
Simon Davy (bloodearnest) :
1367. By Simon Davy

- whitespace
- remove unneeded sessionid config

1368. By Simon Davy

re-add missing SSH_ARGS

1369. By Simon Davy

 - add ssh_config file to avoid unwieldy cli args
 - fix location of .juju-repo

1370. By Simon Davy

clean up juju repo

Revision history for this message
Natalia Bidart (nataliabidart) :
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

One more question, I ran:

$ make lint
make: /home/nessita/canonical/bloodearnest/sso-dev/env/bin/flake8: Command not found
Makefile.common:152: recipe for target 'lint' failed

any idea what is missing?

Revision history for this message
Simon Davy (bloodearnest) wrote :
Download full text (11.2 KiB)

On Tue, Nov 17, 2015 at 3:18 PM, Natalia Bidart
<email address hidden> wrote:
>
>
> Diff comments:
>
>>
>> === renamed file 'Makefile' => 'Makefile.common'
>> --- Makefile 2015-11-12 17:08:24 +0000
>> +++ Makefile.common 2015-11-17 13:23:47 +0000
>> @@ -1,9 +1,9 @@
>> -# Copyright (C) 2014 Canonical Ltd.
>> -
>> +# Copyright (C) 2014 Canonical Ltd.
>
> Since you are editing this file, would you mind updating the Copyright notice to 2014-2015?

Done

>> +#
>> CM ?= /usr/lib/config-manager/cm.py
>> CONFIGMANAGER = config-manager.txt
>> CONN_CHECK_CONFIG_PATH ?= /tmp/sso_conn_check_config.yaml
>> -DJANGO_SETTINGS_MODULE = settings
>> +DJANGO_SETTINGS_MODULE ?= settings
>> ENV = $(CURDIR)/env
>> JUJU_ENV ?= local
>> JUJU_REPO ?= ../.juju-repo
>> @@ -42,27 +42,32 @@
>> $(TARBALL_BUILD_DIR):
>> @mkdir -p $(TARBALL_BUILD_DIR)
>>
>> +## run django's collectstatic command, STATIC_ROOT defaults to ./staticfiles
>> collectstatic:
>> # this uses a modified collectstatic command, called linkstatic, where the
>> # --link option uses relative urls, so save space when tarballed
>> @DJANGO_SETTINGS_MODULE=django_project.settings_build $(DJANGO_MANAGE) linkstatic --noinput --link
>>
>> +## create a pre-gzipped version of static text assets
>> zipstatic:
>> @echo Gzipping static asset files...
>> @find $(STATIC_ROOT) -name \*.js -or -name \*.css -or -name \*.svg | xargs gzip -kf
>>
>> -# variation of compilemessages target that uses settings_build
>> +## variation of compilemessages target that uses settings_build
>> compilemessages-build:
>> @DJANGO_SETTINGS_MODULE=django_project.settings_build $(MAKE) compilemessages
>>
>> # note: fetch-sourcedeps needs to be manually called before this will work.
>> +## build a deployment tarbal
>
> Typo here? tarball

Fixed

>> build-tarball: install-wheels $(TARBALL_BUILD_PATH)
>>
>> +## write the bzr revno to lib/versioninfo.py
>> version:
>> bzr version-info --format=python > lib/versioninfo.py
>>
>> ### Wheels ###
>>
>> +## create/reinitialise the virtualenv
>> virtualenv:
>> @virtualenv --clear --system-site-packages $(ENV)
>>
>>
>> === added file 'Makefile.juju'
>> --- Makefile.juju 1970-01-01 00:00:00 +0000
>> +++ Makefile.juju 2015-11-17 13:23:47 +0000
>> @@ -0,0 +1,124 @@
>> +# sso specific config
>> +CHARM_SERIES = trusty
>> +CHARM = canonical-identity-provider
>> +CHARM_BRANCH = lp:~ubuntuone-pqm-team/canonical-is-charms/canonical-identity-provider
>> +CHARM_SRC = ../sso-charm
>> +DEPLOYER_CONFIG = $(CURDIR)/django_project/deploy.yaml
>> +DEPLOYER_TARGET = sso-app-dev
>> +
>> +# generic config
>> +LOG_DIRS ?= ./logs/www-oops ./logs/schema-updates
>> +ABS_CHARM_SRC = $(shell readlink -f $(CHARM_SRC))
>> +LOCAL_JUJU_CONFIG = .local.yaml
>> +JUJU_REPOSITORY ?= $(CURDIR)/.juju-repo
>> +JUJU_HOME ?= $(HOME)/.juju
>> +JENV = $(JUJU_HOME)/environments/$(JUJU_ENV).jenv
>> +export JUJU_REPOSITORY JUJU_ENV
>> +export I_CAN_HAZ_JUJU=yes
>> +
>> +# python config, overriding the non-juju config
>> +PYTHONPATH := $(LXC_BASEDIR)/etc:$(SRC_DIR):$(LIB_DIR):$(CURDIR)
>> +export PYTHONPATH
>> +
>> +
>> +
>> +$(CHARM_SRC):
>> + @bzr branch $...

Revision history for this message
Simon Davy (bloodearnest) wrote :

On Tue, Nov 17, 2015 at 3:18 PM, Natalia Bidart
<email address hidden> wrote:
> One more question, I ran:
>
> $ make lint
> make: /home/nessita/canonical/bloodearnest/sso-dev/env/bin/flake8: Command not found
> Makefile.common:152: recipe for target 'lint' failed
>
> any idea what is missing?

Assuming you've bootstrapped (or just make dependencies), not sure. I
haven;t altered any of the dev deps or make targets beyond bootrstrap
(which is now dependecnies) and make run.

It works for me here.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

More errors. On the host, on a sso-dev clean branch, I tried:

nessita@dali:~/canonical/bloodearnest/sso-dev$ export I_CAN_HAZ_JUJU=yes
nessita@dali:~/canonical/bloodearnest/sso-dev$ make clean
(Makefiles changed - rebuilding lxc target list)
unknown option -- -
usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-E log_file] [-e escape_char]
           [-F configfile] [-I pkcs11] [-i identity_file]
           [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]
           [-O ctl_cmd] [-o option] [-p port]
           [-Q cipher | cipher-auth | mac | kex | key]
           [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port]
           [-w local_tun[:remote_tun]] [user@]hostname [command]
Makefile:106: recipe for target 'clean' failed
make: *** [clean] Error 255

The main issue I see with this errors is that I have no idea what is going on, nor I can debug in a easy way.

Revision history for this message
Simon Davy (bloodearnest) wrote :

On Tue, Nov 17, 2015 at 9:05 PM, Natalia Bidart
<email address hidden> wrote:
> More errors. On the host, on a sso-dev clean branch, I tried:
>
> nessita@dali:~/canonical/bloodearnest/sso-dev$ export I_CAN_HAZ_JUJU=yes
> nessita@dali:~/canonical/bloodearnest/sso-dev$ make clean
> (Makefiles changed - rebuilding lxc target list)
> unknown option -- -
> usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
> [-D [bind_address:]port] [-E log_file] [-e escape_char]
> [-F configfile] [-I pkcs11] [-i identity_file]
> [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]
> [-O ctl_cmd] [-o option] [-p port]
> [-Q cipher | cipher-auth | mac | kex | key]
> [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port]
> [-w local_tun[:remote_tun]] [user@]hostname [command]
> Makefile:106: recipe for target 'clean' failed
> make: *** [clean] Error 255

Hmm, this suggests your lxd is not set up correctly, it doesn't have
an IP currently.

The ssh command is on line 106:

@ssh -qtAF $(SSH_CONFIG_FILE) $(IP) -- $(MAKE) $(LXC_MAKE_FLAGS) -C
$(PWD) $@ $(LXC_MAKE_VARS)

I suspect the issue is that the $(IP) is coming out as empty, which is
confusing ssh

I will try and add an explicit check for an IP address, with suitable
error message. Previously, I have just been checking the container was
created, not also a) it was running and b) it has an IP address, which
are all things that are required so ssh in, but can fail.

Additionally, clean should be able to be run from host without ssh,
which I will fix

Would echoing the ssh command by default be better? It would make
things clearer in case of error, but at the expense of largely
irrelevant line noise on most command output.

--

Thanks

1371. By Simon Davy

 - make clean now works in host w/o ssh
 - add explicit check for IP address for better error messages

Revision history for this message
Simon Davy (bloodearnest) wrote :

On Wed, Nov 18, 2015 at 10:34 AM, Simon Davy <email address hidden> wrote:
> On Tue, Nov 17, 2015 at 9:05 PM, Natalia Bidart
> <email address hidden> wrote:
>> More errors. On the host, on a sso-dev clean branch, I tried:
>>
>> nessita@dali:~/canonical/bloodearnest/sso-dev$ export I_CAN_HAZ_JUJU=yes
>> nessita@dali:~/canonical/bloodearnest/sso-dev$ make clean
>> (Makefiles changed - rebuilding lxc target list)
>> unknown option -- -
>> usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
>> [-D [bind_address:]port] [-E log_file] [-e escape_char]
>> [-F configfile] [-I pkcs11] [-i identity_file]
>> [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]
>> [-O ctl_cmd] [-o option] [-p port]
>> [-Q cipher | cipher-auth | mac | kex | key]
>> [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port]
>> [-w local_tun[:remote_tun]] [user@]hostname [command]
>> Makefile:106: recipe for target 'clean' failed
>> make: *** [clean] Error 255
>
> Hmm, this suggests your lxd is not set up correctly, it doesn't have
> an IP currently.
>
> The ssh command is on line 106:
>
> @ssh -qtAF $(SSH_CONFIG_FILE) $(IP) -- $(MAKE) $(LXC_MAKE_FLAGS) -C
> $(PWD) $@ $(LXC_MAKE_VARS)
>
> I suspect the issue is that the $(IP) is coming out as empty, which is
> confusing ssh
>
> I will try and add an explicit check for an IP address, with suitable
> error message.

Done. If it can't find an IP address for the container, any command
that needs ssh will fail with a more helpful error.

Another option would be to auto-start the container it its not started, perhaps?

--
Simon

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

I pulled the changes. A run of make clean without the env var and I run with it both succeded with the same output:

nessita@dali:~/canonical/bloodearnest/sso-dev$ make clean
rm -rf /home/nessita/canonical/bloodearnest/sso-dev/env
rm -rf branches/wheels
rm -rf ../.juju-repo
rm -rf branches/*
rm -rf logs/*.*
rm -rf staticfiles
rm -f lib/versioninfo.py
rm -f targets.mk
find -name '*.pyc' -delete
find -name '*.~*' -delete
nessita@dali:~/canonical/bloodearnest/sso-dev$ export I_CAN_HAZ_JUJU=yes
nessita@dali:~/canonical/bloodearnest/sso-dev$ make clean
(Makefiles changed - rebuilding lxc target list)
rm -rf
rm -rf
rm -rf
rm -rf branches/*
rm -rf logs/*.*
rm -rf staticfiles
rm -f lib/versioninfo.py
rm -f targets.mk
find -name '*.pyc' -delete
find -name '*.~*' -delete
nessita@dali:~/canonical/bloodearnest/sso-dev$

Were you expecting this or there is some randomness around? What confuses me is that I don't see the container in my list of containers:

nessita@dali:~/canonical/bloodearnest/sso-dev$ sudo lxc-ls --fancy
NAME STATE IPV4 IPV6 GROUPS AUTOSTART
----------------------------------------------------------------
cpi-trusty STOPPED - - - NO
juju-trusty-lxc-template STOPPED - - - NO
sca-trusty STOPPED - - - NO
sso-trusty STOPPED - - - NO

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Replying to:

"FWIW: that script is just:

#!/bin/bash
sudo service gunicorn stop
trap 'sudo service gunicorn start' INT
bash /srv/gunicorn/run_sso_wsgi.sh $@

We could actually get rid of this, perhaps. Some thing like:

run: gunicorn-stop
    @trap 'sudo service gunicorn start' INT;
/srv/gunicorn/run_sso_wsgi.sh --bind=$(ARGS) --reload
--error-logfile=- --access-logfile=- --timeout=99999

would probably work. I can have a look at that if you've prefer to get
rid of the script?"

I would prefer to get rid of the script mainly because having the script mean that when reading the Makefile it requires to go an open other script in other folder; and also sometimes I try to cleanup stuff and is not trivial to know where a script is used or not, to decide if it can be removed.

Revision history for this message
Simon Davy (bloodearnest) wrote :

On Wed, Nov 18, 2015 at 12:15 PM, Natalia Bidart
<email address hidden> wrote:
> I pulled the changes. A run of make clean without the env var and I run with it both succeded with the same output:
>
> nessita@dali:~/canonical/bloodearnest/sso-dev$ make clean
> rm -rf /home/nessita/canonical/bloodearnest/sso-dev/env
> rm -rf branches/wheels
> rm -rf ../.juju-repo
> rm -rf branches/*
> rm -rf logs/*.*
> rm -rf staticfiles
> rm -f lib/versioninfo.py
> rm -f targets.mk
> find -name '*.pyc' -delete
> find -name '*.~*' -delete
> nessita@dali:~/canonical/bloodearnest/sso-dev$ export I_CAN_HAZ_JUJU=yes
> nessita@dali:~/canonical/bloodearnest/sso-dev$ make clean
> (Makefiles changed - rebuilding lxc target list)
> rm -rf
> rm -rf
> rm -rf
> rm -rf branches/*
> rm -rf logs/*.*
> rm -rf staticfiles
> rm -f lib/versioninfo.py
> rm -f targets.mk
> find -name '*.pyc' -delete
> find -name '*.~*' -delete
> nessita@dali:~/canonical/bloodearnest/sso-dev$
>
> Were you expecting this or there is some randomness around?

This is correct. Most make targets are unaltered and shared between
old and new dev envs

> What confuses me is that I don't see the container in my list of containers:
>
> nessita@dali:~/canonical/bloodearnest/sso-dev$ sudo lxc-ls --fancy
> NAME STATE IPV4 IPV6 GROUPS AUTOSTART
> ----------------------------------------------------------------
> cpi-trusty STOPPED - - - NO
> juju-trusty-lxc-template STOPPED - - - NO
> sca-trusty STOPPED - - - NO
> sso-trusty STOPPED - - - NO

lxd and lxc containers are differently managed. Try

lxc list

FYI lxd containers are in /var/lib/lxd/containers, not /var/lib/lxc

--
Simon

Revision history for this message
Simon Davy (bloodearnest) wrote :

On Wed, Nov 18, 2015 at 12:24 PM, Natalia Bidart
<email address hidden> wrote:
> Replying to:
>
> "FWIW: that script is just:
>
> #!/bin/bash
> sudo service gunicorn stop
> trap 'sudo service gunicorn start' INT
> bash /srv/gunicorn/run_sso_wsgi.sh $@
>
> We could actually get rid of this, perhaps. Some thing like:
>
> run: gunicorn-stop
> @trap 'sudo service gunicorn start' INT;
> /srv/gunicorn/run_sso_wsgi.sh --bind=$(ARGS) --reload
> --error-logfile=- --access-logfile=- --timeout=99999
>
> would probably work. I can have a look at that if you've prefer to get
> rid of the script?"
>
> I would prefer to get rid of the script mainly because having the script mean that when reading the Makefile it requires to go an open other script in other folder; and also sometimes I try to cleanup stuff and is not trivial to know where a script is used or not, to decide if it can be removed.

Ok, I will try this approach.

--
Simon

1372. By Simon Davy

- remove scripts/run_gunicorn.sh, handle trap in makefile instead
- deploy target now has dependencies as a prerequisite
- removed docs about deploy/dependencies targets to avoid confusion - bootstrap should be the main one
- auto matically update the sso-charm to latest on deploy

Revision history for this message
Natalia Bidart (nataliabidart) wrote :
Download full text (26.8 KiB)

Thank you for all the answers and improvements. I tried a new run from scratch, issuing:

$ make lxc-delete
$ make clean

$ make lxc-setup
Using saved parent location: bzr+ssh://bazaar.launchpad.net/~bloodearnest/+junk/ols-tools/
No revisions or tags to pull.
./branches/ols-tools/setup-devel-lxd sso /srv/login.ubuntu.com/devel
Using lxc sso
Checking ssh key set up...done
Setting up posgtresql init on /dev/shm on boot...done
Device .home removed from sso
Device .src removed from sso
Device .logs removed from sso
Device .etc removed from sso
Device .home added to sso
Device .src added to sso
Device .logs added to sso
Device .etc added to sso
Creating fake tarball...done.
Setting up nessita for passwordless sudo...done.
Removing landscape-common...done.
Checking for network access...done.
Updating package index...done.
Installing ppa deps...done.
Installing juju stable ppa...done.
Updating package index (again)...done.
Updating system packages...done.
Installing required packages...done.
Cleaning up packages...done.
Configuring lxc sshd...done.
Restarting ssh...done.
Updating sso juju environment to use lxc ip 10.0.3.41
Checking for basenode access...done
Checking for CAT access...done.
Updating basenode...done.
Installing basenode...done.

And then make bootstrap, which fails as follow (I'm connected to the VPN):

nessita@dali:~/canonical/bloodearnest/sso-dev$ make bootstrap
cat dependencies.txt | xargs sudo apt-get install -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
python-amqplib is already the newest version.
python-bson is already the newest version.
python-iso8601 is already the newest version.
python-launchpadlib is already the newest version.
python-m2crypto is already the newest version.
python-memcache is already the newest version.
python-psutil is already the newest version.
python-psycopg2 is already the newest version.
python-simplejson is already the newest version.
python-testresources is already the newest version.
python-bcrypt is already the newest version.
python-beautifulsoup is already the newest version.
python-virtualenv is already the newest version.
bzr is already the newest version.
python-lxml is already the newest version.
python-tz is already the newest version.
python-yaml is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
cat dependencies-devel.txt | xargs sudo apt-get install -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
build-essential is already the newest version.
libxslt1-dev is already the newest version.
make is already the newest version.
memcached is already the newest version.
python-dev is already the newest version.
screen is already the newest version.
swig is already the newest version.
config-manager is already the newest version.
firefox is already the newest version.
gettext is already the newest version.
libpq-dev is already the newest version.
libxml2-dev is already the newest version.
postgresql-client-9.3 is already the newest version.
postgresql-contrib-9....

1373. By Simon Davy

 - fix jenv file not being delete
 - fix LXC_MAKE_ARGS partial rename
 - run db-reset on lxc-start, to cope with shared memory

Revision history for this message
Simon Davy (bloodearnest) wrote :

>> === modified file 'src/identityprovider/tests/test_command_cleanup.py'
>> --- src/identityprovider/tests/test_command_cleanup.py 2015-04-30 17:20:09 +0000
>> +++ src/identityprovider/tests/test_command_cleanup.py 2015-11-17 13:23:47 +0000
>> @@ -48,8 +48,8 @@
>>
>> def make_test_accounts(self, count=0, date_created=None):
>> for i in xrange(count):
>> - email = self.factory.make_email_address(prefix='isdtest+',
>> - domain='canonical.com')
>> + email = self.factory.make_email_address(prefix='testemail+',
>> + domain='example.com')
>
> What's the rationale for this change? The job needs to clear from the DB all email addressed created by the acceptance tests, which use the isdtest+ prefix, so changing it will not trigger the right cleanup.

So, one of the things I tried to do was "normalise" the dev acceptance
test configuration, so it could just be part default devel
configuration. This would mean that a) you wouldn't need access to the
config branch to run acceptance tests and b) could run the acceptance
tests against the dev server OOTB with no config changes, which
simplified stuff a lot.

The only thing in the *dev* acceptance settings that was at all
sensitive was the isdtest email stuff, as it might leak info about our
production config.

Now, the isdtest email stuff was already in the code base anyway (like
in the above test), but I went ahead an made the default dev config
use <email address hidden>, and updated some tests that were expecting
other config.

I don't *think* this will have broken the clean up job, as that uses
the configured emails, which are unchanged in prod or staging.

But maybe I missed something?

--
Thanks

1374. By Simon Davy

make clean now works properly again

1375. By Simon Davy

merging

Revision history for this message
Daniel Manrique (roadmr) wrote :

Poke... what's the status on this? Simon, could I at least request, if feasible, for you to merge trunk into this? I did so but there was a (minor) conflict, I think I solved it well enough that my local copy is working but I'd be more at ease if I knew you did the right thing while merging :)

The actual reason I'm asking is this: I tried running acceptance tests in my old-style lxc setup and failed miserably. The set of config directives I used to just inject in my ../local_config/settings.py no longer "just works", and after spending a couple of hours trying, I gave up and decided to give sso-dev another whirl. Acceptance tests worked magically out of the box. So I'm wondering if perhaps the work done to remove the settings-by-symlink workflow broke the old way of doing acceptance testing.

Does this make sense to you? What do I need to do now in order to run acceptance tests locally? OTOH if it's easier to just use sso-dev, that's fair enough, but we'd need to push for this to land so that people wanting to run acceptance aren't left in the same limbo as me (or I was just being extra dumb today - always a possibility, particularly on Mondays).

Thanks and apologies for the rant!

1376. By Simon Davy

merging

Revision history for this message
Simon Davy (bloodearnest) wrote :

On Mon, Dec 7, 2015 at 10:37 PM, Daniel Manrique
<email address hidden> wrote:
> Poke... what's the status on this? Simon, could I at least request, if feasible, for you to merge trunk into this?

Done. All tests passing.

> I did so but there was a (minor) conflict, I think I solved it well enough that my local copy is working but I'd be more at ease if I knew you did the right thing while merging :)

Yep, it was just bzr merge failing hard on trivial changes, for
unknown reasons :)

> The actual reason I'm asking is this: I tried running acceptance tests in my old-style lxc setup and failed miserably. The set of config directives I used to just inject in my ../local_config/settings.py no longer "just works", and after spending a couple of hours trying, I gave up and decided to give sso-dev another whirl. Acceptance tests worked magically out of the box. So I'm wondering if perhaps the work done to remove the settings-by-symlink workflow broke the old way of doing acceptance testing.

Hmm, it shouldn't have. ../local_config/settings.py is still used, but
just via PYTHONPATH, not a symlink. I did test the acceptances tests
with that change, with out issue. I will try again.

However, the old way of running acceptance tests (via run-tests and
scripts/acceptance-tests) mv's ../local_config/settings.py out of the
way, writes its own version there, runs the server and tests, and then
copies back your old settings.py. So, to my knowledge, you've never
been able to manually tweak ../local_config/settings.py when running
tests this way.

However, if you run the server yourself manually, and run the tests
separately with make run-acceptance, then your local settings.py is
used (and you'll need to have the acceptance relations

The sso-dev work removes all this complexity. The is now no difference
between devel settings and the acceptance tests settings, so no file
mv'ing needed. It also already has an sso server and mail server
running, so everything is much simpler when it comes to running

> Does this make sense to you? What do I need to do now in order to run acceptance tests locally? OTOH if it's easier to just use sso-dev, that's fair enough, but we'd need to push for this to land so that people wanting to run acceptance aren't left in the same limbo as me (or I was just being extra dumb today - always a possibility, particularly on Mondays).

I would like to land, but still waiting on review approval, there's
some outstanding comments. I will ask Natalia to have a look again.

> Thanks and apologies for the rant!

No worries - sorry it's not landed yet :(

--
Simon

Revision history for this message
Simon Davy (bloodearnest) wrote :

On Tue, Dec 8, 2015 at 11:18 AM, Simon Davy <email address hidden> wrote:
> On Mon, Dec 7, 2015 at 10:37 PM, Daniel Manrique
> <email address hidden> wrote:
>> Poke... what's the status on this? Simon, could I at least request, if feasible, for you to merge trunk into this?
>
> Done. All tests passing.
>
>> I did so but there was a (minor) conflict, I think I solved it well enough that my local copy is working but I'd be more at ease if I knew you did the right thing while merging :)
>
> Yep, it was just bzr merge failing hard on trivial changes, for
> unknown reasons :)
>
>> The actual reason I'm asking is this: I tried running acceptance tests in my old-style lxc setup and failed miserably. The set of config directives I used to just inject in my ../local_config/settings.py no longer "just works", and after spending a couple of hours trying, I gave up and decided to give sso-dev another whirl. Acceptance tests worked magically out of the box. So I'm wondering if perhaps the work done to remove the settings-by-symlink workflow broke the old way of doing acceptance testing.
>
> Hmm, it shouldn't have. ../local_config/settings.py is still used, but
> just via PYTHONPATH, not a symlink. I did test the acceptances tests
> with that change, with out issue. I will try again.

Using ./run-tests dev, the acceptance tests ran fine for me on r1374

Thanks

--
Simon

1377. By Simon Davy

merging properly this time

Revision history for this message
Daniel Manrique (roadmr) wrote :

Argh, so I did ./run-tests dev (note, using trunk, not sso-dev) and it still won't run acceptance :( (r1376 here).

What I'm seeing is that ./run-tests dev starts by unconditionally bootstrapping, which I think destroys my ../local_config/settings.py, so by the time the acceptance tests start, the config is all borked and obviously they fail.

No worries though, I have a reasonable workaround by using sso-dev whenever I need acceptance tests run ;) (which is not often, really).

1378. By Simon Davy

merging

1379. By Simon Davy

merging

Revision history for this message
Daniel Manrique (roadmr) wrote :

Ohnoes... here comes Daniel with more crazy problems...

Apparently once the container is shut down and restarted, part of the db configuration changes, so on next boot it fails with (ultimately) this:

django.db.utils.OperationalError: FATAL: password authentication failed for user "ssoadmin"

How to repro (I_CAN_HAZ_JUJU assumed to be set at all times):

(maybe delete any old sso containers with lxc delete)
(set up my crazy /src mount in the ols-dev profile)
get a checkout of sso-dev
merge latest trunk (I did this myself, maybe I screwed up?)
make lxc-setup
make bootstrap
ssh into container, change to /src/blahblah/sso-dev dir
make test ARGS=some.quick.test
*it works*
sudo poweroff (the container!)
lxc start sso
wait until juju stabilizes (on startup a series of config-changeds fire up)
ssh into container, change to /src/blahblah/sso-dev dir
make test ARGS=some.quick.test
* now it fails with the above-shown message *

Logging out of the container and redoing "make bootstrap" from the host brings things to a working state again, but I seem to recall this shouldn't be necessary.

Revision history for this message
Simon Davy (bloodearnest) wrote :

On Wed, Jan 6, 2016 at 10:16 PM, Daniel Manrique
<email address hidden> wrote:
> Ohnoes... here comes Daniel with more crazy problems...
>
> Apparently once the container is shut down and restarted, part of the db configuration changes, so on next boot it fails with (ultimately) this:
>
> django.db.utils.OperationalError: FATAL: password authentication failed for user "ssoadmin"
>
> How to repro (I_CAN_HAZ_JUJU assumed to be set at all times):
>
>
> (maybe delete any old sso containers with lxc delete)
> (set up my crazy /src mount in the ols-dev profile)
> get a checkout of sso-dev
> merge latest trunk (I did this myself, maybe I screwed up?)
> make lxc-setup
> make bootstrap
> ssh into container, change to /src/blahblah/sso-dev dir
> make test ARGS=some.quick.test
> *it works*
> sudo poweroff (the container!)
> lxc start sso
> wait until juju stabilizes (on startup a series of config-changeds fire up)
> ssh into container, change to /src/blahblah/sso-dev dir
> make test ARGS=some.quick.test
> * now it fails with the above-shown message *
>
> Logging out of the container and redoing "make bootstrap" from the host brings things to a working state again, but I seem to recall this shouldn't be necessary.

It shouldn't. I will look into it, and merge trunk in the process

FYI, there are lxc-start and lxc-stop make commands which I would
encourage rather than sudo poweroff

--
Simon

1380. By Simon Davy

merging

1381. By Simon Davy

merging

1382. By Simon Davy

merging

1383. By Simon Davy

fix some small issues from user testing

Revision history for this message
Daniel Manrique (roadmr) wrote :

Hello :)

Unmerged revisions

1383. By Simon Davy

fix some small issues from user testing

1382. By Simon Davy

merging

1381. By Simon Davy

merging

1380. By Simon Davy

merging

1379. By Simon Davy

merging

1378. By Simon Davy

merging

1377. By Simon Davy

merging properly this time

1376. By Simon Davy

merging

1375. By Simon Davy

merging

1374. By Simon Davy

make clean now works properly again

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2015-10-09 16:03:29 +0000
+++ .bzrignore 2016-03-04 19:06:06 +0000
@@ -7,4 +7,8 @@
7node_modules7node_modules
8staticfiles8staticfiles
9lib/versioninfo.py9lib/versioninfo.py
10settings.py10.juju-repo
11EXTRACTED
12django_project/settings.py
13django_project/settings_local.py
14targets.mk
1115
=== added file 'Makefile'
--- Makefile 1970-01-01 00:00:00 +0000
+++ Makefile 2016-03-04 19:06:06 +0000
@@ -0,0 +1,162 @@
1.DEFAULT_GOAL = help
2# disable builtin rules, which are not used
3.SUFFIXES:
4
5
6# sso specific config
7SSO_LXC ?= sso
8# base dir inside lxc
9LXC_BASEDIR = /srv/login.ubuntu.com/devel
10CODE_DIR=$(LXC_BASEDIR)/code/devel
11
12# shared config between all dev envs
13WHEELS_BRANCH_URL ?= lp:~ubuntuone-pqm-team/$(PROJECT_NAME)/dependencies
14WHEELS_DIR = branches/wheels
15ENV = $(CURDIR)/env
16
17# commands that can be run on host or container
18clean:
19 rm -rf $(ENV)
20 rm -rf $(WHEELS_DIR)
21 rm -rf $(JUJU_REPOSITORY)
22 rm -rf branches/*
23 rm -rf logs/*.*
24 rm -rf staticfiles
25 rm -f lib/versioninfo.py
26 rm -f targets.mk
27 find -name '*.pyc' -delete
28 find -name '*.~*' -delete
29
30
31ifeq ("$(I_CAN_HAZ_JUJU)","yes")
32
33LXC_NAME = $(SSO_LXC)
34JUJU_ENV = $(LXC_NAME)
35JUJU_HOME ?= $(HOME)/.juju
36JENV = $(JUJU_HOME)/environments/$(JUJU_ENV).jenv
37JUJU_REPOSITORY ?= $(CURDIR)/.juju-repo
38JUJU_HOME ?= $(HOME)/.juju
39export JUJU_REPOSITORY JUJU_ENV
40
41OLS_TOOLS_BRANCH ?= lp:~bloodearnest/+junk/ols-tools
42TOOLS = branches/ols-tools
43LXC_PATH = /var/lib/lxd/containers/$(LXC_NAME)
44LXC_STATE = $(shell lxc info $(LXC_NAME) | grep Status | awk '{ print $$2 }')
45IP = $(shell lxc info $(LXC_NAME) | grep eth0 | grep -v inet6 | awk '{ print $$3 }')
46HOST = $(shell hostname)
47SSH_CONFIG_FILE ?= django_project/ssh_config
48LXC_TARGETS ?= targets.mk
49# flags/vars for passing to make invocation inside lxc
50LXC_MAKE_FLAGS=--no-print-directory --no-builtin-rules
51LXC_MAKE_VARS = "I_CAN_HAZ_JUJU=yes"
52ERR_LOG=$(shell mktemp)
53
54APT_PROXY ?=
55export APT_PROXY
56
57# multiline error message
58define RUN_LXC_SETUP
59
60lxc container $(LXC_NAME) not found
61Please run the following to create it:
62make lxc-setup
63endef
64
65
66ifneq ($(HOST),$(LXC_NAME))
67# We are on the host machine, so ssh to the lxc and run the command
68
69# use the container dir as a fs-level proxy to whether the lxc exists
70$(LXC_PATH):
71 $(error $(RUN_LXC_SETUP))
72
73lxc-available: $(LXC_PATH)
74 @test -n "$(IP)" || { echo "Cannot find ip address for container $(LXC_NAME) - is it running? Try: make lxc-start"; exit 1; }
75
76# sadly (or maybe not), these can't be in config-manager.txt, as we need to
77# bootstrap to get those, and we can't bootstrap until we have an lxc.
78## fetch the shared ols-tools branch
79$(TOOLS):
80 @[ -d $@ ] && bzr pull -d $@ || bzr branch $(OLS_TOOLS_BRANCH) $@
81.PHONY: $(TOOLS)
82
83# this is idempotent (kinda), can be rerun to update the lxc
84## create/update the development lxc
85lxc-setup: $(TOOLS)
86 ./branches/ols-tools/setup-devel-lxd $(LXC_NAME) $(LXC_BASEDIR)
87
88## start the lxc and reset the db
89lxc-start: $(LXC_PATH)
90 @[ "$(LXC_STATE)" = "Running" ] && echo "lxc $(LXC_NAME) already running" || (echo "Starting lxc $(LXC_NAME)" && lxc start $(LXC_NAME) && sleep 3)
91 @# reset db, as it's on shared memory, and thus been wiped
92 $(MAKE) db-reset
93
94## stop the lxc, including the juju env
95lxc-stop: $(LXC_PATH)
96 @[ "$(LXC_STATE)" != "Running" ] && echo "lxc $(LXC_NAME) already stopped" || (echo "Stopping lxc $(LXC_NAME)" && lxc stop $(LXC_NAME))
97
98## stop and delete the lxc
99lxc-delete: lxc-stop
100 @echo Destroying lxc $(LXC_NAME)
101 @lxc delete $(LXC_NAME)
102 @rm -f $(JENV) # juju env is gone now, so clean up
103
104## convenient shortcut to ssh in
105ssh: lxc-available
106 JUJU_ENV=$(JUJU_ENV) ssh -tA -F $(SSH_CONFIG_FILE) $(IP) 'cd $(PWD) ; exec "$$SHELL" -l'
107
108# TODO: an easy way to set env vars inside the lxc
109# an explicit list of envvars to transfer as make args
110# if args is not present, don't set it, or else we override the default to be empty
111ifdef ARGS
112LXC_MAKE_VARS += ARGS=\"$(ARGS)\"
113endif
114ifdef DJANGO_SETTINGS_MODULE
115LXC_MAKE_VARS += DJANGO_SETTINGS_MODULE=$(DJANGO_SETTINGS_MODULE)
116endif
117ifdef SST_BASE_URL
118LXC_MAKE_VARS += SST_BASE_URL=$(SST_BASE_URL)
119endif
120
121
122# These rules build a list of the makefile targets that are available in the lxc
123# to use for providing tab completion on the host.
124# They utilise the special re-making behaviour where make will first try and
125# build any targets that are also included Makefiles, then restart parsing.
126# So in this case, make will try and build $(LXC_TARGETS) first, then
127# include it
128# https://www.gnu.org/software/make/manual/html_node/Remaking-Makefiles.html
129$(LXC_TARGETS): Makefile Makefile.common Makefile.juju
130 @echo "(Makefiles changed - rebuilding lxc target list)"
131 @echo -n "TARGETS=" > $(LXC_TARGETS)
132 @echo '$(shell make -nrRpq -f Makefile.juju -f Makefile.common | egrep -o "^[a-zA-Z0-9._/-]+:" | grep -v "^\." | grep -v Makefile | cut -d: -f1 | sort -u)' >> $(LXC_TARGETS)
133
134# the - means its absence is ignored on the first pass
135-include $(LXC_TARGETS)
136
137# We can now guarantee the file target list is generated and up to date
138$(TARGETS): lxc-available
139 @ssh -qtAF $(SSH_CONFIG_FILE) $(IP) -- $(MAKE) $(LXC_MAKE_FLAGS) -C $(PWD) $@ $(LXC_MAKE_VARS)
140
141else # we are in the lxc
142
143# here to avoid overriding non-juju config. Can be moved once juju is default
144DJANGO_SETTINGS_MODULE ?= django_project.settings_devel_juju
145
146include Makefile.common
147include Makefile.juju
148
149endif
150
151else # we are not using juju
152
153include Makefile.common
154include Makefile.db
155
156bootstrap: $(LOCAL_SETTINGS_PATH) virtualenv sourcedeps install-wheels-dev
157
158run: ARGS=0.0.0.0:8000
159run:
160 $(ENV)/bin/gunicorn django_project.wsgi:application --workers=2 --reload --pid=logs/gunicorn.pid --bind=$(ARGS) --timeout=99999
161
162endif
0163
=== renamed file 'Makefile' => 'Makefile.common'
--- Makefile 2016-02-25 17:59:36 +0000
+++ Makefile.common 2016-03-04 19:06:06 +0000
@@ -1,12 +1,11 @@
1# Copyright (C) 2014 Canonical Ltd.1# Copyright (C) 2015 Canonical Ltd.
22#
3CM ?= /usr/lib/config-manager/cm.py3CM ?= /usr/lib/config-manager/cm.py
4CONFIGMANAGER = config-manager.txt4CONFIGMANAGER = config-manager.txt
5CONN_CHECK_CONFIG_PATH ?= /tmp/sso_conn_check_config.yaml5CONN_CHECK_CONFIG_PATH ?= /tmp/sso_conn_check_config.yaml
6DJANGO_SETTINGS_MODULE ?= settings6DJANGO_SETTINGS_MODULE ?= settings
7ENV = $(CURDIR)/env
8JUJU_ENV ?= local7JUJU_ENV ?= local
9JUJU_REPO ?= ../.juju-repo8JUJU_REPOSITORY ?= ../.juju-repo
10LOCAL_SETTINGS_DIR ?= $(CURDIR)/../local_config9LOCAL_SETTINGS_DIR ?= $(CURDIR)/../local_config
11LOCAL_SETTINGS_PATH = $(LOCAL_SETTINGS_DIR)/settings.py10LOCAL_SETTINGS_PATH = $(LOCAL_SETTINGS_DIR)/settings.py
12FLAKE8 = $(ENV)/bin/flake811FLAKE8 = $(ENV)/bin/flake8
@@ -21,13 +20,11 @@
21TRANSLATIONS_DIR = $(CURDIR)/branches/translations/po20TRANSLATIONS_DIR = $(CURDIR)/branches/translations/po
22# this is a bit hackey, could be an external script in python (Simon)21# this is a bit hackey, could be an external script in python (Simon)
23UNITTEST_TARGETS = $(shell find $(SRC_DIR) -name test_\*.py | sed 's+\(^$(SRC_DIR)/\|.py\)++g' | sed 's+/+.+g')22UNITTEST_TARGETS = $(shell find $(SRC_DIR) -name test_\*.py | sed 's+\(^$(SRC_DIR)/\|.py\)++g' | sed 's+/+.+g')
24WHEELS_BRANCH_URL ?= lp:~ubuntuone-pqm-team/$(PROJECT_NAME)/dependencies
25WHEELS_DIR = branches/wheels
26STATIC_ROOT ?= $(shell grep -R STATIC_ROOT django_project/settings_base.py | awk '{print $$3}')23STATIC_ROOT ?= $(shell grep -R STATIC_ROOT django_project/settings_base.py | awk '{print $$3}')
27# Create archives in labelled directories (ie. r27/$(PROJECT_NAME).tbz2)24# Create archives in labelled directories (ie. r27/$(PROJECT_NAME).tbz2)
28TARBALL_BUILD_LABEL ?= $(shell bzr version-info --custom --template="r{revno}\n")25TARBALL_BUILD_LABEL ?= $(shell bzr version-info --custom --template="r{revno}\n")
29TARBALL_FILE_NAME = $(PROJECT_NAME).tbz226TARBALL_FILE_NAME = $(PROJECT_NAME).tbz2
30TARBALL_BUILDS_DIR ?= $(JUJU_REPO)/builds27TARBALL_BUILDS_DIR ?= $(JUJU_REPOSITORY)/builds
31TARBALL_BUILD_DIR = $(TARBALL_BUILDS_DIR)/$(TARBALL_BUILD_LABEL)28TARBALL_BUILD_DIR = $(TARBALL_BUILDS_DIR)/$(TARBALL_BUILD_LABEL)
32TARBALL_BUILD_PATH = $(TARBALL_BUILD_DIR)/$(TARBALL_FILE_NAME)29TARBALL_BUILD_PATH = $(TARBALL_BUILD_DIR)/$(TARBALL_FILE_NAME)
3330
@@ -59,13 +56,16 @@
59 @DJANGO_SETTINGS_MODULE=django_project.settings_build $(MAKE) compilemessages 56 @DJANGO_SETTINGS_MODULE=django_project.settings_build $(MAKE) compilemessages
6057
61# note: fetch-sourcedeps needs to be manually called before this will work.58# note: fetch-sourcedeps needs to be manually called before this will work.
59## build a deployment tarball
62build-tarball: install-wheels $(TARBALL_BUILD_PATH)60build-tarball: install-wheels $(TARBALL_BUILD_PATH)
6361
62## write the bzr revno to lib/versioninfo.py
64version:63version:
65 bzr version-info --format=python > lib/versioninfo.py64 bzr version-info --format=python > lib/versioninfo.py
6665
67### Wheels ###66### Wheels ###
6867
68## create/reinitialise the virtualenv
69virtualenv:69virtualenv:
70 @virtualenv --clear --system-site-packages $(ENV)70 @virtualenv --clear --system-site-packages $(ENV)
7171
@@ -73,24 +73,33 @@
73update-wheels: virtualenv73update-wheels: virtualenv
74 $(PIP) wheel -w $(WHEELS_DIR) -f $(WHEELS_DIR) $(ARGS)74 $(PIP) wheel -w $(WHEELS_DIR) -f $(WHEELS_DIR) $(ARGS)
7575
76## install wheel dependencies
76install-wheels: ARGS=-r requirements.txt77install-wheels: ARGS=-r requirements.txt
77install-wheels: virtualenv78install-wheels: virtualenv
78 $(PIP) install --find-links=$(WHEELS_DIR) --no-index $(ARGS)79 $(PIP) install --find-links=$(WHEELS_DIR) --no-index $(ARGS)
7980
81## install development wheel dependencies
80install-wheels-dev: virtualenv82install-wheels-dev: virtualenv
81 $(MAKE) install-wheels ARGS="-r requirements_devel.txt --pre"83 $(MAKE) install-wheels ARGS="-r requirements_devel.txt --pre"
8284
85## setup localmail server in container
86localmail:
87 ./scripts/setup-localmail.sh
88
83### dependencies ###89### dependencies ###
8490
85branches/last_build: $(CONFIGMANAGER)91branches/last_build: $(CONFIGMANAGER)
86 $(CM) update $(CONFIGMANAGER)92 $(CM) update $(CONFIGMANAGER)
87 touch $@93 touch $@
8894
95## update wheels branch
89wheels:96wheels:
90 [ -d $(WHEELS_DIR) ] && (cd $(WHEELS_DIR) && bzr pull) || (bzr branch $(WHEELS_BRANCH_URL) $(WHEELS_DIR))97 [ -d $(WHEELS_DIR) ] && (cd $(WHEELS_DIR) && bzr pull) || (bzr branch $(WHEELS_BRANCH_URL) $(WHEELS_DIR))
9198
99## fetch sourcedeps and wheels branch
92fetch-sourcedeps: branches/last_build wheels version100fetch-sourcedeps: branches/last_build wheels version
93101
102## fetch sourcedeps
94sourcedeps: fetch-sourcedeps install-wheels103sourcedeps: fetch-sourcedeps install-wheels
95104
96### local config ###105### local config ###
@@ -101,23 +110,8 @@
101$(LOCAL_SETTINGS_PATH): $(LOCAL_SETTINGS_DIR)110$(LOCAL_SETTINGS_PATH): $(LOCAL_SETTINGS_DIR)
102 @cp django_project/settings.py.example $(LOCAL_SETTINGS_PATH)111 @cp django_project/settings.py.example $(LOCAL_SETTINGS_PATH)
103112
104### for devel: start and stop the local postgresql DB ###
105
106include Makefile.db
107
108### what you really need ###113### what you really need ###
109114
110bootstrap: $(LOCAL_SETTINGS_PATH) virtualenv sourcedeps install-wheels-dev
111
112clean:
113 rm -rf $(ENV)
114 rm -rf $(WHEELS_DIR)
115 rm -rf branches/*
116 rm -rf staticfiles
117 rm -f lib/versioninfo.py
118 find -name '*.pyc' -delete
119 find -name '*.~*' -delete
120
121conn-check:115conn-check:
122 @echo "Generating conn-check config from Django settings.."116 @echo "Generating conn-check config from Django settings.."
123 @sudo -u $$(ls -ld $(CURDIR) | awk '{print $$3}') PYTHONPATH=$(PYTHONPATH) \117 @sudo -u $$(ls -ld $(CURDIR) | awk '{print $$3}') PYTHONPATH=$(PYTHONPATH) \
@@ -142,17 +136,13 @@
142# Check python files (except for the south migration files that are not pep8136# Check python files (except for the south migration files that are not pep8
143# compliant and probably never will).137# compliant and probably never will).
144lint:138lint:
145 @$(FLAKE8) --exclude='migrations' \139 @$(FLAKE8) --exclude='migrations,django_project/settings.py' \
146 --filename='*.py' \140 --filename='*.py' \
147 src/ django_project/ scripts/141 src/ django_project/ scripts/
148142
149manage:143manage:
150 $(DJANGO_MANAGE) $(ARGS)144 $(DJANGO_MANAGE) $(ARGS)
151145
152run: ARGS=0.0.0.0:8000
153run: collectstatic
154 $(ENV)/bin/gunicorn django_project.wsgi:application --workers=2 --reload --pid=logs/gunicorn.pid --bind=$(ARGS) --timeout=99999 --error-logfile=- --access-logfile=-
155
156start: bootstrap start-db146start: bootstrap start-db
157147
158stop: stop-db148stop: stop-db
@@ -186,4 +176,21 @@
186 cd -; \176 cd -; \
187 done177 done
188178
189.PHONY: clean conn-check version makemessages compilemessages collectstatic run-acceptance docs179## display this help message
180help:
181 $(info Available targets)
182 @awk '/^[a-zA-Z\-\_0-9]+:/ { \
183 nb = sub( /^## /, "", helpMsg ); \
184 if(nb == 0) { \
185 helpMsg = $$0; \
186 nb = sub( /^[^:]*:.* ## /, "", helpMsg ); \
187 } \
188 if (nb) \
189 printf "\033[1;31m%-" width "s\033[0m %s\n", $$1, helpMsg; \
190 } \
191 { helpMsg = $$0 }' \
192 width=$$(grep -o '^[a-zA-Z_0-9]\+:' $(MAKEFILE_LIST) | wc -L) \
193 $(MAKEFILE_LIST)
194
195
196.PHONY: conn-check version makemessages compilemessages collectstatic run-acceptance docs
190197
=== added file 'Makefile.juju'
--- Makefile.juju 1970-01-01 00:00:00 +0000
+++ Makefile.juju 2016-03-04 19:06:06 +0000
@@ -0,0 +1,120 @@
1# sso specific config
2CHARM_SERIES = trusty
3CHARM = canonical-identity-provider
4CHARM_BRANCH = lp:~ubuntuone-pqm-team/canonical-is-charms/canonical-identity-provider
5CHARM_SRC = ../sso-charm
6DEPLOYER_CONFIG = $(CURDIR)/django_project/deploy.yaml
7DEPLOYER_TARGET = sso-app-dev
8
9
10LOG_DIRS ?= ./logs/www-oops ./logs/schema-updates
11ABS_CHARM_SRC = $(shell readlink -f $(CHARM_SRC))
12LOCAL_JUJU_CONFIG = .local.yaml
13export I_CAN_HAZ_JUJU=yes
14
15# python config, overriding the non-juju config
16PYTHONPATH := $(LXC_BASEDIR)/etc:$(SRC_DIR):$(LIB_DIR):$(CURDIR)
17export PYTHONPATH
18
19
20
21$(CHARM_SRC):
22 @test -d $@ && bzr pull -d $@ || bzr branch $(CHARM_BRANCH) $@
23
24
25# | is order only dependency - means if the dir is present, we're good. no need to rebuild
26# https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html
27$(JUJU_REPOSITORY): $(CHARM_SRC)
28 @mkdir -p $(JUJU_REPOSITORY)/$(CHARM_SERIES)
29 @rm -f $(JUJU_REPOSITORY)/$(CHARM_SERIES)/$(CHARM)
30 @ln -sf $(ABS_CHARM_SRC) $(JUJU_REPOSITORY)/$(CHARM_SERIES)/$(CHARM)
31
32# make sure log subdirs are created with user ownership, or else they are owned by root.
33$(LOG_DIRS):
34 mkdir -p $@
35 sudo chown $$USER:$$USER $@
36
37$(LOCAL_JUJU_CONFIG):
38 @echo "$(DEPLOYER_TARGET): {services: {sso-app: {options: { user: $$USER }}}}" > $(LOCAL_JUJU_CONFIG)
39.INTERMEDIATE: $(LOCAL_JUJU_CONFIG)
40.DELETE_ON_ERROR: $(LOCAL_JUJU_CONFIG)
41
42
43# we need to stop gunicorn so we can relink the python in the venv
44gunicorn-start:
45 @test -f /etc/init/gunicorn.conf && sudo service gunicorn start || true
46gunicorn-stop:
47 @test -f /etc/init/gunicorn.conf && { sudo service gunicorn stop; sleep 1; } || true
48
49dependencies: system-dependencies system-dependencies-devel gunicorn-stop virtualenv sourcedeps install-wheels-dev gunicorn-start
50
51system-dependencies: dependencies.txt
52 cat dependencies.txt | xargs sudo apt-get install -y
53
54system-dependencies-devel: dependencies-devel.txt
55 @cat dependencies-devel.txt | xargs sudo apt-get install -y
56
57## install dependencies and deploy charms
58bootstrap: dependencies deploy
59
60# use jenv file as indication the environment is up or not
61$(JENV):
62 juju bootstrap --upload-tools
63
64# clean up any stale jenv files
65clean-old-jenv:
66 @test -f $(JENV) && grep -q $(shell hostname -I) $(JENV) || rm -f $(JENV)
67
68juju-bootstrap: clean-old-jenv $(JENV)
69
70deploy: dependencies juju-bootstrap $(JUJU_REPOSITORY) $(LOCAL_JUJU_CONFIG) | $(LOG_DIRS)
71 juju-deployer --local-mods -w 15 -s 0 --debug -c $(CHARM_SRC)/deploy.yaml -c $(DEPLOYER_CONFIG) -c $(LOCAL_JUJU_CONFIG) $(DEPLOYER_TARGET)
72 $(MAKE) setup-db localmail I_CAN_HAZ_JUJU=yes
73
74## destroy juju environment
75juju-destroy:
76 juju destroy-environment $(JUJU_ENV) --force || true
77 @# work around manual provider rubbishness, and remove charms
78 @echo Cleaning up manual provider leftovers
79 @sudo rm -rf /var/lib/juju/*
80 @sudo rm -f /etc/init/juju*
81 @sudo killall -q jujud || true
82 @sudo killall -q mongod || true
83 @# clean up any charm left overs
84 @sudo rm -f /etc/init/gunicorn*
85 @sudo rm -f /etc/init.d/gunicorn*
86 @sudo rm -rf /srv/gunicorn /srv/conn-check
87
88## destroy juju environment and rebuild
89redeploy: juju-destroy deploy
90
91# preserving old alias
92setup-db reset-db: db-setup
93
94## setup a clean database
95db-setup db-reset:
96 @# protect for when the juju env is not up yet
97 juju ssh sso-postgresql/0 true &>/dev/null && { $(CHARM_SRC)/scripts/create-dev-db; $(MAKE) migrate; }
98
99## migrate the db
100migrate:
101 $(DJANGO_MANAGE) migrate --noinput
102
103# this stops the system gunicorn and runs it manually, restarting on exit
104## run server in foreground for debugging
105run: ARGS=0.0.0.0:8080
106run: GUNICORN_DEVEL_ARGS=--reload --error-logfile=- --access-logfile=- --timeout=99999
107run: gunicorn-stop
108 @trap 'sudo service gunicorn start' INT; bash /srv/gunicorn/run_sso_wsgi.sh --bind=$(ARGS) $(GUNICORN_DEVEL_ARGS)
109
110## run acceptance tests in development
111acceptance-dev:
112 ./scripts/acceptance-dev-juju.sh $(ARGS)
113.PHONY: acceptance-dev
114
115acceptance-db: db-reset
116 $(DJANGO_MANAGE) loaddata test
117 $(DJANGO_MANAGE) create_test_team
118 # add openid RP config
119 # we need this to explicitly allow unverified logins
120 $(DJANGO_MANAGE) add_openid_rp_config $$SST_BASE_URL/consumer --allow-unverified --allowed-user-attribs=\"fullname,nickname,email,language,account_verified\"
0121
=== added file 'README.juju'
--- README.juju 1970-01-01 00:00:00 +0000
+++ README.juju 2016-03-04 19:06:06 +0000
@@ -0,0 +1,220 @@
1=============================
2Development environment setup
3=============================
4
5Getting started
6===============
7
8Note: currently you need to set I_CAN_HAZ_JUJU=yes in the environment to enable the juju dev env.
9
100. Get the code
11::
12
13.. note::
14 You need to install, configure and setup bzr and ssh keys. See BAZAAR below.
15
16 bzr branch lp:canonical-identity-provider
17
18
191. Install lxd
20::
21
22 The supported way to develop Canonical Identity Provider is using Juju and LXD
23
24 Follow the instructions here to install/configure lxd
25
26 https://linuxcontainers.org/lxd/getting-started-cli/
27
28 Optional: you don't need juju on the host (as it will be installed in the
29 lxc), but it is useful to be able to query the juju system direct from the
30 host
31
32 sudo apt-get install juju-core
33
342. Create the lxd container.
35::
36
37 The following command will create an lxd container, in which everything
38 will be deployed. This will create the container if it does not exist,
39 update it, install dependencies, and set up juju properly. It mounts the
40 current directory into the container, so you can edit your code on the
41 host. It also mirrors your user and mounts your home dir into the
42 container. This allows conveniences like ssh/bzr/bash configs to be used
43 inside the container. Some important configuration options that can be
44 configured via env vars or make args:
45
46 SSO_LXC - name of lxd container and juju environment. Default: sso
47
48 APT_PROXY - http://url of local apt proxy, highly recommended to have one
49 set up. Default: none
50
51 DEVELOPER_PACKAGES - list of additional packages to install. Default: none
52
53 $ cd canonical-identity-provider
54 $ make lxc-setup [APT_PROXY=http://...]
55
56.. note::
57
58 You can access the container via the normal lxd mechanism (e.g lxc
59 exec), or via ssh, or just do
60
61 make ssh
62
63 If you create an lxd profile called ols-dev, this will be applied to the
64 container. This is useful if you have an unusual $HOME set up, amongst
65 other things. For example, to have all your lxd containers for OLS
66 projects have a special mount into your $HOME dir:
67
68 lxc profile create ols-dev
69 lxc profile device add ols-dev <name> disk source=/mnt/encrypted path=$HOME/work
70
71 By default, the development environment uses django_project/ssh_config
72 as its ssh config file. This is to provide a good default experience.
73 However, If you wish to configure ssh into the container yourself, you
74 can set SSH_CONFIG_FILE env var or make argument. Note: agent
75 forwarding is required, and is hardcoded by cli arguments in the
76 makefiles.
77
78 You should start, stop or destroy the container using the following:
79
80 make lxc-stop
81 make lxc-start
82 make lxc-delete # this will wipe everything!
83
84
853. Bootstrap the project
86
87 This will fetch python dependencies, and install them into a virtualenv. It
88 will also check out the juju charm, and bootstrap/deploy a juju environment
89 in the container, inluding postgresql, memcached, and gunicorn. Both of
90 these steps take a few minutes each the first time you do them, but
91 subsequent bootstraps are much quicker. When complete, the service should
92 be accessible on port 8080 of the container.
93
94 $ make bootstrap
95
96.. note::
97
98 For more commands, see
99
100 $ make help
101
102
1034. Run the tests
104::
105
106 $ make test
107
108 To run tests in 4 parallel
109
110 $ make test ARGS=-c4
111
112
1135. Debug the instance
114::
115 By default, the service is running on port 8080 under upstart, exactly
116 like production. If you wish to use a debugger, you need to use the
117 following command. This will stop the upstart controlled gunicorn, and
118 run it in the foreground, so you can attach to stdin/out
119
120 $ make run
121
122
1236. (Optional) Setup reCaptcha
124::
125
126 captcha is disabled by default. If you wish to enable it, you can do
127
128 juju set sso-app captcha_public_key=<your public key>
129 juju set sso-app captcha_private_key=<your private key>
130
131 You may also need to enable the gargoyle flag for captcha
132
133
1347. (Optional) Accessing the mail server
135::
136 The development set up includes an email server (lp:localmail), which
137 supports delivery via smtp on port 2025, and access via IMAP on port 2143,
138 or a simple web interface on port 8880.
139
140 Additionally, the logs are available in logs/localmail, and a mbox file is
141 at logs/localmail.mbox, which you can read with mutt or other mail client.
142
143
1448. (Optional) Create your own certificate and private key for SAML 2.0
145::
146 Required if you want to test interaction with a real Service Point.
147
148 See instructions in the django-saml2-idp upstream project:
149 http://code.google.com/p/django-saml2-idp/source/browse/trunk/idptest/keys/mk_keys.sh
150
151 Once you have the files (certificate.pem and private-key.pem), update the
152 saml_remotes config on the charm to point to them.
153
154
1559. (Optional) Running acceptance tests
156::
157
158 There is suite of selenium tests in ./acceptance. To run those against
159 your container:
160
161 make acceptance-dev
162
163 For more info:
164
165 make acceptance-dev ARGS=--help
166
16710. (Optional) CSS Hacking
168::
169
170 (https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager)
171
172 npm install
173 npm install -g gulp
174 gulp
175
176 Will start a watcher to lint, minify and concat CSS (see ./gulpfile.js)
177 CSS source can be found in src/identityprovider/static/src/css and is built
178 to src/identityprovider/static/css/ (see ./gulpfile.js)
179
180
18111. (Optional) Build deployment tarball
182::
183 To build a tarball that contains all the code, dependencies and the
184 virtualenv:
185
186 make fetch-sourcedeps
187 make build-tarball
188
189 Note: this is two separate steps as in Mojo specs we need to separate the
190 dependency collect step from the build step, as the build step runs in an
191 lxc with no internet access at all.
192
193
194
195BAZAAR
196------
197You can install bzr like this:
198
199$ sudo apt-get install bzr
200$ bzr whoami "You Name <youremail@example.com"
201
202You will also need to setup SSH keys. If you already have them, you will need
203to copy them to the machine you wish to use. (Otherwise, Launchpad won't talk
204to you.) Although, this suggests you can have multiple keys:
205
206https://launchpad.net/~YOURUSERNAME/+editsshkeys
207
208Background Reading
209------------------
210For those new to this project, this may help bring you up to speed quickly.
211The Identity Provider uses some conventions that you may not have seen before.
212These include:
213
214- virtualenv
215- preflight
216
217Enjoy!
218======
219
220We hope you enjoy using this software.
0221
=== added file 'django_project/deploy.yaml'
--- django_project/deploy.yaml 1970-01-01 00:00:00 +0000
+++ django_project/deploy.yaml 2016-03-04 19:06:06 +0000
@@ -0,0 +1,25 @@
1sso-app-dev:
2 inherits:
3 - sso-dev-minimal
4 services:
5 sso-app:
6 to: [0]
7 options:
8 build_label: devel
9 deployment: devel
10 secret_key: development
11 email_hostport: localhost:2025
12 django_settings_module: django_project.settings_devel_juju
13 # use unix socket
14 db_host: ""
15 db_port: ""
16 # use db superuser for dev
17 db_user: ssoadmin
18 db_password: ssoadmin
19 sso-postgresql:
20 to: [0]
21 options:
22 # enable access via local socket
23 extra_pg_auth: local all sso md5,local all ssoadmin md5
24 sso-memcached:
25 to: [0]
026
=== modified file 'django_project/paths.py'
--- django_project/paths.py 2015-10-09 16:03:29 +0000
+++ django_project/paths.py 2016-03-04 19:06:06 +0000
@@ -29,7 +29,9 @@
2929
3030
31def setup_paths():31def setup_paths():
32 sys.path = list(get_paths(PATHS)) + sys.path + APPEND_PATHS32 sys.path = list(get_paths(PATHS)) + sys.path
33 if 'I_CAN_HAZ_JUJU' not in os.environ:
34 sys.path += APPEND_PATHS
33 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')35 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
3436
3537
3638
=== added symlink 'django_project/settings_acceptance_juju.py'
=== target is u'../branches/config/settings_acceptance_juju.py'
=== modified file 'django_project/settings_base.py'
--- django_project/settings_base.py 2016-01-27 12:00:39 +0000
+++ django_project/settings_base.py 2016-03-04 19:06:06 +0000
@@ -503,7 +503,7 @@
503SESSION_SAVE_EVERY_REQUEST = False503SESSION_SAVE_EVERY_REQUEST = False
504SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'504SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
505SETTINGS_ENCODING = 'utf-8'505SETTINGS_ENCODING = 'utf-8'
506SETTINGS_MODULE = 'django_project.settings'506SETTINGS_MODULE = 'settings'
507SHORT_DATETIME_FORMAT = 'm/d/Y P'507SHORT_DATETIME_FORMAT = 'm/d/Y P'
508SHORT_DATE_FORMAT = 'm/d/Y'508SHORT_DATE_FORMAT = 'm/d/Y'
509SHOW_USER_NUM_AUTHLOGS = 50509SHOW_USER_NUM_AUTHLOGS = 50
510510
=== added file 'django_project/settings_devel_juju.py'
--- django_project/settings_devel_juju.py 1970-01-01 00:00:00 +0000
+++ django_project/settings_devel_juju.py 2016-03-04 19:06:06 +0000
@@ -0,0 +1,54 @@
1import os
2
3os.environ.setdefault('SSO_ROOT_URL', 'http://0.0.0.0:8080/')
4from settings import * # noqa
5
6ALLOWED_HOSTS = ['*']
7CSRF_COOKIE_SECURE = False
8DEBUG = True
9GARGOYLE_SWITCH_DEFAULTS = {
10 'TWOFACTOR': {'is_active': True},
11 'CAN_VIEW_SUPPORT_PHONE': {'is_active': True},
12 'CAPTCHA': {'is_active': False},
13 'PREFLIGHT': {'is_active': True},
14 'LOGIN_BY_TOKEN': {'is_active': True},
15}
16PASSWORD_HASHERS = [
17 'django.contrib.auth.hashers.SHA1PasswordHasher',
18 'identityprovider.auth.BCrypt13PasswordHasher',
19 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
20]
21SESSION_COOKIE_SECURE = False
22STATSD_CLIENT = 'django_statsd.clients.null'
23TEMPLATE_DEBUG = True
24TESTING = True
25TWOFACTOR_MANDATORY_TEAMS = ['ubuntuone-hackers']
26# Load a minimal blacklist in development so as to not need too much
27# time and memory and not break any tests
28PASSWORD_BLACKLIST_FILE = os.path.join(BASE_DIR, "blacklist-devel.txt")
29
30# this config is only needed for running the sst acceptance tests
31# the server doesn't need this config
32EMAIL_ADDRESS_PATTERN = 'testemail+%s@example.com'
33SSO_TEST_ACCOUNT_EMAIL = 'testemail@example.com'
34SSO_TEST_ACCOUNT_FULL_NAME = 'Test Account'
35SSO_TEST_ACCOUNT_PASSWORD = 'password'
36TEST_ACCOUNT_EMAIL = 'testemail+something@example.com'
37TEST_ACCOUNT_PASSWORD = 'password'
38TEST_DISCOVER_ROOT = SRC_DIR
39TEST_DISCOVER_TOP_LEVEL = SRC_DIR
40TEST_PROFILE = 'test.prof'
41TEST_RUNNER = 'testing.runner.TestRunner'
42
43# localmail imap server
44IMAP_PORT = 2143
45IMAP_USERNAME = 'DOESNOTMATTER'
46IMAP_PASSWORD = 'DOESNOTMATTER'
47IMAP_SERVER = 'localhost'
48IMAP_USE_SSL = False
49
50
51try:
52 from django_project.settings_local import * # noqa
53except ImportError:
54 pass
055
=== added file 'django_project/ssh_config'
--- django_project/ssh_config 1970-01-01 00:00:00 +0000
+++ django_project/ssh_config 2016-03-04 19:06:06 +0000
@@ -0,0 +1,8 @@
1# disable all key checking and warnings
2CheckHostIP no
3UserKnownHostsFile /dev/null
4StrictHostKeyChecking no
5LogLevel ERROR
6# pass through JUJU_ENV
7SendEnv JUJU_ENV
8SendEnv I_CAN_HAZ_JUJU
09
=== modified file 'requirements_devel.txt'
--- requirements_devel.txt 2016-01-20 18:34:00 +0000
+++ requirements_devel.txt 2016-03-04 19:06:06 +0000
@@ -7,7 +7,7 @@
7fixtures==0.3.127fixtures==0.3.12
8flake8==2.4.08flake8==2.4.0
9junitxml==0.79junitxml==0.7
10localmail==0.310localmail==0.4.1
11logilab-astng==0.24.311logilab-astng==0.24.3
12logilab-common==0.59.112logilab-common==0.59.1
13mechanize==0.2.513mechanize==0.2.5
1414
=== added file 'run-tests-juju'
--- run-tests-juju 1970-01-01 00:00:00 +0000
+++ run-tests-juju 2016-03-04 19:06:06 +0000
@@ -0,0 +1,52 @@
1#! /bin/bash
2# How the tests are run in Jenkins by Tarmac
3#
4# ./run-tests -- run unit/acceptance tests for an environment.
5#
6# Usage: ./run-tests [dev|staging|production]
7set -e
8
9TARGET=$1
10BOOTSTRAP=${2:-yes}
11
12if [ "$TARGET" = "production" ]; then
13 SST_BASE_URL="https://login.ubuntu.com"
14elif [ "$TARGET" = "staging" ]; then
15 SST_BASE_URL="https://login.staging.ubuntu.com"
16fi
17
18# Some Jenkins jobs copy workspace.tar.gz from successful build.
19if [ -r "workspace.tar.gz" ]; then
20 tar zxf workspace.tar.gz -C .
21fi
22
23# clean old results
24rm -rf results/*
25
26# make sure that dependencies are up to date
27if [ $BOOTSTRAP = "yes" ]; then
28 echo "Setting up lxc..."
29 make lxc-setup
30 echo "Bootstrapping..."
31 make clean && make bootstrap
32fi
33
34# Before setting up the DB, ensure developer generated all needed migrations
35# Will abort if there are pending migrations
36echo "Check missing Django migrations left behind. If output is not 'No changes detected', run will abort."
37make manage ARGS=makemigrations | tee /tmp/sso.log && grep "No changes detected" /tmp/sso.log > /dev/null
38
39# run tests
40if [[ -z ${TARGET} ]]; then
41 echo "Updating translation messages"
42 make makemessages
43 echo "Running canonical-identity-provider tests in tarmac"
44 make test ARGS="--noinput --failfast"
45else
46 # run acceptance tests if TARGET given
47 if [ ${TARGET} = "dev" ]; then
48 make acceptance-dev
49 else
50 make run-acceptance SST_BASE_URL="$SST_BASE_URL" DJANGO_SETTINGS_MODULE=django_project.settings_acceptance_juju
51 fi
52fi
053
=== added file 'scripts/acceptance-dev-juju.sh'
--- scripts/acceptance-dev-juju.sh 1970-01-01 00:00:00 +0000
+++ scripts/acceptance-dev-juju.sh 2016-03-04 19:06:06 +0000
@@ -0,0 +1,66 @@
1#!/bin/bash
2
3set -ue
4
5function usage {
6 cat << EOF
7Usage: $0 [-t TESTCASE] [-h|-f] [-p PORT]
8Run SSO acceptance tests on a random port.
9 -t [TESTCASE] run using TESTCASE regex. Will not reset db
10 -h run headless (default)
11 -f run headful
12 -p [PORT] use a specific port (e.g. -p 8001)
13 -c force a clean db (if using -t option)
14 -1 stop on the first failure (AKA "fail-fast")
15EOF
16}
17
18# random port by default
19PORT=8080
20TESTCASE=
21HEADLESS="-x"
22CLEAN="false"
23FAILFAST=
24
25while getopts ":t:hfc1p:" opt; do
26 case $opt in
27 t) TESTCASE=$OPTARG ;;
28 h) HEADLESS="-x" ;;
29 f) HEADLESS="" ;;
30 p) PORT=$OPTARG ;;
31 c) CLEAN="true" ;;
32 1) FAILFAST="--failfast" ;;
33 \?)
34 echo "Invalid option: -$OPTARG" >&2
35 usage
36 exit 1
37 ;;
38 :)
39 echo "Option -$OPTARG requires an argument." >&2
40 usage
41 exit 1
42 ;;
43 esac
44done
45
46export PORT=$PORT
47export SSO_HOSTNAME="0.0.0.0:$PORT"
48export SSO_ROOT_URL="http://$SSO_HOSTNAME"
49export SST_BASE_URL="http://$SSO_HOSTNAME"
50
51# only reset db if we're doing a full run or explicitly told to
52if [ -z $TESTCASE ] || $CLEAN
53then
54 echo "Setting up acceptance database"
55 make acceptance-db
56 make collectstatic
57fi
58
59SST_ARGS="-s -r xml -q -c 1 $FAILFAST $HEADLESS"
60
61if [ -n "$TESTCASE" ]; then
62 SST_ARGS="$SST_ARGS \"$TESTCASE\""
63fi
64echo $SST_ARGS
65
66make run-acceptance ARGS="$SST_ARGS" DJANGO_SETTINGS_MODULE=django_project.settings_devel_juju
067
=== added file 'scripts/setup-localmail.sh'
--- scripts/setup-localmail.sh 1970-01-01 00:00:00 +0000
+++ scripts/setup-localmail.sh 2016-03-04 19:06:06 +0000
@@ -0,0 +1,47 @@
1#!/bin/bash
2set -eu
3
4sudo service localmail stop || true
5
6LOGS=$PWD/logs
7LOCALMAIL=/srv/localmail
8if [ ! -d $LOCALMAIL ]
9then
10 sudo mkdir -p $LOCALMAIL
11 sudo chown $USER:$USER $LOCALMAIL
12 virtualenv $LOCALMAIL
13 $LOCALMAIL/bin/pip install -U pip
14
15fi
16$LOCALMAIL/bin/pip install -U localmail
17upstart=/tmp/localmail.conf
18cron=/tmp/localmail.sh
19
20cat > $upstart <<EOF
21description "localmail development smtp/imap server"
22
23start on (local-filesystems and net-device-up IFACE=eth0)
24stop on runlevel [!12345]
25
26# If the process quits unexpectadly trigger a respawn
27respawn
28respawn limit 10 5
29
30setuid $USER
31setgid $USER
32chdir $PWD
33
34exec $LOCALMAIL/bin/twistd -n --pidfile= --logfile $LOGS/localmail.log localmail --smtp 2025 --imap 2143 --http 8880 --file $LOGS/localmail.mbox
35EOF
36
37cat > $cron <<EOF
38#!/bin/bash
39service localmail stop
40rm -f $LOGS/localmail.mbox $LOGS/localmail.log
41service localmail start
42EOF
43
44sudo mv $upstart /etc/init/localmail.conf
45sudo mv $cron /etc/cron.daily/localmail
46sudo chmod +x /etc/cron.daily/localmail
47sudo service localmail start
048
=== modified file 'src/identityprovider/tests/test_command_cleanup.py'
--- src/identityprovider/tests/test_command_cleanup.py 2015-12-09 20:01:10 +0000
+++ src/identityprovider/tests/test_command_cleanup.py 2016-03-04 19:06:06 +0000
@@ -47,8 +47,8 @@
4747
48 def make_test_accounts(self, count=0, date_created=None):48 def make_test_accounts(self, count=0, date_created=None):
49 for i in xrange(count):49 for i in xrange(count):
50 email = self.factory.make_email_address(prefix='isdtest+',50 email = self.factory.make_email_address(prefix='testemail+',
51 domain='canonical.com')51 domain='example.com')
5252
53 account = self.factory.make_account(email=email)53 account = self.factory.make_account(email=email)
54 if date_created is not None:54 if date_created is not None:
@@ -134,7 +134,7 @@
134 def assert_testdata(self, accounts=0, emails=0, passwords=0):134 def assert_testdata(self, accounts=0, emails=0, passwords=0):
135 tomorrow = now().date() + timedelta(days=1)135 tomorrow = now().date() + timedelta(days=1)
136 test_emails = EmailAddress.objects.filter(136 test_emails = EmailAddress.objects.filter(
137 email__iregex=r'^isdtest\+[^@]+@canonical\.com$',137 email__iregex=r'^testemail\+[^@]+@example\.com$',
138 date_created__lt=tomorrow)138 date_created__lt=tomorrow)
139 test_accounts = Account.objects.filter(139 test_accounts = Account.objects.filter(
140 displayname__startswith='Test Account')140 displayname__startswith='Test Account')
@@ -209,7 +209,7 @@
209 def test_cleanup_orphaned_accounts(self):209 def test_cleanup_orphaned_accounts(self):
210 self.make_test_accounts(count=10)210 self.make_test_accounts(count=10)
211 emails = EmailAddress.objects.filter(211 emails = EmailAddress.objects.filter(
212 email__iregex=r'^isdtest\+[^@]+@canonical\.com$')212 email__iregex=r'^testemail\+[^@]+@example\.com$')
213 email_ids = emails.values_list('pk')[:5]213 email_ids = emails.values_list('pk')[:5]
214 EmailAddress.objects.filter(pk__in=email_ids).delete()214 EmailAddress.objects.filter(pk__in=email_ids).delete()
215215
216216
=== modified file 'src/webui/tests/test_views_ui.py'
--- src/webui/tests/test_views_ui.py 2016-01-13 19:11:31 +0000
+++ src/webui/tests/test_views_ui.py 2016-03-04 19:06:06 +0000
@@ -606,7 +606,6 @@
606606
607 def assert_logged_out_in_sso(self, response):607 def assert_logged_out_in_sso(self, response):
608 self.assertTemplateUsed(response, 'registration/logout.html')608 self.assertTemplateUsed(response, 'registration/logout.html')
609 self.assertContains(response, 'You have been logged out')
610 self.assertIsInstance(response.context['user'], AnonymousUser)609 self.assertIsInstance(response.context['user'], AnonymousUser)
611610
612 def assert_redirect_as_per_request(self, response, redirected_to):611 def assert_redirect_as_per_request(self, response, redirected_to):