subspace 2.1.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd87407fb11ec6c94c168ebd5b9352df4f5d548d58680d8d55f48d10b358ebf2
4
- data.tar.gz: b2ee02cff26d17e5a7ec2f09e3dbbee0c9faf9884bf28d2800419729363cb319
3
+ metadata.gz: 1a7d67442d9d8f4d6e936c27e62bfa3975b2a78a68f2cbee3684163a93cafab9
4
+ data.tar.gz: 5779b928d53d165975310a59b362b4b092388f495bb15d1da7c28602fddfe2e4
5
5
  SHA512:
6
- metadata.gz: fbb758b5dbefb0df98314cb8001baa09eab07f7586e5377441c9f453a70cce025abf0ee3aa0a09d36fb99ec437abe3565372f3a578dc6e361278e12a315397af
7
- data.tar.gz: 57bdb1094df5925b3594e198e91fe47b0f1971c7cacb0e05f2b474a2b72d81a0d5e5be216e9a998fcdf03ba62cc605d61005ce468780d227d4a805aef8decd83
6
+ metadata.gz: b71b2a2f3b4b42a61a65436ed888a735ec6d5d6d9ee17366843453ae016a594ede442d7750c1f191264166a9f58db71cb9a3435058f4fcb60fa66e3188a27996
7
+ data.tar.gz: 43cd84e03cd768befea33217d5d7440d1ac83c2cdd5e87e0b2ba2d1920dd9c1e24271274fd2c4c0be522f177e9f71cd976bd4c92160e379d670876bde77239e8
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.4.4
1
+ 2.6.3
data/.travis.yml CHANGED
@@ -1,4 +1,4 @@
1
- sudo: false
1
+ become: false
2
2
  language: ruby
3
3
  rvm:
4
4
  - 2.3.1
