Upgrade to exa v0.9.0-dev from repos.
This commit is contained in:
parent
061e9b99f7
commit
b7f4b7e65b
180
debops
Executable file
180
debops
Executable file
@ -0,0 +1,180 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
debops: run ansible-playbook with some customization
|
||||||
|
"""
|
||||||
|
# Copyright (C) 2014-2015 Hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
|
# Part of the DebOps - https://debops.org/
|
||||||
|
|
||||||
|
# This program 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.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not,
|
||||||
|
# write to the Free Software Foundation, Inc., 59
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# An on-line copy of the GNU General Public License can
|
||||||
|
# be downloaded from the FSF web page at:
|
||||||
|
# https://www.gnu.org/copyleft/gpl.html
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import ConfigParser
|
||||||
|
|
||||||
|
import ansible
|
||||||
|
|
||||||
|
from debops import *
|
||||||
|
from debops.cmds import *
|
||||||
|
|
||||||
|
__author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__copyright__ = "Copyright 2014-2015 by Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__licence__ = "GNU General Public License version 3 (GPL v3) or later"
|
||||||
|
|
||||||
|
|
||||||
|
PATHSEP = ':'
|
||||||
|
|
||||||
|
ConfigFileHeader = """\
|
||||||
|
# Ansible configuration file generated by DebOps, all changes will be lost.
|
||||||
|
# You can manipulate the contents of this file via `.debops.cfg`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def write_config(filename, config):
|
||||||
|
cfgparser = ConfigParser.ConfigParser()
|
||||||
|
for section, pairs in config.items():
|
||||||
|
cfgparser.add_section(section)
|
||||||
|
for option, value in pairs.items():
|
||||||
|
cfgparser.set(section, option, value)
|
||||||
|
|
||||||
|
with open(filename, "w") as fh:
|
||||||
|
print(ConfigFileHeader, file=fh)
|
||||||
|
cfgparser.write(fh)
|
||||||
|
|
||||||
|
|
||||||
|
def gen_ansible_cfg(filename, config, project_root, playbooks_path,
|
||||||
|
inventory_path):
|
||||||
|
# Generate Ansible configuration file
|
||||||
|
|
||||||
|
def custom_paths(type):
|
||||||
|
if type in defaults:
|
||||||
|
# prepend value from .debops.cfg
|
||||||
|
yield defaults[type]
|
||||||
|
yield os.path.join(project_root, "ansible", type)
|
||||||
|
yield os.path.join(playbooks_path, type)
|
||||||
|
yield os.path.join("/usr/share/ansible/", type)
|
||||||
|
|
||||||
|
# Add custom configuration options to ansible.cfg: Take values
|
||||||
|
# from [ansible ...] sections of the .debops.cfg file
|
||||||
|
# Note: To set debops default values, use debops.config.DEFAULTS
|
||||||
|
cfg = dict((sect.split(None, 1)[1], pairs)
|
||||||
|
for sect, pairs in config.items() if sect.startswith('ansible '))
|
||||||
|
|
||||||
|
defaults = cfg.setdefault('defaults', {})
|
||||||
|
defaults['inventory'] = inventory_path
|
||||||
|
defaults['roles_path'] = PATHSEP.join(filter(None, (
|
||||||
|
defaults.get('roles_path'), # value from .debops.cfg or None
|
||||||
|
os.path.join(project_root, "roles"),
|
||||||
|
os.path.join(project_root, "ansible", "roles"),
|
||||||
|
os.path.join(playbooks_path, "..", "roles"),
|
||||||
|
os.path.join(playbooks_path, "roles"),
|
||||||
|
"/etc/ansible/roles")))
|
||||||
|
for plugin_type in ('action', 'callback', 'connection',
|
||||||
|
'filter', 'lookup', 'vars'):
|
||||||
|
plugin_type = plugin_type+"_plugins"
|
||||||
|
defaults[plugin_type] = PATHSEP.join(custom_paths(plugin_type))
|
||||||
|
|
||||||
|
if ansible.__version__ >= "1.7":
|
||||||
|
# work around a bug obviously introduced in 1.7, see
|
||||||
|
# https://github.com/ansible/ansible/issues/8555
|
||||||
|
if ' ' in defaults[plugin_type]:
|
||||||
|
defaults[plugin_type] = PATHSEP.join(
|
||||||
|
'"%s"' % p for p in defaults[plugin_type].split(PATHSEP))
|
||||||
|
|
||||||
|
defaults['library'] = PATHSEP.join(custom_paths('library'))
|
||||||
|
|
||||||
|
write_config(filename, cfg)
|
||||||
|
|
||||||
|
|
||||||
|
def main(cmd_args):
|
||||||
|
project_root = find_debops_project(required=True)
|
||||||
|
config = read_config(project_root)
|
||||||
|
playbooks_path = find_playbookpath(config, project_root, required=True)
|
||||||
|
|
||||||
|
# Make sure required commands are present
|
||||||
|
require_commands('ansible-playbook')
|
||||||
|
|
||||||
|
def find_playbook(playbook):
|
||||||
|
tries = [
|
||||||
|
(project_root, "playbooks", playbook),
|
||||||
|
(project_root, "ansible", "playbooks", playbook),
|
||||||
|
(playbooks_path, playbook),
|
||||||
|
]
|
||||||
|
|
||||||
|
if 'playbooks_path' in config['paths']:
|
||||||
|
tries += [(custom_path, playbook) for custom_path in
|
||||||
|
config['paths']['playbooks_path'].split(PATHSEP)]
|
||||||
|
|
||||||
|
for parts in tries:
|
||||||
|
play = os.path.join(*parts)
|
||||||
|
if os.path.isfile(play):
|
||||||
|
return play
|
||||||
|
|
||||||
|
# Check if user specified a potential playbook name as the first
|
||||||
|
# argument. If yes, use it as the playbook name and remove it from
|
||||||
|
# the argument list
|
||||||
|
play = None
|
||||||
|
if len(cmd_args) > 0:
|
||||||
|
maybe_play = cmd_args[0]
|
||||||
|
if os.path.isfile(maybe_play):
|
||||||
|
play = maybe_play
|
||||||
|
else:
|
||||||
|
play = find_playbook(maybe_play + ".yml")
|
||||||
|
if play:
|
||||||
|
cmd_args.pop(0)
|
||||||
|
del maybe_play
|
||||||
|
if not play:
|
||||||
|
play = find_playbook("site.yml")
|
||||||
|
|
||||||
|
inventory_path = find_inventorypath(project_root)
|
||||||
|
os.environ['ANSIBLE_HOSTS'] = inventory_path
|
||||||
|
|
||||||
|
ansible_config_file = os.path.join(project_root, ANSIBLE_CONFIG_FILE)
|
||||||
|
os.environ['ANSIBLE_CONFIG'] = os.path.abspath(ansible_config_file)
|
||||||
|
gen_ansible_cfg(ansible_config_file, config, project_root, playbooks_path,
|
||||||
|
inventory_path)
|
||||||
|
|
||||||
|
# Allow insecure SSH connections if requested
|
||||||
|
if INSECURE:
|
||||||
|
os.environ['ANSIBLE_HOST_KEY_CHECKING'] = 'False'
|
||||||
|
|
||||||
|
# Create path to EncFS encrypted directory, based on inventory name
|
||||||
|
encfs_encrypted = os.path.join(os.path.dirname(inventory_path),
|
||||||
|
ENCFS_PREFIX + SECRET_NAME)
|
||||||
|
|
||||||
|
# Check if encrypted secret directory exists and use it
|
||||||
|
revert_unlock = padlock_unlock(encfs_encrypted)
|
||||||
|
try:
|
||||||
|
# Run ansible-playbook with custom environment
|
||||||
|
print("Running Ansible playbook from:")
|
||||||
|
print(play, "...")
|
||||||
|
return subprocess.call(['ansible-playbook', play] + cmd_args)
|
||||||
|
finally:
|
||||||
|
if revert_unlock:
|
||||||
|
padlock_lock(encfs_encrypted)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
sys.exit(main(sys.argv[1:]))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise SystemExit('... aborted')
|
111
debops-defaults
Executable file
111
debops-defaults
Executable file
@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
debops-defaults: aggregate all defaults from Ansible roles into one stream
|
||||||
|
"""
|
||||||
|
# Copyright (C) 2014-2015 Hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
|
# Part of the DebOps - https://debops.org/
|
||||||
|
|
||||||
|
# This program 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.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not,
|
||||||
|
# write to the Free Software Foundation, Inc., 59
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# An on-line copy of the GNU General Public License can
|
||||||
|
# be downloaded from the FSF web page at:
|
||||||
|
# https://www.gnu.org/copyleft/gpl.html
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import codecs
|
||||||
|
import subprocess
|
||||||
|
import glob
|
||||||
|
import argparse
|
||||||
|
import errno
|
||||||
|
|
||||||
|
reload(sys)
|
||||||
|
sys.setdefaultencoding('utf-8')
|
||||||
|
|
||||||
|
from debops import *
|
||||||
|
from debops.cmds import *
|
||||||
|
|
||||||
|
__author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__copyright__ = "Copyright 2014-2015 by Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__licence__ = "GNU General Public License version 3 (GPL v3) or later"
|
||||||
|
|
||||||
|
def cat(filename, outstream):
|
||||||
|
try:
|
||||||
|
fh = codecs.open(filename, encoding=sys.getdefaultencoding())
|
||||||
|
except IOError, e:
|
||||||
|
# This should only happen if the user listed a unknown role.
|
||||||
|
outstream.write('%s: %s\n' % (e.strerror, e.filename))
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
# Read input file as Unicode object and pass it to outstream.
|
||||||
|
outstream.write(fh.read())
|
||||||
|
finally:
|
||||||
|
fh.close()
|
||||||
|
|
||||||
|
def aggregate_defaults(playbooks_path, role_list, outstream):
|
||||||
|
# Aggregate role/defaults/main.yml files from all roles into one stream
|
||||||
|
roles_path = os.path.normpath(os.path.join(playbooks_path, '..', 'roles'))
|
||||||
|
if role_list:
|
||||||
|
for role in role_list:
|
||||||
|
if not '.' in role:
|
||||||
|
role = ROLE_PREFIX + '.' + role
|
||||||
|
fn = os.path.join(roles_path, role, 'defaults', 'main.yml')
|
||||||
|
cat(fn, outstream=outstream)
|
||||||
|
else:
|
||||||
|
for fn in glob.glob(os.path.join(roles_path,
|
||||||
|
'*', 'defaults', 'main.yml')):
|
||||||
|
cat(fn, outstream=outstream)
|
||||||
|
|
||||||
|
# ---- DebOps environment setup ----
|
||||||
|
|
||||||
|
def main(role_list):
|
||||||
|
project_root = find_debops_project(required=False)
|
||||||
|
config = read_config(project_root)
|
||||||
|
playbooks_path = find_playbookpath(config, project_root, required=True)
|
||||||
|
|
||||||
|
# Make sure required commands are present
|
||||||
|
require_commands('view')
|
||||||
|
|
||||||
|
if sys.stdout.isatty():
|
||||||
|
# if script is run as standalone, redirect to view
|
||||||
|
view = subprocess.Popen(['view', '+set ft=yaml', '-'],
|
||||||
|
stdin=subprocess.PIPE)
|
||||||
|
try:
|
||||||
|
aggregate_defaults(playbooks_path, role_list, view.stdin)
|
||||||
|
except IOError, e:
|
||||||
|
if e.errno not in (errno.EPIPE, errno.EINVAL):
|
||||||
|
# "Invalid pipe" or "Invalid argument"
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
view.communicate()
|
||||||
|
else:
|
||||||
|
# else, send everything to stdout
|
||||||
|
aggregate_defaults(playbooks_path, role_list, sys.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('role', nargs='*')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
main(args.role)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise SystemExit('... aborted')
|
205
debops-init
Executable file
205
debops-init
Executable file
@ -0,0 +1,205 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
debops-init: create a new DebOps project directory
|
||||||
|
"""
|
||||||
|
# Copyright (C) 2014-2015 Hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
|
# Part of the DebOps - https://debops.org/
|
||||||
|
|
||||||
|
# This program 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.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not,
|
||||||
|
# write to the Free Software Foundation, Inc., 59
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# An on-line copy of the GNU General Public License can
|
||||||
|
# be downloaded from the FSF web page at:
|
||||||
|
# https://www.gnu.org/copyleft/gpl.html
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
import codecs
|
||||||
|
import subprocess
|
||||||
|
import glob
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from debops import *
|
||||||
|
from debops.cmds import *
|
||||||
|
|
||||||
|
__author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__copyright__ = "Copyright 2014-2015 by Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__licence__ = "GNU General Public License version 3 (GPL v3) or later"
|
||||||
|
|
||||||
|
SKEL_DIRS = (
|
||||||
|
os.path.join("ansible", INVENTORY, "group_vars", "all"),
|
||||||
|
os.path.join("ansible", INVENTORY, "host_vars"),
|
||||||
|
os.path.join("ansible", "playbooks"),
|
||||||
|
os.path.join("ansible", "roles"),
|
||||||
|
)
|
||||||
|
|
||||||
|
DEFAULT_DEBOPS_CONFIG = """
|
||||||
|
# -*- conf -*-
|
||||||
|
|
||||||
|
[paths]
|
||||||
|
;data-home: /opt/debops
|
||||||
|
|
||||||
|
[ansible defaults]
|
||||||
|
display_skipped_hosts = False
|
||||||
|
retry_files_enabled = False
|
||||||
|
;callback_plugins = /my/plugins/callback
|
||||||
|
;roles_path = /my/roles
|
||||||
|
|
||||||
|
[ansible paramiko]
|
||||||
|
;record_host_keys=True
|
||||||
|
|
||||||
|
[ansible ssh_connection]
|
||||||
|
;ssh_args = -o ControlMaster=auto -o ControlPersist=60s
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEFAULT_GITIGNORE = """\
|
||||||
|
ansible/{SECRET_NAME}
|
||||||
|
{SECRET_NAME}
|
||||||
|
{ENCFS_PREFIX}{SECRET_NAME}
|
||||||
|
ansible.cfg
|
||||||
|
|
||||||
|
#-- python
|
||||||
|
*.py[co]
|
||||||
|
|
||||||
|
#-- vim
|
||||||
|
[._]*.s[a-w][a-z]
|
||||||
|
[._]s[a-w][a-z]
|
||||||
|
*.un~
|
||||||
|
Session.vim
|
||||||
|
.netrwhist
|
||||||
|
*~
|
||||||
|
|
||||||
|
#-- Emacs
|
||||||
|
\#*\#
|
||||||
|
/.emacs.desktop
|
||||||
|
/.emacs.desktop.lock
|
||||||
|
*.elc
|
||||||
|
auto-save-list
|
||||||
|
tramp
|
||||||
|
.\#*
|
||||||
|
|
||||||
|
#-- SublimeText
|
||||||
|
*.sublime-workspace
|
||||||
|
#*.sublime-project
|
||||||
|
|
||||||
|
#-- sftp configuration file
|
||||||
|
sftp-config.json
|
||||||
|
"""
|
||||||
|
|
||||||
|
HOSTS_FILE_HEADER = """\
|
||||||
|
# This is an Ansible inventory file in INI format. You can define a list of
|
||||||
|
# hosts and groups to be managed by this particular inventory.
|
||||||
|
|
||||||
|
# Hosts listed under [debops_all_hosts] will have common DebOps plays
|
||||||
|
# ran against them. It will include services such as iptables, DNS, Postfix,
|
||||||
|
# sshd configuration and more.
|
||||||
|
#
|
||||||
|
# View the list here:
|
||||||
|
# https://github.com/debops/debops-playbooks/blob/master/playbooks/common.yml
|
||||||
|
#
|
||||||
|
# You should check Getting Started guide for useful suggestions:
|
||||||
|
# https://docs.debops.org/en/latest/debops-playbooks/docs/guides/getting-started.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
HOSTS_FILE_CONTENT_CONTROLER = """
|
||||||
|
# Your host is eligible to be managed by DebOps' common playbook. If you want
|
||||||
|
# that functionality and more, then uncomment your hostname below.
|
||||||
|
|
||||||
|
[debops_all_hosts]
|
||||||
|
#%s ansible_connection=local
|
||||||
|
""" % platform.node()
|
||||||
|
|
||||||
|
HOSTS_FILE_CONTENT_NO_CONTROLER = """
|
||||||
|
# Your host was not detected as compatible with DebOps playbooks, so you will
|
||||||
|
# not be able to leverage the above features on your current operating system.
|
||||||
|
# You can however use a virtual machine as the Ansible Controller.
|
||||||
|
|
||||||
|
[debops_all_hosts]
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def write_file(filename, *content):
|
||||||
|
"""
|
||||||
|
If file:`filename` does not exist, create it and write
|
||||||
|
var:`content` into it.
|
||||||
|
"""
|
||||||
|
if not os.path.exists(filename):
|
||||||
|
with open(filename, "w") as fh:
|
||||||
|
fh.writelines(content)
|
||||||
|
|
||||||
|
|
||||||
|
def write_config_files(project_root):
|
||||||
|
"""
|
||||||
|
Create the default debops-config files in the dir:`project_root`
|
||||||
|
directory.
|
||||||
|
"""
|
||||||
|
# Create .debops.cfg
|
||||||
|
write_file(os.path.join(project_root, DEBOPS_CONFIG), DEFAULT_DEBOPS_CONFIG)
|
||||||
|
# Create .gitignore
|
||||||
|
write_file(os.path.join(project_root, '.gitignore'),
|
||||||
|
DEFAULT_GITIGNORE.format(SECRET_NAME=SECRET_NAME, ENCFS_PREFIX=ENCFS_PREFIX))
|
||||||
|
|
||||||
|
hosts_filename = os.path.join(project_root, "ansible", INVENTORY, "hosts")
|
||||||
|
# Swap in different hosts file content depending on the host's OS/distro
|
||||||
|
if (platform.system() == "Linux" and
|
||||||
|
platform.linux_distribution()[0].lower() in ("debian", "ubuntu")):
|
||||||
|
write_file(hosts_filename,
|
||||||
|
HOSTS_FILE_HEADER, HOSTS_FILE_CONTENT_CONTROLER)
|
||||||
|
else:
|
||||||
|
write_file(hosts_filename,
|
||||||
|
HOSTS_FILE_HEADER, HOSTS_FILE_CONTENT_NO_CONTROLER)
|
||||||
|
|
||||||
|
|
||||||
|
def main(project_root):
|
||||||
|
orig_project_root = project_root
|
||||||
|
project_root = os.path.abspath(project_root)
|
||||||
|
|
||||||
|
#-- Check for existing debops project directory
|
||||||
|
debops_project_root = find_debops_project(project_root, required=False)
|
||||||
|
|
||||||
|
# Exit if DebOps configuration file has been found in project_dir
|
||||||
|
if os.path.exists(os.path.join(project_root, DEBOPS_CONFIG)):
|
||||||
|
error_msg("%s is already a DebOps project directory" % project_root)
|
||||||
|
|
||||||
|
# Exit if we are in a DebOps project dir and nested project would be created
|
||||||
|
if debops_project_root:
|
||||||
|
error_msg("You are inside %s project already" % debops_project_root)
|
||||||
|
|
||||||
|
#-- Main script
|
||||||
|
|
||||||
|
print("Creating new DebOps project directory in", orig_project_root, "...")
|
||||||
|
|
||||||
|
# Create base project directories
|
||||||
|
for skel_dir in SKEL_DIRS:
|
||||||
|
skel_dir = os.path.join(project_root, skel_dir)
|
||||||
|
if not os.path.isdir(skel_dir):
|
||||||
|
os.makedirs(skel_dir)
|
||||||
|
# Write default config files
|
||||||
|
write_config_files(project_root)
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('project_dir', default=os.curdir)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
main(args.project_dir)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise SystemExit('... aborted')
|
187
debops-padlock
Executable file
187
debops-padlock
Executable file
@ -0,0 +1,187 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
debops-padlock: encrypt secret directory with EncFS and GPG
|
||||||
|
"""
|
||||||
|
# Copyright (C) 2014-2015 Hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
|
# Part of the DebOps - https://debops.org/
|
||||||
|
|
||||||
|
# This program 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.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not,
|
||||||
|
# write to the Free Software Foundation, Inc., 59
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# An on-line copy of the GNU General Public License can
|
||||||
|
# be downloaded from the FSF web page at:
|
||||||
|
# https://www.gnu.org/copyleft/gpl.html
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import argparse
|
||||||
|
import itertools
|
||||||
|
import stat
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from pkg_resources import resource_filename
|
||||||
|
|
||||||
|
from debops import *
|
||||||
|
from debops.cmds import *
|
||||||
|
|
||||||
|
__author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__copyright__ = "Copyright 2014-2015 by Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__licence__ = "GNU General Public License version 3 (GPL v3) or later"
|
||||||
|
|
||||||
|
def gen_pwd():
|
||||||
|
from string import ascii_letters, digits, punctuation
|
||||||
|
import random
|
||||||
|
ALLCHARS = digits + ascii_letters + punctuation
|
||||||
|
ALLCHARS = digits + ascii_letters + '-_!@#$%^&*()_+{}|:<>?='
|
||||||
|
pwd = ''.join(random.choice(ALLCHARS) for i in range(ENCFS_KEYFILE_LENGTH))
|
||||||
|
return pwd
|
||||||
|
|
||||||
|
|
||||||
|
# Randomness source for EncFS keyfile generation
|
||||||
|
devrandom = os.environ.get('DEVRANDOM', "/dev/urandom")
|
||||||
|
|
||||||
|
SCRIPT_FILENAME = 'padlock-script'
|
||||||
|
|
||||||
|
# ---- DebOps environment setup ----
|
||||||
|
|
||||||
|
def main(subcommand_func, **kwargs):
|
||||||
|
project_root = find_debops_project(required=True)
|
||||||
|
# :todo: Source DebOps configuration file
|
||||||
|
#[ -r ${debops_config} ] && source ${debops_config}
|
||||||
|
|
||||||
|
# ---- Main script ----
|
||||||
|
|
||||||
|
# Make sure required commands are present
|
||||||
|
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
|
||||||
|
if not inventory_path:
|
||||||
|
inventory_path = os.path.join(project_root, 'ansible', INVENTORY)
|
||||||
|
|
||||||
|
# Create names of EncFS encrypted and decrypted directories, based on
|
||||||
|
# inventory name (absolute paths are specified)
|
||||||
|
encfs_encrypted = os.path.join(os.path.dirname(inventory_path),
|
||||||
|
ENCFS_PREFIX + SECRET_NAME)
|
||||||
|
encfs_decrypted = os.path.join(os.path.dirname(inventory_path),
|
||||||
|
SECRET_NAME)
|
||||||
|
subcommand_func(encfs_decrypted, encfs_encrypted, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def init(encfs_decrypted, encfs_encrypted, recipients):
|
||||||
|
# EncFS cannot create encrypted directory if directory with
|
||||||
|
# decrypted data is not empty
|
||||||
|
if not os.path.exists(encfs_decrypted):
|
||||||
|
os.makedirs(encfs_decrypted)
|
||||||
|
elif os.listdir(encfs_decrypted):
|
||||||
|
error_msg("secret directory not empty")
|
||||||
|
|
||||||
|
# Quit if encrypted directory already exists.
|
||||||
|
if os.path.isdir(encfs_encrypted):
|
||||||
|
error_msg("EncFS directory already exists")
|
||||||
|
os.makedirs(encfs_encrypted)
|
||||||
|
|
||||||
|
encfs_keyfile = os.path.join(encfs_encrypted, ENCFS_KEYFILE)
|
||||||
|
encfs_configfile = os.path.join(encfs_encrypted, ENCFS_CONFIGFILE)
|
||||||
|
|
||||||
|
# put a `-r` in front of each recipient for passing as args to gpg
|
||||||
|
recipients = list(itertools.chain.from_iterable(['-r', r]
|
||||||
|
for r in 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',
|
||||||
|
'--output', encfs_keyfile] + recipients,
|
||||||
|
stdin=subprocess.PIPE)
|
||||||
|
gpg.communicate(pwd)
|
||||||
|
|
||||||
|
# Mount the encfs to the config file will be written. Tell encfs
|
||||||
|
# it to ask gpg for the password.
|
||||||
|
# NB1: Alternativly we could use --stdinpass, but using --extpass makes
|
||||||
|
# the user check if she has the correct passphrase early.
|
||||||
|
# NB2: We can not use padlock_unlock here, because the config file
|
||||||
|
# does not yet exist.
|
||||||
|
encfs = subprocess.Popen([
|
||||||
|
'encfs', encfs_encrypted, encfs_decrypted,
|
||||||
|
'--extpass', 'gpg --no-mdc-warning --output - '+shquote(encfs_keyfile)],
|
||||||
|
stdin=subprocess.PIPE)
|
||||||
|
encfs.communicate('p\n'+pwd)
|
||||||
|
|
||||||
|
# Create padlock-script
|
||||||
|
padlock_script = os.path.join(encfs_encrypted, PADLOCK_CMD)
|
||||||
|
|
||||||
|
# :todo: use resource_stream
|
||||||
|
shutil.copy(resource_filename('debops', SCRIPT_FILENAME), padlock_script)
|
||||||
|
os.chmod(padlock_script,
|
||||||
|
os.stat(padlock_script).st_mode|stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH)
|
||||||
|
|
||||||
|
# Lock the EncFS directory after creation
|
||||||
|
time.sleep(0.5) # :fixme: why sleeping here?
|
||||||
|
padlock_lock(encfs_encrypted)
|
||||||
|
|
||||||
|
# Protect the EncFS configuration file by also encrypting it with
|
||||||
|
# the GPG keys of recipients.
|
||||||
|
subprocess.call(['gpg', '--encrypt', '--armor',
|
||||||
|
'--output', encfs_configfile+'.asc']
|
||||||
|
+ recipients + [encfs_configfile])
|
||||||
|
os.remove(encfs_configfile)
|
||||||
|
|
||||||
|
|
||||||
|
def lock(encfs_decrypted, encfs_encrypted, verbose):
|
||||||
|
# Unmount the directory if it is mounted
|
||||||
|
if padlock_lock(encfs_encrypted):
|
||||||
|
if verbose: print("Locked!")
|
||||||
|
else:
|
||||||
|
if verbose: print("Is already locked.")
|
||||||
|
|
||||||
|
|
||||||
|
def unlock(encfs_decrypted, encfs_encrypted, verbose):
|
||||||
|
# Mount the directory it if it is unmounted
|
||||||
|
if padlock_unlock(encfs_encrypted):
|
||||||
|
if verbose: print("Unlocked!")
|
||||||
|
else:
|
||||||
|
if verbose: print("Is already unlocked.")
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(
|
||||||
|
help='action to perform. Use `%(prog)s --help <action>` for further help.')
|
||||||
|
|
||||||
|
p = subparsers.add_parser('init')
|
||||||
|
p.add_argument('recipients', nargs='*',
|
||||||
|
help=("GPG recipients for which the secret key should be "
|
||||||
|
"encrypted for (name, e-mail or key-id)"))
|
||||||
|
p.set_defaults(subcommand_func=init)
|
||||||
|
|
||||||
|
p = subparsers.add_parser('unlock')
|
||||||
|
p.add_argument('-v', '--verbose', action='store_true', help="be verbose")
|
||||||
|
p.set_defaults(subcommand_func=unlock)
|
||||||
|
|
||||||
|
p = subparsers.add_parser('lock')
|
||||||
|
p.add_argument('-v', '--verbose', action='store_true', help="be verbose")
|
||||||
|
p.set_defaults(subcommand_func=lock)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
main(**vars(args))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise SystemExit('... aborted')
|
74
debops-task
Executable file
74
debops-task
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
debops-task: run ansible with some customization
|
||||||
|
"""
|
||||||
|
# Copyright (C) 2014-2015 Hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
|
# Part of the DebOps - https://debops.org/
|
||||||
|
|
||||||
|
# This program 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.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not,
|
||||||
|
# write to the Free Software Foundation, Inc., 59
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# An on-line copy of the GNU General Public License can
|
||||||
|
# be downloaded from the FSF web page at:
|
||||||
|
# https://www.gnu.org/copyleft/gpl.html
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from debops import *
|
||||||
|
from debops.cmds import *
|
||||||
|
|
||||||
|
__author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__copyright__ = "Copyright 2014-2015 by Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__licence__ = "GNU General Public License version 3 (GPL v3) or later"
|
||||||
|
|
||||||
|
|
||||||
|
DEBOPS_RESERVED_NAMES = ["task", "init", "update", "defaults", "padlock"]
|
||||||
|
|
||||||
|
# ---- DebOps environment setup ----
|
||||||
|
|
||||||
|
# Find DebOps configuration file
|
||||||
|
project_root = find_debops_project(required=True)
|
||||||
|
# Source DebOps configuration file
|
||||||
|
###----- todo: need to decide on semantics!
|
||||||
|
#config = read_config(project_root)
|
||||||
|
|
||||||
|
|
||||||
|
# ---- Main script ----
|
||||||
|
|
||||||
|
# Make sure required commands are present
|
||||||
|
require_commands('ansible')
|
||||||
|
|
||||||
|
ansible_inventory = find_inventorypath(project_root)
|
||||||
|
|
||||||
|
# Get module name from the script name if script is named 'debops-*'
|
||||||
|
module_name = SCRIPT_NAME.rsplit('-', 1)[-1]
|
||||||
|
if module_name not in DEBOPS_RESERVED_NAMES:
|
||||||
|
module = ["-m", module_name]
|
||||||
|
else:
|
||||||
|
module = []
|
||||||
|
|
||||||
|
os.environ['ANSIBLE_HOSTS'] = os.path.abspath(ansible_inventory)
|
||||||
|
|
||||||
|
# Allow insecure SSH connections if requested
|
||||||
|
if INSECURE:
|
||||||
|
os.environ['ANSIBLE_HOST_KEY_CHECKING'] = 'False'
|
||||||
|
|
||||||
|
# Run ansible with custom environment
|
||||||
|
cmd = ['ansible'] + module + sys.argv[1:]
|
||||||
|
subprocess.call(cmd)
|
247
debops-update
Executable file
247
debops-update
Executable file
@ -0,0 +1,247 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
("""
|
||||||
|
debops-update: install or update DebOps playbooks and roles
|
||||||
|
"""
|
||||||
|
# Copyright (C) 2014-2015 Hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
|
# Part of the DebOps - https://debops.org/
|
||||||
|
|
||||||
|
|
||||||
|
# This program 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.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not,
|
||||||
|
# write to the Free Software Foundation, Inc., 59
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# An on-line copy of the GNU General Public License can
|
||||||
|
# be downloaded from the FSF web page at:
|
||||||
|
# https://www.gnu.org/copyleft/gpl.html
|
||||||
|
|
||||||
|
"""
|
||||||
|
This script can be used to install or update installed DebOps playbooks and
|
||||||
|
roles to current or specified version. By default it works on the installed
|
||||||
|
playbook in users $HOME/.local/share/debops directory, but it can also be
|
||||||
|
used on locally installed playbooks and roles in current directory.
|
||||||
|
|
||||||
|
Short usage guide:
|
||||||
|
|
||||||
|
- 'debops-update' will check if we are in DebOps project directory
|
||||||
|
('.debops.cfg' exists)
|
||||||
|
* if yes, it will check if 'debops-playbooks/playbooks/site.yml' exists
|
||||||
|
* if yes, update playbooks and roles in $PWD
|
||||||
|
* if no, check if DebOps playbooks are installed in known places,
|
||||||
|
like ~/.local/share/debops
|
||||||
|
* if yes, update playbooks in a place that they are installed at
|
||||||
|
* if no, install DebOps playbooks in
|
||||||
|
~/.local/share/debops/debops-playbooks
|
||||||
|
|
||||||
|
- 'debops-update path/to/dir' will check if specified directory exists
|
||||||
|
* if no, create it
|
||||||
|
* if yes, check if DebOps playbooks are installed at $path/debops-playbooks
|
||||||
|
* if yes, update them
|
||||||
|
* if no, install DebOps playbooks at $path/debops-playbooks
|
||||||
|
|
||||||
|
""")
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from debops import *
|
||||||
|
from debops.cmds import *
|
||||||
|
|
||||||
|
__author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__copyright__ = "Copyright 2014-2015 by Hartmut Goebel <h.goebel@crazy-compilers.com>"
|
||||||
|
__licence__ = "GNU General Public License version 3 (GPL v3) or later"
|
||||||
|
|
||||||
|
|
||||||
|
# ---- Configuration variables ----
|
||||||
|
|
||||||
|
# Default URI of DebOps (user https for server authentication)
|
||||||
|
GIT_URI = "https://github.com/debops"
|
||||||
|
|
||||||
|
# Default git sources for debops-playbooks
|
||||||
|
PLAYBOOKS_GIT_URI = GIT_URI + "/debops-playbooks"
|
||||||
|
|
||||||
|
# Default slug prefix for roles
|
||||||
|
GIT_ROLE_PREFIX = "ansible-"
|
||||||
|
|
||||||
|
# Ansible Galaxy requirements file to use by default to download or update
|
||||||
|
GALAXY_REQUIREMENTS = "galaxy/requirements.txt"
|
||||||
|
|
||||||
|
# Default Ansible Galaxy user account name
|
||||||
|
GALAXY_ACCOUNT = "debops"
|
||||||
|
|
||||||
|
|
||||||
|
# ---- Functions ----
|
||||||
|
|
||||||
|
def fetch_or_clone_roles(roles_path, requirements_file, dry_run=False):
|
||||||
|
"""
|
||||||
|
Efficiently fetch or clone a role
|
||||||
|
"""
|
||||||
|
with open(requirements_file) as fh:
|
||||||
|
requirements = [r.strip().split() for r in fh.readlines()]
|
||||||
|
num_roles = len(requirements)
|
||||||
|
|
||||||
|
for cnt, role_name in enumerate(requirements, 1):
|
||||||
|
# Parse the requirements.txt file to extract the role name and version
|
||||||
|
try:
|
||||||
|
role_name, role_version = role_name[:2]
|
||||||
|
except:
|
||||||
|
role_name = role_name[0]
|
||||||
|
role_version = 'master'
|
||||||
|
|
||||||
|
# :todo: rethink if we really want this
|
||||||
|
if role_name.startswith(GALAXY_ACCOUNT + '.'):
|
||||||
|
galaxy_name = role_name
|
||||||
|
role_name = role_name.split('.', 1)[1]
|
||||||
|
else:
|
||||||
|
galaxy_name = GALAXY_ACCOUNT + '.' + role_name
|
||||||
|
|
||||||
|
remote_uri = GIT_URI + '/' + GIT_ROLE_PREFIX + role_name
|
||||||
|
destination_dir = os.path.join(roles_path, galaxy_name)
|
||||||
|
progress_label="[{role_version}] ({cnt}/{num_roles})".format(**locals())
|
||||||
|
|
||||||
|
# Either update or clone the role
|
||||||
|
if os.path.exists(destination_dir):
|
||||||
|
print("Updating", remote_uri, progress_label)
|
||||||
|
update_git_repository(destination_dir, dry_run, remote_uri)
|
||||||
|
else:
|
||||||
|
print()
|
||||||
|
print("Installing", remote_uri, progress_label)
|
||||||
|
clone_git_repository(remote_uri, role_version, destination_dir, dry_run)
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
repo_uri, destination])
|
||||||
|
|
||||||
|
def update_git_repository(path, dry_run=False, remote_uri=False):
|
||||||
|
"""
|
||||||
|
Update an exiting git repository.
|
||||||
|
|
||||||
|
To get nice output, merge only of origin as updates.
|
||||||
|
"""
|
||||||
|
# Move into the role's directory
|
||||||
|
old_pwd = os.getcwd()
|
||||||
|
os.chdir(path)
|
||||||
|
|
||||||
|
if dry_run:
|
||||||
|
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()
|
||||||
|
|
||||||
|
# Fetch it silently and store the new sha
|
||||||
|
subprocess.call(['git', 'fetch', '--quiet'])
|
||||||
|
fetch_sha = subprocess.check_output(['git', 'rev-parse', 'FETCH_HEAD']).strip()
|
||||||
|
|
||||||
|
if current_sha != fetch_sha:
|
||||||
|
print()
|
||||||
|
print('--')
|
||||||
|
subprocess.call(['git', 'merge', fetch_sha])
|
||||||
|
|
||||||
|
if remote_uri:
|
||||||
|
compare_uri = remote_uri + '/compare/' + current_sha[:7] + '...' + fetch_sha[:7]
|
||||||
|
print()
|
||||||
|
print("Compare:", compare_uri)
|
||||||
|
|
||||||
|
print('--')
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Move back to the initial directory
|
||||||
|
os.chdir(old_pwd)
|
||||||
|
|
||||||
|
|
||||||
|
# ---- Main script ----
|
||||||
|
|
||||||
|
def main(project_dir=None, dry_run=False):
|
||||||
|
|
||||||
|
# Check if user specified a directory as a parameter, if yes, use it as
|
||||||
|
# a project directory and clone DebOps playbooks inside
|
||||||
|
if project_dir:
|
||||||
|
# If it's a new project, create the directory for it
|
||||||
|
if not os.path.exists(project_dir):
|
||||||
|
print ("Creating project directory in", project_dir)
|
||||||
|
if not dry_run:
|
||||||
|
os.makedirs(project_dir)
|
||||||
|
|
||||||
|
# Make sure that playbooks and roles will be installed in project
|
||||||
|
# directory if it's specified
|
||||||
|
install_path = os.path.join(project_dir, "debops-playbooks")
|
||||||
|
|
||||||
|
# If playbooks already are installed in specified location, set them as
|
||||||
|
# currently used for eventual update
|
||||||
|
if os.path.isfile(os.path.join(install_path, DEBOPS_SITE_PLAYBOOK)):
|
||||||
|
playbooks_path = install_path
|
||||||
|
else:
|
||||||
|
playbooks_path = None
|
||||||
|
|
||||||
|
else:
|
||||||
|
# If there's no project specified, look for playbooks in known locations
|
||||||
|
project_root = find_debops_project(required=False)
|
||||||
|
config = read_config(project_root)
|
||||||
|
playbooks_path = find_playbookpath(config, project_root, required=False)
|
||||||
|
if playbooks_path:
|
||||||
|
install_path = os.path.dirname(playbooks_path)
|
||||||
|
else:
|
||||||
|
install_path = config['paths']['install-path']
|
||||||
|
|
||||||
|
roles_path = os.path.join(install_path, 'roles')
|
||||||
|
|
||||||
|
# ---- Create or update the playbooks and roles ----
|
||||||
|
|
||||||
|
# Playbooks have not been found, at this point assume playbooks are not
|
||||||
|
# installed. Install them in user home directory
|
||||||
|
if not playbooks_path:
|
||||||
|
if dry_run:
|
||||||
|
raise SystemExit("--dry-run requires DebOps playbooks.\n" \
|
||||||
|
"Run debops-update without --dry-run first.")
|
||||||
|
|
||||||
|
# Download/clone main debops-playbooks repository
|
||||||
|
print("DebOps playbooks have not been found, installing into",
|
||||||
|
install_path)
|
||||||
|
print()
|
||||||
|
|
||||||
|
clone_git_repository(PLAYBOOKS_GIT_URI, 'master', install_path, dry_run)
|
||||||
|
os.chdir(install_path)
|
||||||
|
os.makedirs(roles_path)
|
||||||
|
else:
|
||||||
|
# Update found debops-playbooks repository
|
||||||
|
print("DebOps playbooks have been found in", install_path)
|
||||||
|
update_git_repository(install_path, dry_run)
|
||||||
|
print()
|
||||||
|
os.chdir(install_path)
|
||||||
|
|
||||||
|
# Now install or update the roles into roles_path
|
||||||
|
fetch_or_clone_roles(roles_path, GALAXY_REQUIREMENTS, dry_run)
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--dry-run', action='store_true',
|
||||||
|
help='perform a trial run with no changes made')
|
||||||
|
parser.add_argument('project_dir', nargs='?')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
main(args.project_dir, args.dry_run)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise SystemExit('... aborted')
|
BIN
docker-compose
Executable file
BIN
docker-compose
Executable file
Binary file not shown.
89
loran_warez.sh
Executable file
89
loran_warez.sh
Executable file
@ -0,0 +1,89 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# VARIABLES
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# the warez dir
|
||||||
|
WAREZ="lib"
|
||||||
|
# remote
|
||||||
|
R_USER="warez"
|
||||||
|
R_HOST="ks3367494.wezee.eu"
|
||||||
|
R_PATH="/usr/local/warez"
|
||||||
|
# rsync
|
||||||
|
# bwlimit peutêtre défini à 2000 pour limiter la conso de bande passante
|
||||||
|
RSYNC_DAEMON="/usr/local/bin/rsync"
|
||||||
|
RSYNC_OPT="--quiet --recursive --update --compress --stats --human-readable --ipv4"
|
||||||
|
RSYNC_BWLIMIT="--bwlimit=6000"
|
||||||
|
# ssh
|
||||||
|
SSH_PORT="22420"
|
||||||
|
SSH_RSA="/home/lsm/.ssh/warez_id_rsa"
|
||||||
|
#local
|
||||||
|
L_USER="lsm"
|
||||||
|
L_GROUP="lsm"
|
||||||
|
L_PATH="/usr/local/download"
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# JOURNAL
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
LOG_DIR="/var/log/warez"
|
||||||
|
if [ ! -d ${LOG_DIR} ]; then
|
||||||
|
mkdir ${LOG_DIR}
|
||||||
|
fi
|
||||||
|
LOG="${LOG_DIR}/`date +%Y%m%d%H%M`.log"
|
||||||
|
touch ${LOG}
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# TESTS
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# le script est-il déjà en cours d'exécution ?
|
||||||
|
if [ -f "${LOCK}" ]; then
|
||||||
|
printf "\n Warez job's is already in progress, we'll try again later...\n\n" >> ${LOG}
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# es-ce que $R_HOST est reachable ?
|
||||||
|
ping -c 3 ${R_HOST}
|
||||||
|
if [ "$?" -eq "0" ]; then
|
||||||
|
printf "\n ${R_HOST} is reachable, let's go for the warez job's \n" >> ${LOG}
|
||||||
|
else
|
||||||
|
printf "\n HOUSTON we've lost ${R_HOST}, no warez job's for now :( \n" >> ${LOG}
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# GRAB MOI TOUT CE VILAIN STUFF BRO'
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
|
||||||
|
# we're starting bro'
|
||||||
|
LOCK="/tmp/frw.run"
|
||||||
|
touch ${LOCK}
|
||||||
|
|
||||||
|
# grab all of 'em
|
||||||
|
SSH="ssh -l ${R_USER} -i ${SSH_RSA} -p ${SSH_PORT}"
|
||||||
|
RSYNC="${RSYNC_DAEMON} ${RSYNC_OPT} ${RSYNC_BWLIMIT}"
|
||||||
|
${RSYNC} -e "${SSH}" ${R_USER}@${R_HOST}:${R_PATH}/${WAREZ} ${L_PATH} >> ${LOG} 2>&1
|
||||||
|
|
||||||
|
# btw fix owner and permissions
|
||||||
|
chown -R ${L_USER}:${L_GROUP} ${L_PATH}/${WAREZ} >> ${LOG} 2>&1
|
||||||
|
find ${L_PATH}/${WAREZ} -type d -exec chmod 755 {} \; >> ${LOG} 2>&1
|
||||||
|
find ${L_PATH}/${WAREZ} -type f -exec chmod 644 {} \; >> ${LOG} 2>&1
|
||||||
|
|
||||||
|
# we're done bro'
|
||||||
|
rm ${LOCK}
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
#-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
||||||
|
#entrée dans le /etc/crontab
|
||||||
|
# 1st line is for normal days of the week
|
||||||
|
# 2nd line have to be commented if you're at home and need full Internet bandwidth!
|
||||||
|
# 3rd line is for week-end time
|
||||||
|
#23 1-10 * * mon,tue,wed,thu root /bin/sh /root/fetch_remote_warez.sh
|
||||||
|
#32 11-17 * * mon,tue,wed,thu root /bin/sh /root/fetch_remote_warez.sh
|
||||||
|
#23 5-10 * * fri,sat,sun root /bin/sh /root/fetch_remote_warez.sh
|
||||||
|
|
||||||
|
#mais je vais modifier ça, et faire tester au script la présence d'un fichier nowarez dans un rep accessible via samba, if true = no warez job else
|
37
netaddr
Executable file
37
netaddr
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
|
||||||
|
#
|
||||||
|
# Released under the BSD license. See the LICENSE file for details.
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
"""an interactive shell for the netaddr library"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import netaddr
|
||||||
|
from netaddr import *
|
||||||
|
|
||||||
|
# aliases to save some typing ...
|
||||||
|
from netaddr import IPAddress as IP, IPNetwork as CIDR
|
||||||
|
from netaddr import EUI as MAC
|
||||||
|
|
||||||
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
|
banner = "\nnetaddr shell %s - %s\n" % (netaddr.__version__, __doc__)
|
||||||
|
exit_msg = "\nShare and enjoy!"
|
||||||
|
rc_override = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
# ipython >= 0.11
|
||||||
|
from IPython.terminal.embed import InteractiveShellEmbed
|
||||||
|
ipshell = InteractiveShellEmbed(banner1=banner, exit_msg=exit_msg)
|
||||||
|
except ImportError:
|
||||||
|
# ipython < 0.11
|
||||||
|
from IPython.Shell import IPShellEmbed
|
||||||
|
ipshell = IPShellEmbed(argv, banner, exit_msg, rc_override)
|
||||||
|
except ImportError:
|
||||||
|
sys.stderr.write('IPython (http://ipython.scipy.org/) not found!\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
ipshell()
|
2
qutebrowser-git
Executable file
2
qutebrowser-git
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
~/depot/qutebrowser/.venv/bin/python3 -m qutebrowser --backend webengine "$@"
|
1
rocketchat
Symbolic link
1
rocketchat
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/opt/Rocket.Chat+/rocketchat
|
2
update-motd.d/10-uname
Executable file
2
update-motd.d/10-uname
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
uname -snrvm
|
Loading…
Reference in New Issue
Block a user