diff --git a/rattail_fabric2/apache.py b/rattail_fabric2/apache.py index edf847e..1d6073b 100644 --- a/rattail_fabric2/apache.py +++ b/rattail_fabric2/apache.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2018 Lance Edgar +# Copyright © 2010-2019 Lance Edgar # # This file is part of Rattail. # @@ -57,6 +57,16 @@ def enable_mod(c, *names): c.sudo('a2enmod {}'.format(name)) +def enable_port(c, port): + """ + Tell Apache to listen on the given port. + """ + if not isinstance(port, int) and not port.isdigit(): + raise ValueError("port must be an integer") + if c.run("grep '^Listen {}' /etc/apache2/ports.conf".format(port), warn=True).failed: + c.sudo("""bash -c 'echo "Listen {}" >> /etc/apache2/ports.conf'""".format(port)) + + def enable_site(c, *names): """ Enable the given Apache site(s) diff --git a/rattail_fabric2/composer.py b/rattail_fabric2/composer.py new file mode 100644 index 0000000..98d12f6 --- /dev/null +++ b/rattail_fabric2/composer.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2019 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# Rattail. If not, see . +# +################################################################################ +""" +Fabric lib for Composer (PHP dependency manager) +""" + +from __future__ import unicode_literals, absolute_import + +from rattail_fabric2 import make_deploy, exists + + +deploy = make_deploy(__file__) + + +def install_globally(c): + """ + Install `composer.phar` in global location + """ + if not exists(c, '/usr/local/bin/composer.phar'): + deploy(c, 'composer/install-composer.sh', '/tmp/install-composer.sh', mode='0700', use_sudo=True) + c.sudo("bash -c 'cd /usr/local/bin; /tmp/install-composer.sh'") + c.sudo('rm /tmp/install-composer.sh') diff --git a/rattail_fabric2/core.py b/rattail_fabric2/core.py index 0d9f7a1..cd98a1f 100644 --- a/rattail_fabric2/core.py +++ b/rattail_fabric2/core.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2018 Lance Edgar +# Copyright © 2010-2019 Lance Edgar # # This file is part of Rattail. # @@ -214,6 +214,26 @@ class Deployer(object): from rattail_fabric2.backup import deploy_backup_app deploy_backup_app(c, self, envname, *args, **kwargs) + def certbot_account(self, c, uuid, localdir='certbot/account'): + """ + Deploy files to establish a certbot account on target server + """ + from .util import exists + + localdir = localdir.rstrip('/') + paths = [ + '/etc/letsencrypt/accounts', + '/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org', + '/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory', + ] + final_path = '{}/{}'.format(paths[-1], uuid) + paths.append(final_path) + if not exists(c, final_path, use_sudo=True): + mkdir(c, paths, mode='0700', use_sudo=True) + self.deploy(c, '{}/private_key.json'.format(localdir), '{}/private_key.json'.format(final_path), mode='0600', use_sudo=True) + self.deploy(c, '{}/meta.json'.format(localdir), '{}/meta.json'.format(final_path), use_sudo=True) + self.deploy(c, '{}/regr.json'.format(localdir), '{}/regr.json'.format(final_path), use_sudo=True) + def make_deploy(deploy_path, last_segment='deploy'): """ diff --git a/rattail_fabric2/corepos.py b/rattail_fabric2/corepos.py new file mode 100644 index 0000000..a7834b2 --- /dev/null +++ b/rattail_fabric2/corepos.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2019 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# Rattail. If not, see . +# +################################################################################ +""" +Fabric library for CORE-POS (IS4C) +""" + +from __future__ import unicode_literals, absolute_import + +import os + +from rattail_fabric2 import mysql, exists, mkdir + + +def install_fannie(c, rootdir, user='www-data', branch='version-2.10', + mysql_user='is4c', mysql_pass='is4c'): + """ + Install the Fannie app to the given location. + + Please note, this assumes composer is already installed and available. + """ + mkdir(c, rootdir, owner=user, use_sudo=True) + + # fannie source + is4c = os.path.join(rootdir, 'IS4C') + if not exists(c, is4c): + c.sudo('git clone https://github.com/CORE-POS/IS4C.git {}'.format(is4c), user=user) + c.sudo("bash -c 'cd {}; git checkout {}'".format(is4c, branch), user=user) + c.sudo("bash -c 'cd {}; git pull'".format(is4c), user=user) + + # fannie dependencies + mkdir(c, [os.path.join(is4c, 'vendor'), + os.path.join(is4c, 'fannie/src/javascript/composer-components')], + owner=user, use_sudo=True) + c.sudo("bash -c 'cd {}; composer.phar install'".format(is4c), user=user) + + # shadowread + # TODO: check first; only 'make' if necessary + c.sudo("bash -c 'cd {}/fannie/auth/shadowread; make'".format(is4c), user=user) + c.sudo("bash -c 'cd {}/fannie/auth/shadowread; make install'".format(is4c)) # as root! + + # fannie logging + c.sudo("bash -c 'cd {}/fannie/logs; touch fannie.log debug_fannie.log queries.log php-errors.log dayend.log'".format(is4c), user=user) + + # fannie databases + mysql.create_user(c, mysql_user, host='%', password=mysql_pass) + mysql.create_db(c, 'core_op', user="{}@'%'".format(mysql_user)) + mysql.create_db(c, 'core_trans', user="{}@'%'".format(mysql_user)) + mysql.create_db(c, 'trans_archive', user="{}@'%'".format(mysql_user)) diff --git a/rattail_fabric2/deploy/composer/install-composer.sh b/rattail_fabric2/deploy/composer/install-composer.sh new file mode 100755 index 0000000..6f01e38 --- /dev/null +++ b/rattail_fabric2/deploy/composer/install-composer.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig) +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');") + +if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] +then + >&2 echo 'ERROR: Invalid installer signature' + rm composer-setup.php + exit 1 +fi + +php composer-setup.php --quiet +RESULT=$? +rm composer-setup.php +exit $RESULT