Skip to content
Permalink
Browse files

Merge branch 'htgoebel-prognames-as-constants'

  • Loading branch information...
drybjed committed Sep 8, 2019
2 parents 1845737 + 2de2703 commit 7a15ccfeeb3646c7ecbf0bf065bc55a14e6826be
Showing with 61 additions and 23 deletions.
  1. +7 −0 CHANGELOG.rst
  2. +6 −2 bin/debops
  3. +15 −6 bin/debops-padlock
  4. +5 −2 bin/debops-task
  5. +11 −7 bin/debops-update
  6. +12 −5 debops/__init__.py
  7. +5 −1 debops/cmds/__init__.py
@@ -55,6 +55,13 @@ Updates of upstream application versions
``12.1``. This is the last release that supports Ruby 2.5 which is included
in Debian Buster.

General
'''''''

- External commands used in the DebOps scripts have been defined as constants
to allow easier changes of the command location in various operating systems,
for example Guix.

:ref:`debops.apt_preferences` role
''''''''''''''''''''''''''''''''''

@@ -59,6 +59,10 @@ ConfigFileHeader = """\
# You can manipulate the contents of this file via `.debops.cfg`.
"""

# External programms used. List here for easy substitution for
# hard-coded paths.
ANSIBLE_PLAYBOOK = 'ansible-playbook'


def write_config(filename, config):
cfgparser = configparser.ConfigParser()
@@ -131,7 +135,7 @@ def gen_ansible_cfg(filename, config, project_root, playbooks_path,
os.path.join(playbooks_path, "roles"),
"/etc/ansible/roles")))

ansible_version_out = subprocess.check_output(["ansible-playbook",
ansible_version_out = subprocess.check_output([ANSIBLE_PLAYBOOK,
"--version"]).decode()

# Get first line and split by spaces to get second 'word'.
@@ -256,7 +260,7 @@ def main(cmd_args):
print("Running Ansible playbooks:")
for element in play_list:
print(element)
return subprocess.call(['ansible-playbook'] + play_list + arg_list)
return subprocess.call([ANSIBLE_PLAYBOOK] + play_list + arg_list)
finally:
if revert_unlock:
padlock_lock(encfs_encrypted)
@@ -67,6 +67,14 @@ devrandom = os.environ.get('DEVRANDOM', "/dev/urandom")

SCRIPT_FILENAME = 'padlock-script'

# External programms used. List here for easy substitution for
# hard-coded paths.
ENCFS = 'encfs'
FIND = 'find'
FUSERMOUNT = 'fusermount'
UMOUNT = 'umount'
GPG = 'gpg'

# ---- DebOps environment setup ----


@@ -80,9 +88,9 @@ def main(subcommand_func, **kwargs):
# Make sure required commands are present
# OS X compatibility
if sys.platform == 'darwin':
require_commands('encfs', 'find', 'umount', 'gpg')
require_commands(ENCFS, FIND, UMOUNT, GPG)
else:
require_commands('encfs', 'find', 'fusermount', 'gpg')
require_commands(ENCFS, FIND, FUSERMOUNT, GPG)

inventory_path = find_inventorypath(project_root, required=False)
# If inventory hasn't been found automatically, assume it's the default
@@ -121,7 +129,7 @@ def init(encfs_decrypted, encfs_encrypted, recipients):
# Generate a random password and encrypt it with GPG keys of recipients.
print("Generating a random", ENCFS_KEYFILE_LENGTH, "char password")
pwd = gen_pwd()
gpg = subprocess.Popen(['gpg', '--encrypt', '--armor',
gpg = subprocess.Popen([GPG, '--encrypt', '--armor',
'--output', encfs_keyfile] + recipients,
stdin=subprocess.PIPE)
gpg.communicate(pwd.encode('utf-8'))
@@ -133,9 +141,10 @@ def init(encfs_decrypted, encfs_encrypted, recipients):
# NB2: We can not use padlock_unlock here, because the config file
# does not yet exist.
encfs = subprocess.Popen([
'encfs', encfs_encrypted, encfs_decrypted,
ENCFS, encfs_encrypted, encfs_decrypted,
'--extpass',
'gpg --decrypt --no-mdc-warning --output - '+shquote(encfs_keyfile)],
GPG + ' --decrypt --no-mdc-warning --output - '
+ shquote(encfs_keyfile)],
stdin=subprocess.PIPE)
encfs.communicate(('p\n'+pwd).encode('utf-8'))

@@ -154,7 +163,7 @@ def init(encfs_decrypted, encfs_encrypted, recipients):

# Protect the EncFS configuration file by also encrypting it with
# the GPG keys of recipients.
subprocess.call(['gpg', '--encrypt', '--armor',
subprocess.call([GPG, '--encrypt', '--armor',
'--output', encfs_configfile+'.asc']
+ recipients + [encfs_configfile])
os.remove(encfs_configfile)
@@ -49,11 +49,14 @@ project_root = find_debops_project(required=True)
# todo: need to decide on semantics!
# config = read_config(project_root)

# External programms used. List here for easy substitution for
# hard-coded paths.
ANSIBLE = 'ansible'

# ---- Main script ----

# Make sure required commands are present
require_commands('ansible')
require_commands(ANSIBLE)

ansible_inventory = find_inventorypath(project_root)

@@ -71,5 +74,5 @@ if INSECURE:
os.environ['ANSIBLE_HOST_KEY_CHECKING'] = 'False'

# Run ansible with custom environment
cmd = ['ansible'] + module + sys.argv[1:]
cmd = [ANSIBLE] + module + sys.argv[1:]
subprocess.call(cmd)
@@ -90,6 +90,10 @@ GALAXY_REQUIREMENTS = "galaxy/requirements.txt"
# Default Ansible Galaxy user account name
GALAXY_ACCOUNT = "debops"

# External programms used. List here for easy substitution for
# hard-coded paths.
GIT = 'git'


# ---- Functions ----

@@ -137,7 +141,7 @@ def clone_git_repository(repo_uri, branch, destination, dry_run=False):
if dry_run:
print("Cloning '%s' to %s..." % (repo_uri, destination))
else:
subprocess.call(['git', 'clone', '--quiet', '--branch', branch,
subprocess.call([GIT, 'clone', '--quiet', '--branch', branch,
repo_uri, destination])


@@ -152,22 +156,22 @@ def update_git_repository(path, dry_run=False, remote_uri=False):
os.chdir(path)

if dry_run:
subprocess.call(['git', 'fetch'])
subprocess.call(['git', 'diff', 'HEAD', 'origin', '--stat'])
subprocess.call([GIT, 'fetch'])
subprocess.call([GIT, 'diff', 'HEAD', 'origin', '--stat'])
else:
# Get the current sha of the head branch
current_sha = subprocess.check_output(
['git', 'rev-parse', 'HEAD']).strip()
[GIT, 'rev-parse', 'HEAD']).strip()

# Fetch it silently and store the new sha
subprocess.call(['git', 'fetch', '--quiet'])
subprocess.call([GIT, 'fetch', '--quiet'])
fetch_sha = subprocess.check_output(
['git', 'rev-parse', 'FETCH_HEAD']).strip()
[GIT, 'rev-parse', 'FETCH_HEAD']).strip()

if current_sha != fetch_sha:
print()
print('--')
subprocess.call(['git', 'merge', fetch_sha])
subprocess.call([GIT, 'merge', fetch_sha])

if remote_uri:
compare_uri = (remote_uri + '/compare/' + current_sha[:7]
@@ -93,6 +93,13 @@ def shquote(s):
# Length of the random EncFS password stored in encrypted keyfile
ENCFS_KEYFILE_LENGTH = 256

# External programms used. List here for easy substitution for
# hard-coded paths.
ENCFS = 'encfs'
FUSERMOUNT = 'fusermount'
UMOUNT = 'umount'
GPG = 'gpg'


# ---- Functions ----

@@ -180,9 +187,9 @@ def padlock_lock(encrypted_path):
return False
# OS X compatibility
if sys.platform == 'darwin':
subprocess.call(['umount', decrypted_path])
subprocess.call([UMOUNT, decrypted_path])
else:
subprocess.call(['fusermount', '-u', decrypted_path])
subprocess.call([FUSERMOUNT, '-u', decrypted_path])
return True


@@ -237,14 +244,14 @@ def padlock_unlock(encrypted_path):
# Start encfs. It will wait for input on the `configfile` named
# pipe.
encfs = subprocess.Popen([
'encfs', encrypted_path, decrypted_path,
ENCFS, encrypted_path, decrypted_path,
'--extpass',
'gpg --decrypt --no-mdc-warning --output - %s' % shquote(keyfile)])
GPG + ' --decrypt --no-mdc-warning --output - %s' % shquote(keyfile)])
# now decrypt the config and write it into the named pipe
with open(configfile, 'w') as fh:
# NB: gpg must write to stdout to avoid it is asking whether
# the file should be overwritten
subprocess.Popen(['gpg',
subprocess.Popen([GPG,
'--decrypt', '--no-mdc-warning', '--output', '-',
crypted_configfile], stdout=fh).wait()
encfs.wait()
@@ -55,6 +55,10 @@
# command line)
INSECURE = bool(os.environ.get('INSECURE', False))

# External programms used. List here for easy substitution for
# hard-coded paths.
WHICH = 'which'


def error_msg(message, severity="Error"):
"""
@@ -70,7 +74,7 @@ def require_commands(*cmd_names):
Check if required commands exist.
"""
def command_exists(cmd_name):
which = "where" if platform.system() == "Windows" else "which"
which = "where" if platform.system() == "Windows" else WHICH
return not subprocess.call([which, cmd_name],
stdout=DEVNULL, stderr=subprocess.STDOUT)

0 comments on commit 7a15ccf

Please sign in to comment.
You can’t perform that action at this time.