data/CHANGELOG.md CHANGED
@@ -10,10 +10,14 @@ This project attempts to follow [semantic versioning](https://semver.org/)
10
10
  * Not working on OSX - macs don't read from /etc/profile.d/
11
11
  * Stops showing color if you `sudo su`
12
12
 
13
+ ## 2.2.0
14
+ * Add maintenance_mode command
15
+ * Add ppa:ondrej/nginx repo in common role for TLS 1.3 and nginx support
16
+
13
17
  ## 2.1.2
14
18
  * bug fixes
15
19
  * PostgreSQL database server works for version > 10
16
- * New LetsEncrypt/NGINX servers get the correct file from the certbot repo
20
+ * New LetsEncrypt/NGINX servers get the correct file from the certbot repo
17
21
 
18
22
  ## 2.1.1
19
23
  * bug fixes
data/README.md CHANGED
@@ -69,6 +69,18 @@ At the time of this writing, we pass through the `ansible-playbook` "limit" opti
69
69
 
70
70
  e.g. To run only on the host "prod-web1": `subspace maintain production --limit=prod-web1`
71
71
 
72
+ ### `subspace maintenance_mode <environment> --on`
73
+
74
+ This sets up nginx to return all requests as 503 and serve only the
75
+ static page at `/u/apps/{{project_name}}/current/public/maintenance.html`
76
+ which must be checked into your project and deployed to the server.
77
+
78
+ `--on` and `--off`, defaults to off.
79
+
80
+ Only works for hosts using the `nginx` role, but you can pass in your entire environment. Running it on worker servers won't hurt anything.
81
+
82
+ MUST be turned off manually by running `subspace maintenance_mode <environment> --off`, even a deploy will not disable maintenance mode.
83
+
72
84
  #### Tagged roles
73
85
 
74
86
  Role | Tags | Comment
@@ -0,0 +1,5 @@
1
+ ---
2
+ - hosts: "{{ maintenance_hosts }}"
3
+ become: true
4
+ roles:
5
+ - nginx-maintenance
@@ -71,6 +71,10 @@
71
71
  tags:
72
72
  - maintenance
73
73
 
74
+ - name: Add ppa:ondrej/nginx apt repository for TLS 1.3
75
+ apt_repository:
76
+ repo: ppa:ondrej/nginx
77
+
74
78
  - name: apt-get update
75
79
  apt: update_cache=yes cache_valid_time=86400
76
80
  become: true
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  - name: apache restart
3
3
  service: name=apache2 state=restarted
4
- sudo: yes
4
+ become: yes
5
5
 
6
6
  - name: nginx restart
7
7
  service: name=nginx state=restarted
8
- sudo: yes
8
+ become: yes
@@ -2,5 +2,5 @@
2
2
  dependencies:
3
3
  - {
4
4
  role: ANXS.mysql,
5
- sudo: true
5
+ become: true
6
6
  }
@@ -3,10 +3,10 @@
3
3
  template:
4
4
  src: mysql_database.yml
5
5
  dest: /u/apps/{{project_name}}/shared/config/database.yml
6
- sudo: true
6
+ become: true
7
7
  sudo_user: "{{deploy_user}}"
8
8
 
9
9
  - name: Install mysql2 gem dependencies
10
10
  apt:
11
11
  name: libmysqlclient-dev
12
- sudo: true
12
+ become: true
@@ -3,6 +3,6 @@
3
3
  # dependencies:
4
4
  # - {
5
5
  # role: ANXS.mysql,
6
- # sudo: true
6
+ # become: true
7
7
  # }
8
8
 
@@ -2,4 +2,4 @@
2
2
  - name: Install mysql2 gem dependencies
3
3
  apt:
4
4
  name: libmysqlclient-dev
5
- sudo: true
5
+ become: true
@@ -3,21 +3,21 @@
3
3
  apt_repository:
4
4
  repo: deb http://apt.newrelic.com/debian/ newrelic non-free
5
5
  state: present
6
- sudo: true
6
+ become: true
7
7
 
8
8
  - name: Add New Relic apt key
9
9
  apt_key:
10
10
  url: https://download.newrelic.com/548C16BF.gpg
11
11
  state: present
12
- sudo: true
12
+ become: true
13
13
 
14
14
  - name: Install New Relic server agent
15
15
  apt:
16
16
  pkg: newrelic-sysmond
17
17
  state: present
18
18
  update_cache: true
19
- sudo: true
19
+ become: true
20
20
 
21
21
  - shell: "nrsysmond-config --set license_key={{newrelic_licence}}"
22
- sudo: true
22
+ become: true
23
23
  notify: start newrelic agent
@@ -0,0 +1,33 @@
1
+ ---
2
+ - name: Check that /opt/subspace/ exists
3
+ stat:
4
+ path: /opt/subspace/
5
+ register: subspace_dir
6
+ tags:
7
+ - maintenance_on
8
+ - maintenance_off
9
+
10
+ - name: Check that /u/apps/{{project_name}}/current/public/maintenance.html exists
11
+ stat:
12
+ path: /u/apps/{{project_name}}/current/public/maintenance.html
13
+ register: app_maintenance_html
14
+ tags:
15
+ - maintenance_on
16
+
17
+ - name: Move maintenance.html to /opt/subspace
18
+ command: cp /u/apps/{{project_name}}/current/public/maintenance.html /opt/subspace/maintenance.html
19
+ args:
20
+ creates: /opt/subspace/maintenance.html
21
+ when:
22
+ - app_maintenance_html.stat.exists == True
23
+ - subspace_dir.stat.exists == True
24
+ tags:
25
+ - maintenance_on
26
+
27
+ - name: Remove /opt/subspace/maintenance.html
28
+ file:
29
+ path: /opt/subspace/maintenance.html
30
+ state: absent
31
+ when: subspace_dir.stat.exists == True
32
+ tags:
33
+ - maintenance_off
@@ -2,6 +2,9 @@
2
2
  try_files $uri/index.html $uri @app;
3
3
 
4
4
  location @app {
5
+ if (-f /opt/subspace/maintenance.html) {
6
+ return 503;
7
+ }
5
8
  proxy_pass http://app;
6
9
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
7
10
  proxy_set_header X-Forwarded-Proto $app_proto;
@@ -20,7 +23,11 @@
20
23
  }
21
24
  {% endif %}
22
25
 
23
- error_page 500 502 503 504 /500.html;
26
+ error_page 500 502 504 /500.html;
27
+ error_page 503 /maintenance.html;
28
+ location /maintenance.html {
29
+ root /opt/subspace;
30
+ }
24
31
  client_max_body_size {{client_max_body_size}};
25
32
  keepalive_timeout 10;
26
33
 
@@ -5,23 +5,23 @@
5
5
  - command: tar xzf /tmp/remote_syslog.tar.gz chdir=/tmp/ creates=/usr/bin/remote_syslog
6
6
 
7
7
  - command: mv /tmp/remote_syslog/remote_syslog /usr/bin/remote_syslog creates=/usr/bin/remote_syslog
8
- sudo: true
8
+ become: true
9
9
 
10
10
  - file: path=/usr/bin/remote_syslog owner=root group=root mode=0755
11
- sudo: true
11
+ become: true
12
12
 
13
13
  - command: wget -O /etc/init.d/remote_syslog https://raw.githubusercontent.com/papertrail/remote_syslog2/v0.13/examples/remote_syslog.init.d creates=/etc/init.d/remote_syslog
14
- sudo: true
14
+ become: true
15
15
 
16
16
  - file: path=/etc/init.d/remote_syslog owner=root group=root mode=0755
17
- sudo: true
17
+ become: true
18
18
 
19
19
  - file: path=/tmp/remote_syslog/ state=absent
20
20
 
21
21
  - file: path=/tmp/remote_syslog.tar.gz state=absent
22
22
 
23
23
  - service: name=remote_syslog state=restarted enabled=yes
24
- sudo: true
24
+ become: true
25
25
 
26
26
  - template: src=log_files.yml dest=/etc/log_files.yml owner=root group=root mode=0644
27
- sudo: true
27
+ become: true
@@ -3,7 +3,7 @@
3
3
  # [repository]: http://www.postgresql.org/download/
4
4
  - name: Adding APT repository key
5
5
  when: ansible_os_family == 'Debian'
6
- sudo: yes
6
+ become: yes
7
7
  apt_key:
8
8
  id: ACCC4CF8
9
9
  url: https://www.postgresql.org/media/keys/ACCC4CF8.asc
@@ -14,7 +14,7 @@
14
14
 
15
15
  - name: Add PostgreSQL official APT repository
16
16
  when: ansible_os_family == 'Debian'
17
- sudo: yes
17
+ become: yes
18
18
  apt_repository:
19
19
  repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main"
20
20
  tags:
@@ -24,7 +24,7 @@
24
24
 
25
25
  - name: Install PostgreSQL
26
26
  when: ansible_os_family == 'Debian'
27
- sudo: yes
27
+ become: yes
28
28
  apt:
29
29
  name: "postgresql-client-{{postgresql_version}}"
30
30
  state: present
@@ -37,7 +37,7 @@
37
37
 
38
38
  - name: Install dependencies for the Ansible module
39
39
  when: ansible_os_family == 'Debian'
40
- sudo: yes
40
+ become: yes
41
41
  apt:
42
42
  name: "{{item}}"
43
43
  state: latest
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  - name: postgresql restart
3
3
  service: name=postgresql state=restarted
4
- sudo: yes
4
+ become: yes
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  - name: restart postgresql
3
- sudo: yes
3
+ become: yes
4
4
  service: name=postgresql state=restarted
5
5
 
6
6
  - name: reload postgresql
7
- sudo: yes
8
- service: name=postgresql state=reloaded
7
+ become: yes
8
+ service: name=postgresql state=reloaded
@@ -1,7 +1,7 @@
1
1
  ---
2
2
 
3
3
  - name: Create the necessary directories
4
- sudo: yes
4
+ become: yes
5
5
  file:
6
6
  dest: "{{item}}"
7
7
  state: directory
@@ -18,7 +18,7 @@
18
18
  - conf
19
19
 
20
20
  - name: Configure PostgreSQL
21
- sudo: yes
21
+ become: yes
22
22
  template:
23
23
  src: "{{item}}"
24
24
  dest: "{{postgresql_conf_directory}}/{{item}}"
@@ -33,7 +33,7 @@
33
33
  - conf
34
34
 
35
35
  - name: Configure PostgreSQL (authentication)
36
- sudo: yes
36
+ become: yes
37
37
  template:
38
38
  src: pg_hba.conf
39
39
  dest: "{{postgresql_hba_file}}"
@@ -44,7 +44,7 @@
44
44
  - conf
45
45
 
46
46
  - name: Configure PostgreSQL (ident)
47
- sudo: yes
47
+ become: yes
48
48
  template:
49
49
  src: pg_ident.conf
50
50
  dest: "{{postgresql_ident_file}}"
@@ -6,7 +6,7 @@
6
6
 
7
7
  - name: Install development headers
8
8
  when: postgresql_dev_headers == True
9
- sudo: yes
9
+ become: yes
10
10
  apt:
11
11
  name: libpq-dev
12
12
  tags:
@@ -21,7 +21,7 @@
21
21
 
22
22
  - name: Install PostgreSQL contribs
23
23
  when: postgresql_contrib
24
- sudo: yes
24
+ become: yes
25
25
  apt:
26
26
  name: "postgresql-contrib-{{postgresql_version}}"
27
27
  notify: restart postgresql
@@ -36,7 +36,7 @@
36
36
 
37
37
  - name: Add postgis extensions
38
38
  when: postgresql_postgis
39
- sudo: yes
39
+ become: yes
40
40
  apt:
41
41
  name: "{{item}}"
42
42
  with_items:
@@ -5,7 +5,7 @@
5
5
 
6
6
  - name: Adding APT repository key
7
7
  when: ansible_os_family == 'Debian'
8
- sudo: yes
8
+ become: yes
9
9
  apt_key:
10
10
  id: ACCC4CF8
11
11
  url: https://www.postgresql.org/media/keys/ACCC4CF8.asc
@@ -16,7 +16,7 @@
16
16
 
17
17
  - name: Add PostgreSQL official APT repository
18
18
  when: ansible_os_family == 'Debian'
19
- sudo: yes
19
+ become: yes
20
20
  apt_repository:
21
21
  repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main"
22
22
  tags:
@@ -26,7 +26,7 @@
26
26
 
27
27
  - name: Install PostgreSQL
28
28
  when: ansible_os_family == 'Debian'
29
- sudo: yes
29
+ become: yes
30
30
  apt:
31
31
  name: "postgresql-{{postgresql_version}}"
32
32
  state: present
@@ -39,7 +39,7 @@
39
39
 
40
40
  - name: Install dependencies for the Ansible module
41
41
  when: ansible_os_family == 'Debian'
42
- sudo: yes
42
+ become: yes
43
43
  apt:
44
44
  name: "{{item}}"
45
45
  state: latest
data/lib/subspace/cli.rb CHANGED
@@ -13,6 +13,7 @@ require 'subspace/commands/provision'
13
13
  require 'subspace/commands/ssh'
14
14
  require 'subspace/commands/vars'
15
15
  require 'subspace/commands/maintain'
16
+ require 'subspace/commands/maintenance_mode.rb'
16
17
 
17
18
  class Subspace::Cli
18
19
  include Commander::Methods
@@ -105,6 +106,19 @@ class Subspace::Cli
105
106
  c.when_called Subspace::Commands::Maintain
106
107
  end
107
108
 
109
+ command :maintenance_mode do |c, args|
110
+ c.syntax = 'subspace maintenance_mode [options]'
111
+ c.summary = 'Turns on or off maintenance mode'
112
+ c.description = ''
113
+ c.option "-i", "--private-key PRIVATE-KEY", "Alias for private-key"
114
+ c.option "--on", "Turns on maintenance mode"
115
+ c.option "--off", "Turns off maintenance mode"
116
+ Subspace::Commands::MaintenanceMode::PASS_THROUGH_PARAMS.each do |param_name|
117
+ c.option "--#{param_name} #{param_name.upcase}", "Passed directly through to ansible-playbook command"
118
+ end
119
+ c.when_called Subspace::Commands::MaintenanceMode
120
+ end
121
+
108
122
  run!
109
123
  end
110
124
  end
@@ -53,6 +53,23 @@ module Subspace
53
53
  return answer.downcase.start_with? "y"
54
54
  end
55
55
 
56
+ def pass_through_params
57
+ ansible_options = []
58
+ self.class::PASS_THROUGH_PARAMS.each do |param_name|
59
+ x = param_name.split('-')[1..-1].map(&:upcase).join('_')
60
+ hash_key = (param_name.gsub('-', '_') + (x == '' ? '' : "_#{x}")).to_sym
61
+ value = @options.__hash__[hash_key]
62
+ if value
63
+ if param_name.length > 1
64
+ ansible_options += ["--#{param_name}", value]
65
+ else
66
+ ansible_options += ["-#{param_name}", value]
67
+ end
68
+ end
69
+ end
70
+
71
+ ansible_options
72
+ end
56
73
  end
57
74
  end
58
75
  end
@@ -41,7 +41,7 @@ class Subspace::Commands::Bootstrap < Subspace::Commands::Base
41
41
  "--become",
42
42
  "-vvvv"
43
43
  ]
