diff --git a/library/make_feedback.py b/library/make_feedback.py new file mode 100644 index 0000000..ac2f079 --- /dev/null +++ b/library/make_feedback.py @@ -0,0 +1,70 @@ +#!/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 user in os.listdir(src): + userpath = os.path.join(src, user) + for (dirpath, dirnames, filenames) in os.walk(userpath): + for filename in filenames: + fullpath = os.path.join(dirpath, filename) + arcpath = os.path.join(user, name + " Feedback", os.path.relpath(fullpath, userpath)) + 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() diff --git a/library/return_feedback.py b/library/return_feedback.py new file mode 100644 index 0000000..336625c --- /dev/null +++ b/library/return_feedback.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import os +import shutil + +def main(): + module = AnsibleModule( + argument_spec={ + 'src': dict(required=True), + 'overwrite': dict(default=False, type='bool') + } + ) + + src = module.params["src"] + overwrite = module.params["overwrite"] + + if not os.path.exists(src): + module.fail_json(msg="Source path does not exist") + + changed = False + changed_users = [] + + # copy feedback to the home directory of each user + users = sorted(os.listdir(src)) + 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)) + + userfiles = os.listdir(os.path.join(src, user)) + if len(userfiles) != 1: + module.fail_json( + msg="Expected exactly one directory per user, but {} had {}".format( + user, len(userfiles))) + + usrsource = os.path.join(src, user, userfiles[0]) + usrdest = os.path.join(homedir, userfiles[0]) + if not os.path.isdir(usrsource): + module.fail_json(msg="File for user {} is not a directory".format(user)) + + # remove existing feedback, or skip it + if os.path.exists(usrdest): + if not overwrite: + continue + else: + shutil.rmtree(usrdest) + + # copy the feedback + shutil.copytree(usrsource, usrdest) + + # set permissions + module.run_command( + 'chown -R {}:{} "{}"'.format(user, user, usrdest), check_rc=True) + module.run_command( + 'chmod -R u+rX,u-w,og-rwx "{}"'.format(usrdest), check_rc=True) + + changed = True + changed_users.append(user) + + module.exit_json( + changed=changed, + users=changed_users + ) + +from ansible.module_utils.basic import * +main() diff --git a/return.yml b/return.yml new file mode 100644 index 0000000..536938c --- /dev/null +++ b/return.yml @@ -0,0 +1,45 @@ +--- +- hosts: 127.0.0.1 + connection: local + vars_files: + - 'secrets.vault.yml' + - ['vars.local.yml', 'vars.yml'] + + tasks: + - name: create feedback + make_feedback: + src: '{{ assignment_path }}/{{ assignment }}/feedback' + name: '{{ assignment }}' + dest: '/tmp/feedback.tar.gz' + overwrite: yes + + vars_prompt: + assignment: "Which assignment?" + +- hosts: jupyterhub_host + vars_files: + - 'secrets.vault.yml' + - 'users.vault.yml' + - ['vars.local.yml', 'vars.yml'] + + tasks: + - name: remove existing feedback + file: path=/srv/assignments/feedback state=absent + sudo: yes + + - name: create /srv/assignments/feedback + file: path=/srv/assignments/feedback state=directory + sudo: yes + + - name: upload and extract feedback + unarchive: + src: '/tmp/feedback.tar.gz' + dest: '/srv/assignments/feedback' + sudo: yes + + - name: extract feedback to user directories + return_feedback: + src: '/srv/assignments/feedback' + #overwrite: yes + overwrite: no + sudo: yes diff --git a/script/return b/script/return new file mode 100755 index 0000000..78d5991 --- /dev/null +++ b/script/return @@ -0,0 +1,12 @@ +#!/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 + +VAULT_ARG="--vault-password-file ${ROOT}/vault-password" +exec ansible-playbook ${ROOT}/return.yml -i ${ROOT}/inventory ${VAULT_ARG} $@