From 351fe2a257ceceb293a7614506f2f8f70a881f69 Mon Sep 17 00:00:00 2001 From: Kaitlyn Parkhurst Date: Sun, 28 Aug 2022 20:16:49 -0700 Subject: [PATCH] Initial commit. --- .../weightgrapher/files/weightgrapher.service | 23 ++++ .../roles/weightgrapher/handlers/main.yml | 14 +++ .../roles/weightgrapher/tasks/database.yml | 35 ++++++ .../roles/weightgrapher/tasks/main.yml | 14 +++ .../weightgrapher/tasks/manager_account.yml | 54 +++++++++ .../roles/weightgrapher/tasks/update.yml | 6 + .../roles/weightgrapher/tasks/webapp.yml | 113 ++++++++++++++++++ .../roles/weightgrapher/tasks/webserver.yml | 32 +++++ .../weightgrapher/templates/nginx-domain.j2 | 24 ++++ .../templates/weightgrapher.yml.j2 | 12 ++ devops/ansible/site.yml | 7 ++ .../files/weightgrapher.service | 23 ++++ .../make-devel-instance/tasks/docker.yml | 68 +++++++++++ .../roles/make-devel-instance/tasks/main.yml | 5 + .../tasks/weightgrapher_service.yml | 18 +++ .../roles/reset-database/tasks/main.yml | 3 + devops/devtools/run-task | 100 ++++++++++++++++ 17 files changed, 551 insertions(+) create mode 100644 devops/ansible/roles/weightgrapher/files/weightgrapher.service create mode 100644 devops/ansible/roles/weightgrapher/handlers/main.yml create mode 100644 devops/ansible/roles/weightgrapher/tasks/database.yml create mode 100644 devops/ansible/roles/weightgrapher/tasks/main.yml create mode 100644 devops/ansible/roles/weightgrapher/tasks/manager_account.yml create mode 100644 devops/ansible/roles/weightgrapher/tasks/update.yml create mode 100644 devops/ansible/roles/weightgrapher/tasks/webapp.yml create mode 100644 devops/ansible/roles/weightgrapher/tasks/webserver.yml create mode 100644 devops/ansible/roles/weightgrapher/templates/nginx-domain.j2 create mode 100644 devops/ansible/roles/weightgrapher/templates/weightgrapher.yml.j2 create mode 100644 devops/ansible/site.yml create mode 100644 devops/devtools/roles/make-devel-instance/files/weightgrapher.service create mode 100644 devops/devtools/roles/make-devel-instance/tasks/docker.yml create mode 100644 devops/devtools/roles/make-devel-instance/tasks/main.yml create mode 100644 devops/devtools/roles/make-devel-instance/tasks/weightgrapher_service.yml create mode 100644 devops/devtools/roles/reset-database/tasks/main.yml create mode 100755 devops/devtools/run-task diff --git a/devops/ansible/roles/weightgrapher/files/weightgrapher.service b/devops/ansible/roles/weightgrapher/files/weightgrapher.service new file mode 100644 index 0000000..e03594d --- /dev/null +++ b/devops/ansible/roles/weightgrapher/files/weightgrapher.service @@ -0,0 +1,23 @@ +[Unit] +Description=WeightGrapher Web Service +After=postgresql.target + +[Service] +User=manager +Group=manager + +Environment="PERL5LIB=/home/manager/perl5/lib/perl5" +Environment="PERL_MB_OPT=--install_base \"/home/manager/perl5\"" +Environment="PERL_MM_OPT=INSTALL_BASE=/home/manager/perl5" +Environment="PERL_LOCAL_LIB_ROOT=/home/manager/perl5" +Environment="PATH=/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" + +ExecStart=/home/manager/perl5/bin/hypnotoad -f script/weightgrapher +WorkingDirectory=/home/manager/weightgrapher/Web +SyslogIdentifier=weightgrapher +Restart=on-failure +Type=simple +KillMode=process + +[Install] +WantedBy=multi-user.target diff --git a/devops/ansible/roles/weightgrapher/handlers/main.yml b/devops/ansible/roles/weightgrapher/handlers/main.yml new file mode 100644 index 0000000..646db9d --- /dev/null +++ b/devops/ansible/roles/weightgrapher/handlers/main.yml @@ -0,0 +1,14 @@ +- name: Restart nginx + service: + name: nginx + state: restarted + +- name: Restart postgres + service: + name: postgres + state: restarted + +- name: Restart weightgrapher + service: + name: weightgrapher + state: restarted diff --git a/devops/ansible/roles/weightgrapher/tasks/database.yml b/devops/ansible/roles/weightgrapher/tasks/database.yml new file mode 100644 index 0000000..9b3851e --- /dev/null +++ b/devops/ansible/roles/weightgrapher/tasks/database.yml @@ -0,0 +1,35 @@ +- name: Install packages to support postgres + apt: + name: [ + 'libssl-dev', + 'libpq-dev', + 'libz-dev', + 'libexpat1-dev', + 'postgresql-client', + 'postgresql-contrib', + 'postgresql', + 'python3-psycopg2', + ] + state: present + +- name: Start & enable postgres + service: + name: postgresql + state: started + enabled: true + +- name: Create db user account for weightgrapher + postgresql_user: + name: "{{ database.user }}" + password: "{{ database.pass }}" + state: present + become_user: postgres + become: true + +- name: Create weightgrapher database + postgresql_db: + name: "{{ database.name }}" + owner: "{{ database.user }}" + state: present + become_user: postgres + become: true diff --git a/devops/ansible/roles/weightgrapher/tasks/main.yml b/devops/ansible/roles/weightgrapher/tasks/main.yml new file mode 100644 index 0000000..42c12ec --- /dev/null +++ b/devops/ansible/roles/weightgrapher/tasks/main.yml @@ -0,0 +1,14 @@ +- name: Update system packages + include_tasks: update.yml + +- name: Setup the database + include_tasks: database.yml + +- name: Setup the manager user account + include_tasks: manager_account.yml + +- name: Setup the weightgrapher webapp + include_tasks: webapp.yml + +- name: Setup the nginx webserver + include_tasks: webserver.yml diff --git a/devops/ansible/roles/weightgrapher/tasks/manager_account.yml b/devops/ansible/roles/weightgrapher/tasks/manager_account.yml new file mode 100644 index 0000000..746f281 --- /dev/null +++ b/devops/ansible/roles/weightgrapher/tasks/manager_account.yml @@ -0,0 +1,54 @@ +- name: Install packages + apt: + name: [ + 'git', + 'build-essential', + 'cpanminus', + 'vim', + 'curl', + 'ack', + 'tree', + ] + state: present + +- name: Create manager user + user: + name: manager + shell: /bin/bash + comment: Manager User Account + +- name: Create ~manager/.ssh + file: + state: directory + path: /home/manager/.ssh + owner: manager + group: manager + mode: 0700 + +- name: Create ~manager/.ssh/authorized_keys from ~root + copy: + dest: /home/manager/.ssh/authorized_keys + src: /root/.ssh/authorized_keys + remote_src: true + owner: manager + group: manager + mode: 0600 + +- name: Ensure that local::lib is used when logging in + lineinfile: + path: /home/manager/.bashrc + regexp: '^eval \$\(perl' + line: eval $(perl -Mlocal::lib) + +- name: Install Dist::Zilla + shell: cpanm Dist::Zilla + args: + creates: /home/manager/perl5/lib/perl5/Dist/Zilla.pm + environment: + PATH: '/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin' + PERL5LIB: '/home/manager/perl5/lib/perl5' + PERL_MB_OPT: '--install_base "/home/manager/perl5"' + PERL_MM_OPT: 'INSTALL_BASE=/home/manager/perl5' + PERL_LOCAL_LIB_ROOT: '/home/manager/perl5' + become: true + become_user: manager diff --git a/devops/ansible/roles/weightgrapher/tasks/update.yml b/devops/ansible/roles/weightgrapher/tasks/update.yml new file mode 100644 index 0000000..a298342 --- /dev/null +++ b/devops/ansible/roles/weightgrapher/tasks/update.yml @@ -0,0 +1,6 @@ +- name: Update all packages to their latest version + apt: + name: "*" + state: latest + update_cache: yes + diff --git a/devops/ansible/roles/weightgrapher/tasks/webapp.yml b/devops/ansible/roles/weightgrapher/tasks/webapp.yml new file mode 100644 index 0000000..0a2db91 --- /dev/null +++ b/devops/ansible/roles/weightgrapher/tasks/webapp.yml @@ -0,0 +1,113 @@ +- name: Install /etc/weightgrapher.yml + template: + src: "{{ role_path }}/templates/weightgrapher.yml.j2" + dest: /etc/weightgrapher.yml + owner: root + group: root + mode: 0644 + +- name: "Git clone from {{ repo }}" + git: + repo: "{{ repo }}" + dest: /home/manager/weightgrapher + accept_hostkey: true + become: true + become_user: manager + +- name: Build WeightGrapher::Math + shell: dzil build > build.log 2>&1 + args: + chdir: /home/manager/weightgrapher/Math + creates: /home/manager/weightgrapher/Math/build.log + environment: + PATH: '/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin' + PERL5LIB: '/home/manager/perl5/lib/perl5' + PERL_MB_OPT: '--install_base "/home/manager/perl5"' + PERL_MM_OPT: 'INSTALL_BASE=/home/manager/perl5' + PERL_LOCAL_LIB_ROOT: '/home/manager/perl5' + become: true + become_user: manager + +- name: Install WeightGrapher::Math + shell: cpanm WeightGrapher-Math-*.tar.gz + args: + chdir: /home/manager/weightgrapher/Math + creates: /home/manager/perl5/lib/perl5/WeightGrapher/Math/WeightAverager.pm + environment: + PATH: '/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin' + PERL5LIB: '/home/manager/perl5/lib/perl5' + PERL_MB_OPT: '--install_base "/home/manager/perl5"' + PERL_MM_OPT: 'INSTALL_BASE=/home/manager/perl5' + PERL_LOCAL_LIB_ROOT: '/home/manager/perl5' + become: true + become_user: manager + +- name: Build WeightGrapher::DB + shell: dzil build > build.log 2>&1 + args: + chdir: /home/manager/weightgrapher/DB + creates: /home/manager/weightgrapher/DB/build.log + environment: + PATH: '/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin' + PERL5LIB: '/home/manager/perl5/lib/perl5' + PERL_MB_OPT: '--install_base "/home/manager/perl5"' + PERL_MM_OPT: 'INSTALL_BASE=/home/manager/perl5' + PERL_LOCAL_LIB_ROOT: '/home/manager/perl5' + become: true + become_user: manager + +- name: Install WeightGrapher::DB + shell: cpanm WeightGrapher-DB-*.tar.gz + args: + chdir: /home/manager/weightgrapher/DB + creates: /home/manager/perl5/lib/perl5/WeightGrapher/DB.pm + environment: + PATH: '/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin' + PERL5LIB: '/home/manager/perl5/lib/perl5' + PERL_MB_OPT: '--install_base "/home/manager/perl5"' + PERL_MM_OPT: 'INSTALL_BASE=/home/manager/perl5' + PERL_LOCAL_LIB_ROOT: '/home/manager/perl5' + become: true + become_user: manager + +- name: Install WeightGrapher::Web Dependencies + shell: cpanm --installdeps . > build.log 2>&1 + args: + chdir: /home/manager/weightgrapher/Web + creates: /home/manager/weightgrapher/Web/build.log + environment: + PATH: '/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin' + PERL5LIB: '/home/manager/perl5/lib/perl5' + PERL_MB_OPT: '--install_base "/home/manager/perl5"' + PERL_MM_OPT: 'INSTALL_BASE=/home/manager/perl5' + PERL_LOCAL_LIB_ROOT: '/home/manager/perl5' + + become: true + become_user: manager + +- name: Import the WeightGrapher database + shell: /home/manager/weightgrapher/Web/script/weightgrapher dbc < /home/manager/weightgrapher/DB/etc/schema.sql > /home/manager/weightgrapher/DB/etc/schema.log 2>&1 + args: + creates: /home/manager/weightgrapher/DB/etc/schema.log + environment: + PATH: '/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin' + PERL5LIB: '/home/manager/perl5/lib/perl5' + PERL_MB_OPT: '--install_base "/home/manager/perl5"' + PERL_MM_OPT: 'INSTALL_BASE=/home/manager/perl5' + PERL_LOCAL_LIB_ROOT: '/home/manager/perl5' + become: true + become_user: manager + +- name: Install weightgrapher.service file. + copy: + dest: /etc/systemd/system/weightgrapher.service + src: "{{ role_path }}/files/weightgrapher.service" + owner: root + group: root + mode: 0644 + +- name: Start & enable weightgrapher + service: + name: weightgrapher + state: started + enabled: true diff --git a/devops/ansible/roles/weightgrapher/tasks/webserver.yml b/devops/ansible/roles/weightgrapher/tasks/webserver.yml new file mode 100644 index 0000000..5658842 --- /dev/null +++ b/devops/ansible/roles/weightgrapher/tasks/webserver.yml @@ -0,0 +1,32 @@ +- name: Install packages for webserver support + apt: + name: [ + 'nginx', + 'certbot', + 'python3-certbot-nginx', + ] + state: present + +- name: Start & enable nginx + service: + name: nginx + state: started + enabled: true + +- name: "Install /etc/nginx/sites-enabled/{{ domain_name }}" + template: + src: "{{ role_path }}/templates/nginx-domain.j2" + dest: "/etc/nginx/sites-enabled/{{ domain_name }}" + force: no + owner: root + group: root + mode: 0644 + notify: + - Restart nginx + +- name: Setup SSL Certificates + shell: certbot run --nginx -d {{ domain_name }} {{ '-d www.' + domain_name if redirect_www }} --agree-tos --register-unsafely-without-email + args: + creates: /etc/letsencrypt/live/next.weightgrapher.com/cert.pem + notify: + - Restart nginx diff --git a/devops/ansible/roles/weightgrapher/templates/nginx-domain.j2 b/devops/ansible/roles/weightgrapher/templates/nginx-domain.j2 new file mode 100644 index 0000000..68ab530 --- /dev/null +++ b/devops/ansible/roles/weightgrapher/templates/nginx-domain.j2 @@ -0,0 +1,24 @@ +upstream myapp { + server 127.0.0.1:8080; +} + +server { + server_name {{ domain_name }}; + + location / { + proxy_pass http://myapp; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + +} + +server { + server_name www.{{ domain_name }}; + return 301 $scheme://{{ domain_name }}$request_uri; +} + diff --git a/devops/ansible/roles/weightgrapher/templates/weightgrapher.yml.j2 b/devops/ansible/roles/weightgrapher/templates/weightgrapher.yml.j2 new file mode 100644 index 0000000..0332270 --- /dev/null +++ b/devops/ansible/roles/weightgrapher/templates/weightgrapher.yml.j2 @@ -0,0 +1,12 @@ +--- +domain: {{ domain_name }} + +database: + weightgrapher: postgresql://{{ database.user }}:{{ database.pass }}@{{ database.host }}/{{ database.name }} + +secrets: +{% for secret in secrets %} + - {{ secret }} +{% endfor %} + + diff --git a/devops/ansible/site.yml b/devops/ansible/site.yml new file mode 100644 index 0000000..8b2778f --- /dev/null +++ b/devops/ansible/site.yml @@ -0,0 +1,7 @@ +- name: Setup A WeightGrapher Server + remote_user: root + hosts: all + vars: + ansible_ssh_common_args: -A -oControlMaster=auto -oControlPersist=60s -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no + roles: + - weightgrapher diff --git a/devops/devtools/roles/make-devel-instance/files/weightgrapher.service b/devops/devtools/roles/make-devel-instance/files/weightgrapher.service new file mode 100644 index 0000000..4796b19 --- /dev/null +++ b/devops/devtools/roles/make-devel-instance/files/weightgrapher.service @@ -0,0 +1,23 @@ +[Unit] +Description=WeightGrapher Web Service +After=postgresql.target + +[Service] +User=manager +Group=manager + +Environment="PERL5LIB=/home/manager/perl5/lib/perl5" +Environment="PERL_MB_OPT=--install_base \"/home/manager/perl5\"" +Environment="PERL_MM_OPT=INSTALL_BASE=/home/manager/perl5" +Environment="PERL_LOCAL_LIB_ROOT=/home/manager/perl5" +Environment="PATH=/home/manager/perl5/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" + +ExecStart=/home/manager/perl5/bin/morbo -l http://127.0.0.1:8080 ./script/weightgrapher +WorkingDirectory=/home/manager/weightgrapher/Web +SyslogIdentifier=weightgrapher +Restart=on-failure +Type=simple +KillMode=process + +[Install] +WantedBy=multi-user.target diff --git a/devops/devtools/roles/make-devel-instance/tasks/docker.yml b/devops/devtools/roles/make-devel-instance/tasks/docker.yml new file mode 100644 index 0000000..da3370c --- /dev/null +++ b/devops/devtools/roles/make-devel-instance/tasks/docker.yml @@ -0,0 +1,68 @@ +- name: Install packages + apt: + name: [ + 'apt-transport-https', + 'ca-certificates', + 'curl', + 'gnupg', + 'lsb-release', + ] + state: present + +- name: Install Docker Keyring + shell: curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + args: + creates: /usr/share/keyrings/docker-archive-keyring.gpg + +- name: Install Docker Repo File + shell: echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" > + /etc/apt/sources.list.d/docker.list + args: + creates: /etc/apt/sources.list.d/docker.list + +- name: Update apt cache + apt: + name: "curl" + state: latest + update_cache: yes + +- name: Install Docker Packages + apt: + name: [ + 'docker-ce', + 'docker-ce-cli', + 'containerd.io', + ] + state: present + +- name: Make sure we have a wheel group + group: + name: wheel + state: present + +- name: Allow wheel group to have passwordless sudo + lineinfile: + dest: /etc/sudoers + state: present + regexp: '^%wheel' + line: '%wheel ALL=(ALL) NOPASSWD: ALL' + validate: 'visudo -cf %s' + +- name: Add manager to docker and wheel group + user: + name: manager + groups: docker,wheel + append: yes + +- name: Start & enable docker + service: + name: docker + state: started + enabled: true + +- name: Start & enable containerd + service: + name: containerd + state: started + enabled: true + diff --git a/devops/devtools/roles/make-devel-instance/tasks/main.yml b/devops/devtools/roles/make-devel-instance/tasks/main.yml new file mode 100644 index 0000000..2d91b74 --- /dev/null +++ b/devops/devtools/roles/make-devel-instance/tasks/main.yml @@ -0,0 +1,5 @@ +- name: Add docker support for DBIC regeneration + include_tasks: docker.yml + +- name: Update systemd files for weightgrapher + include_tasks: weightgrapher_service.yml diff --git a/devops/devtools/roles/make-devel-instance/tasks/weightgrapher_service.yml b/devops/devtools/roles/make-devel-instance/tasks/weightgrapher_service.yml new file mode 100644 index 0000000..d58e105 --- /dev/null +++ b/devops/devtools/roles/make-devel-instance/tasks/weightgrapher_service.yml @@ -0,0 +1,18 @@ +- name: Stop weightgrapher service + service: + name: weightgrapher + state: stopped + +- name: Install development version of weightgrapher.service. + copy: + dest: /etc/systemd/system/weightgrapher.service + src: "{{ role_path }}/files/weightgrapher.service" + owner: root + group: root + mode: 0644 + +- name: Start the weightgrapher service + service: + name: weightgrapher + state: started + daemon_reload: yes diff --git a/devops/devtools/roles/reset-database/tasks/main.yml b/devops/devtools/roles/reset-database/tasks/main.yml new file mode 100644 index 0000000..e71d625 --- /dev/null +++ b/devops/devtools/roles/reset-database/tasks/main.yml @@ -0,0 +1,3 @@ +- name: Show the name of the domain + debug: + msg: The domain name is {{ domain_name }} diff --git a/devops/devtools/run-task b/devops/devtools/run-task new file mode 100755 index 0000000..35092ef --- /dev/null +++ b/devops/devtools/run-task @@ -0,0 +1,100 @@ +#!/usr/bin/env perl +use warnings; +use strict; +use File::Temp qw( tempfile ); # corelist - 5.6.1 +use File::Find; # corelist - 5 +use Getopt::Long; # corelist - 5 + +my $opts = { + help => 0, + config => 'config.yml' +}; + +GetOptions($opts, qw( + config=s + help! +)); + +my $data = get_data(); + +# If the user asks for help, or doesn't invoke correctly, provide usage. +if ( ( $opts->{help} ) or ( not @ARGV ) or ( @ARGV < 2 )) { + my $roles = join( "", map { "\t$_\n" } find_roles() ); + (my $usage = $data->{USAGE} ) =~ s|\[\% ROLES \%\]|$roles|g; + print STDERR $usage; + exit; +} + +# Gather role, host and then create a playbook. +my ( $role, $host ) = @ARGV; + +(my $playbook = $data->{TEMPLATE} ) =~ s|\[\% ROLE \%\]|$role|g; +$playbook =~ s|\[\% CONFIG_FILE \%\]|$opts->{config}|g; + +# Write the playbook to a temp file that will be deleted once this script is finished. +my ( $fh, $filename ) = tempfile( DIR => '.', SUFFIX => '.yml', UNLINK => 1 ); +print $fh $playbook; +close $fh; + +# Tell the user what we're running, and then run it. +print "[$role] Running: ansible-playbook -i '$host,' $filename\n"; +system( qw( ansible-playbook -i ), "$host,", $filename ); + +# == Data Stuff == # +# Store file and usage in the __DATA__ section and load them +# into a hash based on -!- NAME -!- preceeding the file. If +# there is content before an initial -!- NAME -!- the name will +# be DEFAULT. +sub get_data { + my %data; + my $section = 'DEFAULT'; + foreach my $line ( ) { + if ( $line =~ /^-!- ([A-Z]+) -!-$/ ) { + $section = $1; + next; + } + $data{$section} .= $line; + } + return \%data; +}; + +# Return a list of the rules we know about. +sub find_roles { + my @roles; + + find( sub { + return unless $File::Find::dir =~ tr[/][] == 0; # roles/* only + return unless $_ ne '.'; # No . + push @roles, $_; + }, 'roles' ); + + return @roles; +} + + +__DATA__ +-!- TEMPLATE -!- +--- +- name: Setup a MarkdownSite server + remote_user: root + hosts: all + vars: + ansible_ssh_common_args: -oControlMaster=auto -oControlPersist=60s -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no + vars_files: + - [% CONFIG_FILE %] + + roles: + - [% ROLE %] + +-!- USAGE -!- + +This program runs tasks on a remote host. + +Usage: ./run-task [--config your-config.yml] + +Example ./run-task --config staging.yml reset-database staging.weightgrapher.com + +Tasks you may run: + + [% ROLES %] +