44
- cmd = add_pass_through_params cmd
44
+ cmd = cmd | pass_through_params
45
45
  bootstrap_command cmd
46
46
  end
47
47
 
@@ -51,16 +51,4 @@ class Subspace::Commands::Bootstrap < Subspace::Commands::Base
51
51
  end
52
52
  ansible_command *cmd
53
53
  end
54
-
55
- def add_pass_through_params(cmd)
56
- PASS_THROUGH_PARAMS.each do |param_name|
57
- x = param_name.split('-')[1..-1].map(&:upcase).join('_')
58
- hash_key = (param_name.gsub('-', '_') + (x == '' ? '' : "_#{x}")).to_sym
59
- value = @options.__hash__[hash_key]
60
- if value
61
- cmd += ["--#{param_name}", value]
62
- end
63
- end
64
- cmd
65
- end
66
54
  end
@@ -9,14 +9,7 @@ class Subspace::Commands::Maintain < Subspace::Commands::Base
9
9
 
10
10
  def run
11
11
  ansible_options = ["--diff", "--tags=maintenance"]
12
- PASS_THROUGH_PARAMS.each do |param_name|
13
- x = param_name.split('-')[1..-1].map(&:upcase).join('_')
14
- hash_key = (param_name.gsub('-', '_') + (x == '' ? '' : "_#{x}")).to_sym
15
- value = @options.__hash__[hash_key]
16
- if value
17
- ansible_options += ["--#{param_name}", value]
18
- end
19
- end
12
+ ansible_options = ansible_options | pass_through_params
20
13
  ansible_command "ansible-playbook", "#{@environment}.yml", *ansible_options
