Page MenuHomeDevCentral

No OneTemporary

diff --git a/roles/devserver/userland-software/files/shell.py b/roles/devserver/userland-software/files/shell.py
new file mode 100755
index 0000000..0460f85
--- /dev/null
+++ b/roles/devserver/userland-software/files/shell.py
@@ -0,0 +1,239 @@
+#!/usr/bin/env python3
+
+# -------------------------------------------------------------
+# Operations utilities
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Author: Sébastien Santoro aka Dereckson
+# Created: 2018-03-08
+# License: BSD-2-Clause
+# Source file: roles/devserver/userland-software/files/shell.sh
+# -------------------------------------------------------------
+#
+# <auto-generated>
+# This file is managed by our rOPS SaltStack repository.
+#
+# Changes to this file may cause incorrect behavior
+# and will be lost if the state is redeployed.
+# </auto-generated>
+
+from collections import deque
+
+import os
+import re
+import subprocess
+import sys
+import yaml
+
+
+# -------------------------------------------------------------
+# Configuration file locator
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def get_candidates_configuration_directories():
+ candidates = []
+
+ if 'HOME' in os.environ:
+ candidates.append(os.environ['HOME'])
+
+ candidates.append('/usr/local/etc')
+ candidates.append('/etc')
+
+ return candidates
+
+
+def get_candidates_configuration_files():
+ return [directory + "/.shell.yml" for directory
+ in get_candidates_configuration_directories()]
+
+
+def find_configuration_file():
+ for candidate in get_candidates_configuration_files():
+ if os.path.isfile(candidate):
+ return candidate
+
+
+# -------------------------------------------------------------
+# Configuration file parser
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def parse_configuration_file(filename):
+ configuration_file = open(filename, 'r')
+ configuration = yaml.load(configuration_file)
+ configuration_file.close()
+
+ return configuration
+
+
+# -------------------------------------------------------------
+# Server connection
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+class ServerConnection:
+ """Represents a server connection with a command to run."""
+
+ config = {}
+ args = []
+
+ def __init__(self, config, args):
+ self.config = config
+ self.args = deque(args)
+
+ def clear_args(self):
+ self.args = deque([])
+
+ def pop_all_args(self):
+ to_return = list(self.args)
+ self.clear_args()
+ return to_return
+
+ def get_default_command(self):
+ return ["ssh"]
+
+ def get_alias(self, alias_name):
+ return self.get_config_section('aliases', alias_name)
+
+ def get_handler(self, hander_name):
+ return self.get_config_section('handlers', hander_name)
+
+ def get_config_section(self, section, key):
+ if section in self.config:
+ if key in self.config[section]:
+ return self.config[section][key]
+
+ def parse_alias(self, alias):
+ if 'args' in alias:
+ self.args.extendleft(alias['args'])
+
+ if 'handler' in alias:
+ handler = self.config['handlers'][alias['handler']]
+ return self.parse_handler(handler)
+
+ if 'command' in alias:
+ return self.parse_command(alias['command'])
+
+ raise ValueError("Unable to parse alias")
+
+ def parse_handler(self, handler):
+ command = self.get_default_command()
+
+ if 'interactive' in handler and handler['interactive']:
+ command.append("-t")
+
+ command.append(handler['server'])
+ command.extend(self.parse_command(handler['command']))
+ command.extend(self.args)
+
+ return command
+
+ def parse_variable_fragment(self, variable):
+ # {{%s-|bash}} means %s-, with bash as default value if we don't
+ # have any more argument to substitute
+ matches = re.search('(.*)\|(.*)', variable)
+ if matches:
+ if not self.args:
+ return [matches.group(2)]
+
+ cleaned_fragment = matches.group(1)
+ return self.parse_variable_fragment(cleaned_fragment)
+
+ # Substitute with one argument
+ if variable == '%s':
+ return [self.args.popleft()]
+
+ # Substitute with all arguments
+ if variable == '%s-':
+ return self.pop_all_args()
+
+ raise ValueError("Can't parse " + variable)
+
+ def parse_fragment(self, fragment):
+ # If the fragment is {{something}}, this is a variable to substitute.
+ matches = re.search('{{(.*)}}', fragment)
+ if matches:
+ return self.parse_variable_fragment(matches.group(1))
+
+ return [fragment]
+
+ def parse_command(self, command):
+ parsed_command = []
+
+ fragments = [self.parse_fragment(fragment) for fragment in command]
+ for fragment in fragments:
+ parsed_command.extend(fragment)
+
+ return parsed_command
+
+ def parse_connection(self):
+ if not self.args:
+ raise ValueError("Expected arguments missing")
+
+ target = self.args.popleft()
+
+ # Is it an alias?
+ alias = self.get_alias(target)
+ if alias is not None:
+ return self.parse_alias(alias)
+
+ # Is it an handler?
+ handler = self.get_handler(target)
+ if handler is not None:
+ return self.parse_handler(handler)
+
+ raise ValueError(target + ": No such target")
+
+# -------------------------------------------------------------
+# Runner code
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def get_program_name():
+ return os.path.basename(sys.argv[0])
+
+
+def is_debug_mode_enabled():
+ return 'DEBUG' in os.environ
+
+
+def print_error(err):
+ print("{}: {}".format(get_program_name(), err), file=sys.stderr)
+
+
+def get_configuration():
+ configuration_file = find_configuration_file()
+
+ if configuration_file is None:
+ print_error("No shell configuration file found")
+ exit(2)
+
+ return parse_configuration_file(configuration_file)
+
+
+def usage():
+ print("usage: shell target [subtarget] [command ...]", file=sys.stderr)
+
+
+def main():
+ if len(sys.argv) < 2:
+ usage()
+ exit(1)
+
+ config = get_configuration()
+ connection = ServerConnection(config, sys.argv[1:])
+ try:
+ subprocess_args = connection.parse_connection()
+ except ValueError as e:
+ print_error(e)
+ exit(4)
+
+ if is_debug_mode_enabled():
+ print(subprocess_args, file=sys.stderr)
+
+ subprocess.run(subprocess_args)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/roles/devserver/userland-software/misc.sls b/roles/devserver/userland-software/misc.sls
index 6b3a2be..5df7b90 100644
--- a/roles/devserver/userland-software/misc.sls
+++ b/roles/devserver/userland-software/misc.sls
@@ -1,135 +1,144 @@
# -------------------------------------------------------------
# Salt — Provision dev software
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Created: 2017-10-20
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
-{% from "map.jinja" import packages, packages_prefixes with context %}
+{% from "map.jinja" import dirs, packages, packages_prefixes with context %}
devserver_software_misc_vcs:
pkg:
- installed
- pkgs:
# VCS
- cvs
- fossil
- subversion
# Bridges
- cvs2svn
- {{ packages_prefixes.python2 }}hg-git
devserver_software_misc_media:
pkg:
- installed
- pkgs:
- ffmpeg2theora
- opencore-amr
- opus
- speex
- speexdsp
- x265
devserver_software_misc_text_processing:
pkg:
- installed
- pkgs:
- antiword
- odt2txt
- texlive-full
devserver_software_misc_security:
pkg:
- installed
- pkgs:
- aescrypt
- pwgen
- vault
devserver_software_misc_tools:
pkg:
- installed
- pkgs:
- boxes
- cursive
- fusefs-s3fs
- gist
- p7zip
- primegen
- rsync
- unix2dos
{% if grains['os'] == 'FreeBSD' %}
- gawk
{% endif %}
{% if grains['os'] == 'FreeBSD' %}
devserver_software_misc_ports:
pkg:
- installed
- pkgs:
- ccache
- portmaster
- portshaker
- porttools
- poudriere
- portsearch
portsearch_database:
cmd.run:
- name: portsearch -u
- creates: /var/db/portsearch
- require:
- pkg: devserver_software_misc_ports
/etc/make.conf:
file.managed:
- source: salt://roles/devserver/userland-software/files/make.conf
freebsd_kernel_modules:
pkg.installed:
- pkgs:
- pefs-kmod
freebsd_kernel_modules_enable:
module.wait:
- name: freebsdkmod.load
- mod: pefs
- persist: True
- watch:
- pkg: freebsd_kernel_modules
{% endif %}
devserver_software_misc_p2p:
pkg:
- installed
- pkgs:
- transmission-daemon
- transmission-web
devserver_software_misc_gadgets:
pkg:
- installed
- pkgs:
- asciiquarium
- binclock
- ditaa
- epte
- weatherspect
devserver_software_misc_games:
pkg:
- installed
- pkgs:
- bsdgames
- textmaze
devserver_software_misc_network:
pkg:
- installed
- pkgs:
- getdns
- iftop
{% if grains['os_family'] == 'Debian' %}
- sockstat
{% endif %}
+
+# -------------------------------------------------------------
+# Custom simple binaries
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{{ dirs.bin }}/shell:
+ file.managed:
+ - source: salt://roles/devserver/userland-software/files/shell.py
+ - mode: 755

File Metadata

Mime Type
text/x-diff
Expires
Sat, Oct 11, 21:26 (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3063982
Default Alt Text
(10 KB)

Event Timeline