diff --git a/elao.app_symfony_flex/.manala.yaml b/elao.app_symfony_flex/.manala.yaml index 32defed..27f4689 100644 --- a/elao.app_symfony_flex/.manala.yaml +++ b/elao.app_symfony_flex/.manala.yaml @@ -5,5 +5,6 @@ manala: - .manala/docker .manala/docker - .manala/jenkins .manala/jenkins - .manala/make .manala/make + - .manala/vagrant .manala/vagrant - .manala/.gitignore .manala/.gitignore - README.md .manala/README.md diff --git a/elao.app_symfony_flex/.manala/ansible/lookup_plugins/merge.py b/elao.app_symfony_flex/.manala/ansible/lookup_plugins/merge.py new file mode 100644 index 0000000..123d898 --- /dev/null +++ b/elao.app_symfony_flex/.manala/ansible/lookup_plugins/merge.py @@ -0,0 +1,84 @@ +__metaclass__ = type + +from ansible.errors import AnsibleAssertionError +from ansible.module_utils.six import string_types +from ansible.plugins.lookup import LookupBase + +#from ansible.template import Templar + +class KeyError(Exception): + """Raised for unknown key.""" + def __init__(self, key): + self.key = key + +class LookupModule(LookupBase): + + def _get_nested(self, value, key, **kw): + """ + Get a named key from an value; _get_nested(x, 'a.b.c.d') is equivalent + to x['a']['b']['c']['d']. When a default keyword argument is given, + it is returned when any attribute in the chain doesn't exist; + without it, an exception is raised when a missing attribute is encountered. + """ + + if not isinstance(key, string_types): + raise AnsibleAssertionError('nested key should be a string but was a %s' % type(key)) + + keys = key.split('.') + + #templar = Templar(variables=value, loader=self._loader) + + for key in keys: + if not isinstance(value, dict): + raise AnsibleAssertionError('nested value should be a dict but was a %s' % type(value)) + if key in value: + value = value.get(key) + #value = templar.template(value.get(key), fail_on_undefined=False) + #value = templar.template(value.get(key)) + else: + if kw.has_key('default'): + return kw['default'] + else: + raise KeyError(key) + return value + + def run(self, terms, variables, **kwargs): + + key = terms[0] + hashes = terms[1] + + candidates = [] + + #templar = Templar(variables=variables, loader=self._loader) + + for hash_key in hashes: + try: + hash = self._get_nested(variables, hash_key) + #hash = templar.template(self._get_nested(variables, hash_key), fail_on_undefined=False) + #hash = templar.template(self._get_nested(variables, hash_key)) + if not isinstance(hash, dict): + raise AnsibleAssertionError('hash "%s" should be a dict but was a %s' % (hash_key, type(hash))) + candidates.append(self._get_nested(hash, key)) + except KeyError: + pass + + if not len(candidates): + if kwargs.has_key('default'): + return kwargs['default'] + else: + raise AnsibleAssertionError('no candidates for merging key "%s"' % key) + + ret = None + + for candidate in candidates: + if type(candidate) != type(ret): + ret = candidate + else: + if isinstance(candidate, dict): + ret.update(candidate) + elif isinstance(candidate, list): + ret += candidate + else: + ret = candidate + + return ret diff --git a/elao.app_symfony_flex/.manala/ansible/provision.inventory.yaml.tmpl b/elao.app_symfony_flex/.manala/ansible/provision.inventory.yaml.tmpl new file mode 100644 index 0000000..7d1e88d --- /dev/null +++ b/elao.app_symfony_flex/.manala/ansible/provision.inventory.yaml.tmpl @@ -0,0 +1,42 @@ +--- + +all: + hosts: + localhost: + # Ansible + ansible_connection: local + ansible_become: true + # System + host_system: + {{- .system | toYaml | nindent 8 }} + children: + app: + children: + app_dev: + vars: + env: dev # En déplacant les templates en local, ce devrait pouvoir dégager... + children: + app_local: + hosts: + localhost: + # default: + # hosts: + # localhost: + # vars: + # # # Test + # # group_app_local_system: + # # #motd: prout + # # motd: + # # template: template/elao.j2 + # # message: App + # + # # System + # group_default_system: + # pipi: caca + # # motd: + # # template: template/elao.j2 + # # message: App + # timezone: Etc/UTC + # locales: + # codes: [] + # default: C.UTF-8 diff --git a/elao.app_symfony_flex/.manala/ansible/provision.yaml b/elao.app_symfony_flex/.manala/ansible/provision.yaml new file mode 100644 index 0000000..6a318ba --- /dev/null +++ b/elao.app_symfony_flex/.manala/ansible/provision.yaml @@ -0,0 +1,240 @@ +--- + +- hosts: app + collections: + - manala.roles + vars: + + # merge_hashes: "{{ + # group_names|map('regex_replace', '^(.*)$', 'group_\\1_system')|list + # + ['default_system'] + # + ['host_system'] + # }}" + # merge_hashes: + # - group_default_system + + merge_hashes: + - host_system + + default_system: + motd: + template: template/elao.j2 + message: App + timezone: Etc/UTC + locales: + codes: [] + default: C.UTF-8 + env: [] + apt: + repositories: [] + preferences: + - ansible@ansible + - preference: openjdk@backports + state: "{{ (ansible_distribution_release in ['jessie']) | ternary('present', 'absent') }}" + - preference: git@backports + state: "{{ (ansible_distribution_release in ['jessie', 'stretch']) | ternary('present', 'absent') }}" + - preference: supervisor@{{ (ansible_distribution_release in ['jessie']) | ternary('manala', 'backports') }} + state: "{{ (ansible_distribution_release in ['jessie', 'stretch']) | ternary('present', 'absent') }}" + - preference: htop@backports + state: "{{ (ansible_distribution_release in ['jessie']) | ternary('present', 'absent') }}" + - preference: php@sury_php + state: "{{ query('merge', 'php.version', merge_hashes, default=False) | ternary('present', 'absent') }}" + - preference: nginx@nginx + state: "{{ query('merge', 'nginx', merge_hashes, default=False) | ternary('present', 'absent') }}" + - preference: "nodejs@{{ query('merge', 'nodejs.version', merge_hashes, default=False) | ternary( + 'nodesource_' ~ query('merge', 'nodejs.version', merge_hashes, default='') | string | replace('.', '_'), + 'default' + )}}" + state: "{{ query('merge', 'nodejs.version', merge_hashes, default=False) | ternary('present', 'absent') }}" + - preference: yarn@yarn + state: "{{ query('merge', 'nodejs.version', merge_hashes, default=False) | ternary('present', 'absent') }}" + - preference: "mysql@{{ query('merge', 'mysql.version', merge_hashes, default=False) | ternary( + 'mysql_' ~ query('merge', 'mysql.version', merge_hashes, default='') | string | replace('.', '_'), + 'default' + )}}" + state: "{{ query('merge', 'mysql.version', merge_hashes, default=False) | ternary('present', 'absent') }}" + - preference: postgresql@postgresql + state: "{{ query('merge', 'postgresql.version', merge_hashes, default=False) | ternary('present', 'absent') }}" + - preference: "mongodb@{{ query('merge', 'mongodb.version', merge_hashes, default=False) | ternary( + 'mongodb_' ~ query('merge', 'mongodb.version', merge_hashes, default='') | string | replace('.', '_'), + 'default' + )}}" + state: "{{ query('merge', 'mongodb.version', merge_hashes, default=False) | ternary('present', 'absent') }}" + - preference: "elasticsearch@{{ query('merge', 'elasticsearch.version', merge_hashes, default=False) | ternary( + 'elasticsearch_' ~ query('merge', 'elasticsearch.version', merge_hashes, default='') | string | replace('.', '_'), + 'default' + )}}" + state: "{{ query('merge', 'elasticsearch.version', merge_hashes, default=False) | ternary('present', 'absent') }}" + - preference: influxdb@influxdata + state: "{{ query('merge', 'influxdb', merge_hashes, default=False) | ternary('present', 'absent') }}" + packages: + - debfoster + - rsync + - wget + - curl + - htop + - less + - ssl-cert + php: + # Required to enable php + version: ~ + nodejs: + # Required to enable nodejs + version: ~ + nginx: + configs: [] + mysql: + # Required to enable mysql + version: ~ + mariadb: + # Required to enable mysql + version: ~ + postgresql: + # Required to enable postgresql + version: ~ + mongodb: + # Required to enable mongodb + version: ~ + elasticsearch: + # Required to enable mongodb + version: ~ + influxdb: ~ + + app_default_options: + # OK + motd: true + timezone: true + locales: true + apt: true + + # Problemes... + environment: true + # -> Passage en minuscules des noms des variables + # -> Confusion entre `env` staging|production et `env` lste des variables d'environement + + # Neeeext.... + ssh: true + make: true + git: true + zsh: true + ohmyzsh: true + vim: true + alternatives: true + files: true + mailhog: true + nodejs: true + nodejs_version: "12" # '0.10'|'0.12'|'4'|'5'|'6'|'7'|'8'|'10'|'12' + npm: true + yarn: true + php: true + php_version: "7.3" # '5.6'|'7.0'|'7.1'|'7.2'|'7.3' + composer: true + nginx: true + supervisor: true + phantomjs: true + ngrok: true + ntp: true + java: false + cron: true + opcache_dashboard: true + mysql: false + mysql_version: '5.7' # '5.6'|'5.7' + mariadb: false + mariadb_version: '10.3' # '10.0'|'10.1'|'10.2'|'10.3' + phpmyadmin: true + postgresql: false + postgresql_version: '9.5' + phppgadmin: true + redis: false + phpredisadmin: true + mongodb: false + mongodb_version: '3.2' + mongo_express: true + elasticsearch: false + elasticsearch_version: '6' # '1.5'|'1.6'|'1.7'|'2'|'5'|'6'|'7' + influxdb: false + dnsmasq: false + sqlite: false + thumbor: false + # App + app: + env: dev + env_vars: {} + user: vagrant + group: vagrant + host: "{{ ansible_fqdn }}" + dir: /srv/app + dir_release: ~ + log_dir: /var/log/app # Nouvelle norme ? + cache_dir: /var/cache/app # Nouvelle norme ? + sessions_dir: /var/lib/app/sessions # Nouvelle norme ? + + tasks: + + # Motd (See: https://github.com/manala/ansible-role-motd) + - include_role: + name: motd + vars: + manala_motd_template: "{{ query('merge', 'motd.template', merge_hashes, default=default_system.motd.template) }}" + manala_motd_message: "{{ query('merge', 'motd.message', merge_hashes, default=default_system.motd.message) }}" + + # Timezone (See: https://github.com/manala/ansible-role-timezone) + - include_role: + name: timezone + vars: + manala_timezone_default: "{{ query('merge', 'timezone', merge_hashes, default=default_system.timezone) }}" + + # Locales (See: https://github.com/manala/ansible-role-locales) + - include_role: + name: locales + vars: + manala_locales_codes: "{{ query('merge', 'locales.codes', merge_hashes, default=default_system.locales.codes) }}" + manala_locales_codes_default: "{{ query('merge', 'locales.default', merge_hashes, default=default_system.locales.default) }}" + + # Environment (See: https://github.com/manala/ansible-role-environment) + - include_role: + name: environment + vars: + manala_environment_files: + - zsh + manala_environment_variables: "{{ query('merge', 'env', merge_hashes, default=default_system.env) }}" + + # Apt (See: https://github.com/manala/ansible-role-apt) + - include_role: + name: apt + vars: + manala_apt_configs: + - file: archive + template: configs/check_valid_until_false.j2 + state: "{{ (ansible_distribution_release in ['jessie'])|ternary('present', 'absent') }}" + manala_apt_components: + - main + manala_apt_sources_list_template: sources_list/security_updates.j2 + manala_apt_repositories_exclusive: true + manala_apt_repositories: "{{ + default_system.apt.repositories + + query('merge', 'apt.repositories', merge_hashes, default=[]) + }}" + manala_apt_preferences_exclusive: true + manala_apt_preferences: "{{ + default_system.apt.preferences + + query('merge', 'apt.preferences', merge_hashes, default=[]) + }}" + # Hold ansible package update when ansible itself runs in local + manala_apt_update_holds: "{{ + (ansible_connection == 'local')|ternary(['ansible'],[]) + }}" + manala_apt_packages: "{{ + default_system.apt.packages + + query('merge', 'apt.packages', merge_hashes, default=[]) + }}" + + # - debug: + # var: merge_hashes + + # - debug: + # #msg: "{{ query('merge', 'foo.bar', merge_hashes, default='baz') }}" + # #msg: "{{ query('merge', 'motd.template', merge_hashes) }}" + # #msg: "{{ query('merge', 'motd.message', merge_hashes) }}" + # msg: "{{ query('merge', 'locales.codes', merge_hashes) }}" + # msg: "{{ query('merge', 'locales.default', merge_hashes) }}" diff --git a/elao.app_symfony_flex/.manala/ansible/templates/motd/elao.j2 b/elao.app_symfony_flex/.manala/ansible/templates/motd/elao.j2 new file mode 100644 index 0000000..ec1db0f --- /dev/null +++ b/elao.app_symfony_flex/.manala/ansible/templates/motd/elao.j2 @@ -0,0 +1,20 @@ +  + A0. 0000  + AAV 0000  + AAV 0000  + _.n0000n._°0Q 0000 _.aaaAa._ _.aaaAa._  + .o0AAAAAAAAA0o. 0000 .00000"""00000. .00000"""00000.  + 0AAP° °QAA0 0000 000° °000 000° °000  + 0AV VAA 0000 000 000 000 000  + AAAA0000000000000AAA0 0000 000 000 000 000  + AAAA00000000000000000 0000 000 00A 000 000  + 000 0000 000 00A 000 000  + 000 0000 000 000A 000 000  + 0000. 0000 0000. .00000A 000. .000  + 000MMM 0000 00000nnn0000° 00A °00000nnn00000°  + °^VMM 0000 °^V000V^° 00A °^V000V^°  +  +  +{{ manala_motd_message|center(80) }} +  + diff --git a/elao.app_symfony_flex/.manala/ansible/templates/motd/yoda.j2 b/elao.app_symfony_flex/.manala/ansible/templates/motd/yoda.j2 new file mode 100644 index 0000000..17c22b0 --- /dev/null +++ b/elao.app_symfony_flex/.manala/ansible/templates/motd/yoda.j2 @@ -0,0 +1,31 @@ + ____ + _.' : `._ + .-.'`. ; .'`.-. + __ / : ___\ ; /___ ; \ __ + ,'_ ""--.:__;".-.";: :".-.":__;.--"" _`, + :' `.t""--.. '<@,`;_ ',@>` ..--""j.' `; + `:-.._J '-.-'L__ `-- ' L_..-;' + "-.__ ; .-" "-. : __.-" + L ' /.------.\ ' J + "-. "--" .-" + __.l"-:_JL_;-";.__ + .-j/'.; ;"""" / .'\"-. + .' /:`. "-.: :.-" .'; `. + .-" / ; "-. "-..-" .-" : "-. + .+"-. : :  "-.__.-" ;-._ \ + ; \ `.; ; : : "+. ; + : ; ; ; : ; : \: + : `."-; ; ; : ; ,/; + ; -: ; : ; : .-"' : + :\ \ : ; : \.-" : + ;`. \ ; : ;.'_..-- / ; + : "-. "-: ; :/." .' : + \ .-`.\ /t-"" ":-+. : + `. .-" `l __/ /`. : ; ; \ ; + \ .-" .-"-.-" .' .'j \ / ;/ + \ / .-" /. .'.' ;_:' ; + :-""-.`./-.' / `.___.' + \ `t ._ / + "-.t-._:' + +{{ manala_motd_message|center(42) }} diff --git a/elao.app_symfony_flex/.manala/vagrant/Vagrantfile.tmpl b/elao.app_symfony_flex/.manala/vagrant/Vagrantfile.tmpl new file mode 100644 index 0000000..4cd1c2e --- /dev/null +++ b/elao.app_symfony_flex/.manala/vagrant/Vagrantfile.tmpl @@ -0,0 +1,113 @@ +{{- $box_versions := dict 8 "201912.03.0" 9 "201912.05.0" 10 "201912.05.0" -}} +{{- $box_version := index $box_versions (.system.version|toString) -}} + +{{- $ubuntu_releases := dict 8 "trusty" 9 "xenial" 10 "bionic" -}} +{{- $ubuntu_release := index $ubuntu_releases (.system.version|toString) -}} + +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.require_version '>= 2.2.6' + +# Override vagrant dotfile path +# See: https://stackoverflow.com/a/55153081 +if ENV['VAGRANT_DOTFILE_PATH'].nil? + ENV['VAGRANT_DOTFILE_PATH'] = '.manala/.cache/vagrant' + FileUtils.rm_r('.vagrant') + exec 'vagrant ' + ARGV.map{|arg| Shellwords.escape arg}.join(' ') +end + +# Check virtualbox version +# See: https://stackoverflow.com/a/46125027 +#if Gem::Version.new(`VBoxManage --version`.strip) < Gem::Version.new('6.0.14') +# abort 'Please upgrade Virtualbox to 6.0.14 or later!' +#end + +# Check virtualbox version +# See: https://github.com/hashicorp/vagrant/issues/4649#issuecomment-378675037 +#MIN_VIRTUALBOX_VERSION = Gem::Version.new('5.2.8') +#version = `VBoxManage --version` +#clean_version = /[0-9]+\.[0-9]+\.[0-9]+/.match(version) +#if Gem::Version.new(clean_version) < MIN_VIRTUALBOX_VERSION +# abort "Please upgrade to Virtualbox >= #{MIN_VIRTUALBOX_VERSION}" +#end + +ENV['LC_PIPI'] = 'caca' +# ENV['container'] = 'vagrant' +# Ouais, nan, ca sera plutot à base de /etc/environment ou ~/.profile +# Ah, non, en fait: https://stackoverflow.com/a/36126518 +# Oui, c'est ca, c'est lié à la config de sshd, ou on laisse passer QUE les LC_* + +Vagrant.configure('2') do |config| + + # Ssh + config.ssh.forward_agent = true + config.ssh.insert_key = false + config.ssh.extra_args = ['-q'] + #config.ssh.forward_env = ['container', 'PIPI'] + + # Vm + config.vm.box = 'bento/debian-{{ .system.version }}' + config.vm.box_version = '>= {{ $box_version }}' + config.vm.hostname = '{{ .system.hostname }}' + config.vm.network 'private_network', type: 'dhcp' + config.vm.synced_folder '.', '/srv/app', + type: 'nfs', + mount_options: ['nolock', 'actimeo=1', 'fsc'] + + # Vm - Provider Virtualbox + config.vm.provider 'virtualbox' # Force provider + config.vm.provider :virtualbox do |virtualbox| + virtualbox.name = '{{ regexReplaceAll "^(.*)\\.[^.]*$" .system.hostname "${1}" }}' + {{- if .system.memory }} + virtualbox.memory = {{ .system.memory }} + {{- end }} + end + + # Plugins - Landrush + if Vagrant.has_plugin?('landrush') + config.landrush.enabled = true + config.landrush.tld = config.vm.hostname + config.landrush.guest_redirect_dns = false + end + + # Vm - Provision - Dotfiles + for dotfile in ['.gitconfig', '.gitignore'] + if File.exists?(File.join(Dir.home, dotfile)) then + config.vm.provision dotfile, type: 'file', run: 'always' do |file| + file.source = '~/' + dotfile + file.destination = dotfile + end + end + end + + # Vm - Provision - Bootstrap + config.vm.provision 'bootstrap', type: 'shell', + keep_color: true, + inline: <<-SHELL + printf "[\033[36mAnsible\033[0m] \033[32mInstall...\033[0m\n" + echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu {{ $ubuntu_release }} main" > /etc/apt/sources.list.d/ppa_launchpad_net_ansible_ansible_ubuntu.list + apt-key adv -q --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367 + apt-get update -qq + apt-get install -qq -y --no-install-recommends \ + ansible + printf "[\033[36m36mAnsible Collection\033[0m] \033[32mInstall...\033[0m\n" + ansible-galaxy collection install --collections-path /usr/share/ansible/collections --force manala.roles + SHELL + + # ansible-playbook --inventory .manala/ansible/provision.inventory.yaml /srv/app/ansible/app.yml + # ansible-playbook --inventory .manala/ansible/provision.inventory.yaml .manala/ansible/provision.yaml + + # Vm - Provision + config.vm.provision 'provision', type: 'shell', + keep_color: true, + env: { + 'ANSIBLE_FORCE_COLOR' => 1 + }, + inline: <<-SHELL + printf "[\033[36mAnsible\033[0m] \033[32mProvision...\033[0m\n" + ansible-playbook \ + --inventory .manala/ansible/provision.inventory.yaml \ + /srv/app/ansible/app.yml + SHELL +end