21
14
  end
22
15
  end
@@ -0,0 +1,16 @@
1
+ class Subspace::Commands::MaintenanceMode < Subspace::Commands::Base
2
+ PASS_THROUGH_PARAMS = ["private-key", "limit"]
3
+
4
+ def initialize(args, options)
5
+ @hosts = args.first
6
+ @options = options
7
+ run
8
+ end
9
+
10
+ def run
11
+ on_off = @options.__hash__[:on] ? "on" : "off"
12
+ ansible_options = ["--diff", "-e maintenance_hosts=#{@hosts}", "--tags=maintenance_#{on_off}"]
13
+ ansible_options = ansible_options | pass_through_params
14
+ ansible_command "ansible-playbook", File.join(File.dirname(__FILE__), "../../../ansible/playbooks/maintenance_mode.yml"), *ansible_options
15
+ end
16
+ end
@@ -9,14 +9,7 @@ class Subspace::Commands::Provision < Subspace::Commands::Base
9
9
 
10
10
  def run
11
11
  ansible_options = ["--diff"]
12
- PASS_THROUGH_PARAMS.each do |param_name|
13
- x = param_name.split('-')[1..-1].map(&:upcase).join('_')
14
- hash_key = (param_name.gsub('-', '_') + (x == '' ? '' : "_#{x}")).to_sym
15
- value = @options.__hash__[hash_key]
16
- if value
17
- ansible_options += ["--#{param_name}", value]
18
- end
19
- end
12
+ ansible_options = ansible_options | pass_through_params
20
13
  ansible_command "ansible-playbook", "#{@environment}.yml", *ansible_options
