Skip to content

Commit

Permalink
Add playbook and modules for releasing assignments
Browse files Browse the repository at this point in the history
  • Loading branch information
jhamrick committed Nov 20, 2014
1 parent fe8d272 commit f017098
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 0 deletions.
68 changes: 68 additions & 0 deletions library/make_assignment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

import tempfile
import tarfile
import os

def main():
module = AnsibleModule(
argument_spec={
'src': dict(required=True),
'dest': dict(required=True),
'name': dict(required=True),
'overwrite': dict(default=False, type='bool')
}
)

src = module.params["src"]
dest = module.params["dest"]
name = module.params["name"]
overwrite = module.params["overwrite"]

# Check that the source is a directory
if not os.path.isdir(src):
module.fail_json(msg="Source {} is not a directory".format(src))

# Skip, if the destination exists and overwrite is false
if os.path.exists(dest) and not overwrite:
module.exit_json(
changed=False,
src=src,
dest=dest,
name=name
)

# Check if the destination exists, and create directories, if necessary
if not os.path.exists(os.path.dirname(dest)):
os.makedirs(os.path.dirname(dest))
if os.path.exists(dest):
os.remove(dest)

# Make a temporary file to create the archive
fd, tmp_dest = tempfile.mkstemp()
os.close(fd)

# Create the tarball
tf = tarfile.open(tmp_dest, 'w:gz')
for (dirpath, dirnames, filenames) in os.walk(src):
for filename in filenames:
fullpath = os.path.join(dirpath, filename)
arcpath = os.path.join(name, os.path.relpath(fullpath, src))
tf.add(fullpath, arcname=arcpath)
tf.close()

# Move the archive into place
module.atomic_move(tmp_dest, dest)

module.exit_json(
changed=True,
src=src,
dest=dest,
name=name,
checksum=module.sha1(dest),
md5sum=module.md5(dest)
)

from ansible.module_utils.basic import *
main()
71 changes: 71 additions & 0 deletions library/release_assignment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

import tarfile
import os
import shutil

def main():
module = AnsibleModule(
argument_spec={
'src': dict(required=True),
'users': dict(required=True, type='list'),
'overwrite': dict(default=False, type='bool')
}
)

src = module.params["src"]
users = module.params["users"]
overwrite = module.params["overwrite"]

# Open the tarfile, figure out the prefix
tf = tarfile.open(src, 'r:gz')
prefix = os.path.commonprefix(tf.getnames())
if prefix == '':
module.fail_json(msg="Archive has no common prefix")
tf.close()

# Extract the archive into the home directory of each user
changed = False
changed_users = []
for user in users:
homedir = os.path.abspath('/home/{}'.format(user))
if not homedir.startswith('/home/'):
module.fail_json(msg="Home directory is invalid: {}".format(homedir))
if not os.path.exists(homedir):
module.fail_json(msg="Home directory does not exist: {}".format(homedir))

root = os.path.abspath(os.path.join(homedir, prefix))
if not root.startswith(homedir):
module.fail_json(msg="Root path is invalid: {}".format(root))

# Skip existing directories, if we're not overwriting
if os.path.exists(root) and not overwrite:
continue
else:
changed = True
changed_users.append(user)

# Remove directory, if it already exists
if os.path.exists(root):
shutil.rmtree(root)

# Extract the archive
tf = tarfile.open(src, 'r:gz')
tf.extractall(homedir)
tf.close()

# Set permissions
module.run_command(
'chown -R {}:{} "{}"'.format(user, user, root), check_rc=True)
module.run_command(
'chmod -R u+rwX,og-rwx "{}"'.format(root), check_rc=True)

module.exit_json(
changed=changed,
prefix=prefix,
users=changed_users
)

from ansible.module_utils.basic import *
main()
37 changes: 37 additions & 0 deletions release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
- hosts: 127.0.0.1
connection: local
vars_files:
- ['secrets.yml', 'secrets.vault.yml']
- ['vars.local.yml', 'vars.yml']

tasks:
- name: create assignment
make_assignment:
src: '{{ assignment_path }}/{{ assignment }}/release'
name: '{{ assignment }}'
dest: '/tmp/assignment.tar.gz'
overwrite: yes

vars_prompt:
assignment: "Which assignment?"

- hosts: jupyterhub
vars_files:
- ['secrets.yml', 'secrets.vault.yml']
- ['vars.local.yml', 'vars.yml']

tasks:
- name: create /srv/assignments
file: path=/srv/assignments state=directory
sudo: yes

- name: upload assignment
copy:
src: '/tmp/assignment.tar.gz'
dest: '/srv/assignments/assignment.tar.gz'

- name: extract assignment to directories
release_assignment:
src: '/srv/assignments/assignment.tar.gz'
users: "{{ students | union(instructors) }}"
17 changes: 17 additions & 0 deletions script/release
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

ROOT=$(dirname $0)/..

if [ ! -e ${ROOT}//inventory ]; then
echo "Please create an inventory file with your hosts."
echo " cp inventory.example inventory"
exit 1
fi

if [ -e ${ROOT}/secrets.yml ]; then
VAULT_ARG=
else
VAULT_ARG=--ask-vault-pass
fi

exec ansible-playbook ${ROOT}/release.yml -i ${ROOT}/inventory ${VAULT_ARG} $@

0 comments on commit f017098

Please sign in to comment.