Skip to content
Permalink
Browse files

Scripts: Use constants for external program names.

This makes it much, much easier to replace the program
with one using an absolute path. This is necessary for
e.g. Guix to keep references to these external programs.
  • Loading branch information...
htgoebel committed Aug 8, 2019
1 parent 1845737 commit 740075d9d4fb89b81c0175e3431f9fb02e46ba55
Showing with 54 additions and 23 deletions.
  1. +6 −2 bin/debops
  2. +15 −6 bin/debops-padlock
  3. +5 −2 bin/debops-task
  4. +11 −7 bin/debops-update
  5. +12 −5 debops/__init__.py
  6. +5 −1 debops/cmds/__init__.py
@@ -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 740075d

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