21
14
  end
22
15
  end
@@ -20,16 +20,7 @@ class Subspace::Commands::Ssh < Subspace::Commands::Base
20
20
  user = @user || host_vars["ansible_ssh_user"] || host_vars["ansible_user"]
21
21
  host = host_vars["ansible_ssh_host"] || host_vars["ansible_host"]
22
22
  port = host_vars["ansible_ssh_port"] || host_vars["ansible_port"] || 22
23
- ssh_options = []
24
- PASS_THROUGH_PARAMS.each do |param_name|
25
- x = param_name.split('-')[1..-1].map(&:upcase).join('_')
26
- hash_key = (param_name.gsub('-', '_') + (x == '' ? '' : "_#{x}")).to_sym
27
- value = @options.__hash__[hash_key]
28
- if value
29
- ssh_options += ["-#{param_name}", value]
30
- end
31
- end
32
- cmd = "ssh #{user}@#{host} -p #{port} #{ssh_options.join(" ")}"
23
+ cmd = "ssh #{user}@#{host} -p #{port} #{pass_through_params.join(" ")}"
33
24
  say cmd
34
25
  exec cmd
35
26
  end
@@ -1,3 +1,3 @@
1
1
  module Subspace
2
- VERSION = "2.1.2"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -27,7 +27,7 @@ Subspace.configure do |config|
27
27
  config.host :dev, {
28
28
  ssh_host: "1.2.3.4", # Ansible connects to this to provision
29
29
  ssh_user: "deploy", # ssh user
30
- sudo: true, # probably should be true if user isn't root
30
+ become: true, # probably should be true if user isn't root
31
31
  hostname: "dev.example.com" # This will get set in /etc/hostname
32
32
  }
33
33
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subspace
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Samson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-01 00:00:00.000000000 Z
11
+ date: 2019-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -101,6 +101,7 @@ files:
101
101
  - Rakefile
102
102
  - TODO
103
103
  - ansible/playbooks/local_template.yml
104
+ - ansible/playbooks/maintenance_mode.yml
104
105
  - ansible/roles/alienvault/tasks/main.yml
105
106
  - ansible/roles/apache-rails/tasks/main.yml
106
107
  - ansible/roles/apache-rails/templates/_canonical_domain.conf
@@ -172,6 +173,7 @@ files:
172
173
  - ansible/roles/mysql2_gem/tasks/main.yml
173
174
  - ansible/roles/newrelic/handlers/main.yml
174
175
  - ansible/roles/newrelic/tasks/main.yml
176
+ - ansible/roles/nginx-maintenance/tasks/main.yml
175
177
  - ansible/roles/nginx-rails/defaults/main.yml
176
178
  - ansible/roles/nginx-rails/tasks/main.yml
177
179
  - ansible/roles/nginx-rails/templates/_asset_cors.conf
@@ -263,6 +265,7 @@ files:
263
265
  - lib/subspace/commands/configure.rb
264
266
  - lib/subspace/commands/init.rb
265
267
  - lib/subspace/commands/maintain.rb
268
+ - lib/subspace/commands/maintenance_mode.rb
266
269
  - lib/subspace/commands/override.rb
267
270
  - lib/subspace/commands/provision.rb
268
271
  - lib/subspace/commands/ssh.rb
@@ -300,8 +303,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
303
  - !ruby/object:Gem::Version
301
304
  version: '0'
302
305
  requirements: []
303
- rubyforge_project:
304
- rubygems_version: 2.7.8
306
+ rubygems_version: 3.0.3
305
307
  signing_key:
306
308
  specification_version: 4
307
309
  summary: Ansible-based server provisioning for rails projects