pvcglue 0.1.39 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/README.md +12 -3
  5. data/bin/pvc +4 -2
  6. data/lib/pvcglue.rb +106 -21
  7. data/lib/pvcglue/bootstrap.rb +1 -1
  8. data/lib/pvcglue/cli.rb +28 -17
  9. data/lib/pvcglue/cloud.rb +243 -56
  10. data/lib/pvcglue/configuration.rb +43 -5
  11. data/lib/pvcglue/connection.rb +236 -0
  12. data/lib/pvcglue/custom_hashie.rb +3 -0
  13. data/lib/pvcglue/db.rb +19 -13
  14. data/lib/pvcglue/digital_ocean.rb +21 -0
  15. data/lib/pvcglue/env.rb +52 -28
  16. data/lib/pvcglue/manager.rb +38 -25
  17. data/lib/pvcglue/minion.rb +182 -0
  18. data/lib/pvcglue/nodes.rb +1 -1
  19. data/lib/pvcglue/{packages → old_packages}/bootstrap.rb +15 -15
  20. data/lib/pvcglue/{packages → old_packages}/env.rb +8 -8
  21. data/lib/pvcglue/old_packages/firewall.rb +48 -0
  22. data/lib/pvcglue/old_packages/manager.rb +116 -0
  23. data/lib/pvcglue/{packages → old_packages}/monit-bootstrap.rb +0 -0
  24. data/lib/pvcglue/{packages → old_packages}/monit-web.rb +0 -0
  25. data/lib/pvcglue/{packages → old_packages}/nginx.rb +0 -0
  26. data/lib/pvcglue/{packages → old_packages}/nodejs.rb +0 -0
  27. data/lib/pvcglue/{packages → old_packages}/passenger.rb +0 -0
  28. data/lib/pvcglue/old_packages/postgresql.rb +10 -0
  29. data/lib/pvcglue/{packages → old_packages}/role_db.rb +9 -9
  30. data/lib/pvcglue/{packages → old_packages}/role_lb.rb +6 -6
  31. data/lib/pvcglue/{packages → old_packages}/role_memcached.rb +0 -0
  32. data/lib/pvcglue/{packages → old_packages}/role_redis.rb +0 -0
  33. data/lib/pvcglue/{packages → old_packages}/role_web.rb +9 -9
  34. data/lib/pvcglue/old_packages/rvm.rb +78 -0
  35. data/lib/pvcglue/{packages → old_packages}/timezone.rb +0 -0
  36. data/lib/pvcglue/{packages → old_packages}/ubuntu.rb +0 -0
  37. data/lib/pvcglue/packages.rb +192 -71
  38. data/lib/pvcglue/packages/apt.rb +74 -0
  39. data/lib/pvcglue/packages/apt_repos.rb +48 -0
  40. data/lib/pvcglue/packages/apt_update.rb +18 -0
  41. data/lib/pvcglue/packages/apt_upgrade.rb +20 -0
  42. data/lib/pvcglue/packages/authorized_keys.rb +33 -0
  43. data/lib/pvcglue/packages/bundler.rb +14 -0
  44. data/lib/pvcglue/packages/dir_base.rb +16 -0
  45. data/lib/pvcglue/packages/dir_shared.rb +16 -0
  46. data/lib/pvcglue/packages/firewall.rb +30 -46
  47. data/lib/pvcglue/packages/load_balancer.rb +71 -0
  48. data/lib/pvcglue/packages/maintenance_mode.rb +28 -0
  49. data/lib/pvcglue/packages/manager.rb +101 -99
  50. data/lib/pvcglue/packages/postgresql.rb +36 -8
  51. data/lib/pvcglue/packages/roles.rb +23 -0
  52. data/lib/pvcglue/packages/ruby.rb +13 -0
  53. data/lib/pvcglue/packages/rvm.rb +18 -71
  54. data/lib/pvcglue/packages/secrets.rb +36 -0
  55. data/lib/pvcglue/packages/ssh_key_check.rb +11 -0
  56. data/lib/pvcglue/packages/ssl.rb +45 -0
  57. data/lib/pvcglue/packages/ssl_acme.rb +29 -0
  58. data/lib/pvcglue/packages/swap.rb +14 -0
  59. data/lib/pvcglue/packages/unattended_upgrades.rb +20 -0
  60. data/lib/pvcglue/packages/users.rb +20 -0
  61. data/lib/pvcglue/packages/web.rb +50 -0
  62. data/lib/pvcglue/stack.rb +166 -0
  63. data/lib/pvcglue/templates/50unattended-upgrades.erb +63 -0
  64. data/lib/pvcglue/templates/capfile.erb +4 -1
  65. data/lib/pvcglue/templates/deploy.rb.erb +3 -2
  66. data/lib/pvcglue/templates/lb.sites-enabled.erb +15 -9
  67. data/lib/pvcglue/templates/letsencrypt-webroot.erb +3 -0
  68. data/lib/pvcglue/templates/pg_hba.conf.erb +1 -2
  69. data/lib/pvcglue/templates/postgresql.conf.erb +376 -291
  70. data/lib/pvcglue/templates/stage-deploy.rb.erb +2 -2
  71. data/lib/pvcglue/templates/web.bashrc.erb +16 -5
  72. data/lib/pvcglue/templates/web.nginx.conf.erb +1 -1
  73. data/lib/pvcglue/templates/web.sites-enabled.erb +1 -1
  74. data/lib/pvcglue/version.rb +1 -1
  75. data/pvcglue.gemspec +17 -12
  76. metadata +125 -22
@@ -0,0 +1,74 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class Apt < Pvcglue::Packages
4
+ WEB_WORKER_PACKAGES = %w[
5
+ build-essential
6
+ git
7
+ git-core
8
+ libpq-dev
9
+ libxml2
10
+ libxml2-dev
11
+ imagemagick
12
+ passenger
13
+ nginx
14
+ nginx-extras
15
+ nodejs
16
+ ]
17
+ PACKAGES = {
18
+ common: %w[
19
+ htop
20
+ ufw
21
+ unattended-upgrades
22
+ curl
23
+ ncdu
24
+ ],
25
+ manager: %w[
26
+ git
27
+ git-core
28
+ ],
29
+ lb: %w[
30
+ nginx
31
+ nginx-extras
32
+ ],
33
+ web: WEB_WORKER_PACKAGES,
34
+ worker: WEB_WORKER_PACKAGES,
35
+ pg: %w[
36
+ postgresql-9.6
37
+ postgresql-contrib-9.6
38
+ libpq-dev
39
+ ],
40
+ mc: %w[
41
+ ],
42
+ }
43
+
44
+ def installed?
45
+ false # just let apt take care of this for now
46
+ end
47
+
48
+ def install!
49
+ connection.run!(:root, '', "DEBIAN_FRONTEND=noninteractive apt install -y #{get_package_list}")
50
+ end
51
+
52
+ def post_install_check?
53
+ true
54
+ end
55
+
56
+ def get_package_list
57
+ get_packages.join(' ')
58
+ end
59
+
60
+ def all_packages
61
+ @all_packages ||= PACKAGES.with_indifferent_access
62
+ end
63
+
64
+ def get_packages
65
+ packages = all_packages[:common]
66
+ minion.roles.each do |role|
67
+ packages += all_packages[role] if all_packages[role]
68
+ end
69
+ packages
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,48 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class AptRepos < Pvcglue::Packages
4
+ PASSENGER_SOURCES_LIST_FILENAME = '/etc/apt/sources.list.d/passenger.list'
5
+ PASSENGER_SOURCES_LIST_DATA = 'deb https://oss-binaries.phusionpassenger.com/apt/passenger xenial main'
6
+
7
+ def nginx_needed?
8
+ has_roles? %w(lb web)
9
+ end
10
+
11
+ def node_js_needed?
12
+ has_roles? %w(web worker)
13
+ end
14
+
15
+ def postgresql_needed?
16
+ has_roles? %w(pg)
17
+ end
18
+
19
+ def installed?
20
+ get_minion_state(:apt_repos_updated_at)
21
+ end
22
+
23
+ def install!
24
+ # These could be refactored into packages. :)
25
+
26
+ if nginx_needed?
27
+ # Reference: https://www.phusionpassenger.com/library/install/nginx/install/oss/xenial/
28
+ connection.run!(:root, '', 'apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7')
29
+ connection.run!(:root, '', 'apt-get install -y apt-transport-https ca-certificates')
30
+ connection.write_to_file(:root, PASSENGER_SOURCES_LIST_DATA, PASSENGER_SOURCES_LIST_FILENAME)
31
+ end
32
+
33
+ if node_js_needed?
34
+ # Reference: http://tecadmin.net/install-latest-nodejs-npm-on-ubuntu/
35
+ connection.run!(:root, '', 'apt-get install -y apt-transport-https ca-certificates python-software-properties lsb-release')
36
+ connection.run!(:root, '', 'curl -sL https://deb.nodesource.com/setup_7.x | bash -')
37
+ end
38
+
39
+ if postgresql_needed?
40
+ connection.run!(:root, '', 'add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main"')
41
+ connection.run!(:root, '', 'wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -')
42
+ end
43
+
44
+ set_minion_state(:apt_repos_updated_at, Time.now.utc)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class AptUpdate < Pvcglue::Packages
4
+ def installed?
5
+ # TODO: Add a "force" option
6
+ updated_at = get_minion_state(:last_apt_updated_at)
7
+ return false unless updated_at
8
+ true
9
+ # updated_at > Time.now.utc - 8.hours # Unattended upgrades should take care of refreshing this automatically
10
+ end
11
+
12
+ def install!
13
+ connection.run!(:root, '', 'DEBIAN_FRONTEND=noninteractive apt-get update -y -qq')
14
+ set_minion_state(:last_apt_updated_at, Time.now.utc)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class AptUpgrade < Pvcglue::Packages
4
+ def installed?
5
+ # TODO: Add a "force" option
6
+ updated_at = get_minion_state(:apt_upgraded_at)
7
+ return false unless updated_at
8
+
9
+ # updated_at > Time.now.utc - 8.hours
10
+ # TODO: Give the user a warning after a period of time
11
+ true
12
+ end
13
+
14
+ def install!
15
+ minion.connection.run!(:root, '', 'DEBIAN_FRONTEND=noninteractive apt-get upgrade -y')
16
+ set_minion_state(:apt_upgraded_at, Time.now.utc)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class AuthorizedKeys < Pvcglue::Packages
4
+ def installed?
5
+ false
6
+ end
7
+
8
+ def post_install_check?
9
+ true
10
+ end
11
+
12
+ def install!
13
+ # TODO: Safety check to see if user is locking himself out. :)
14
+ data = minion.get_root_authorized_keys_data
15
+ if data.count == 0
16
+ raise('No authorized keys found for root users!')
17
+ # TODO: work out system for pvc-manager access
18
+ data = [`cat ~/.ssh/id_rsa.pub`.strip]
19
+ end
20
+ connection.write_to_file(:root, data.join("\n"), '/root/.ssh/authorized_keys')
21
+
22
+ connection.mkdir_p(:root, "/home/#{user_name}/.ssh", user_name, user_name, '0700')
23
+ data = minion.get_users_authorized_keys_data
24
+ if data.count == 0
25
+ raise('No authorized keys found for users!')
26
+ # TODO: work out system for pvc-manager access
27
+ data = [`cat ~/.ssh/id_rsa.pub`.strip]
28
+ end
29
+ connection.write_to_file(:root, data.join("\n"), "/home/#{user_name}/.ssh/authorized_keys", user_name, user_name, '0644')
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,14 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class Bundler < Pvcglue::Packages
4
+ def installed?
5
+ connection.run_get_stdout!(user_name, '', 'which bundler') =~ /bundler/
6
+ end
7
+
8
+ def install!
9
+ # TODO: Figure out why this isn't automatic
10
+ connection.run!(user_name, '', 'gem install bundler')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class DirBase < Pvcglue::Packages
4
+ def installed?
5
+ result = connection.run_get_stdout(user_name, '', "stat --format=%U:%G:%a #{Pvcglue.cloud.web_app_base_dir}").strip
6
+ result == "#{user_name}:#{user_name}:2755"
7
+ end
8
+
9
+ def install!
10
+ dir = Pvcglue.cloud.web_app_base_dir
11
+ # used following as a guide for next line: http://capistranorb.com/documentation/getting-started/authentication-and-authorisation/
12
+ connection.run!(user_name, '', "mkdir -p #{dir} && chown #{user_name}:#{user_name} #{dir} && chmod 0755 #{dir} && umask 0002 && chmod g+s #{dir}")
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class DirShared < Pvcglue::Packages
4
+ def installed?
5
+ result = connection.run_get_stdout(user_name, '', "stat --format=%U:%G:%a #{Pvcglue.cloud.deploy_to_app_shared_dir}").strip
6
+ result == "#{user_name}:#{user_name}:2755"
7
+ end
8
+
9
+ def install!
10
+ dir = Pvcglue.cloud.deploy_to_app_shared_dir
11
+ # used following as a guide for next line: http://capistranorb.com/documentation/getting-started/authentication-and-authorisation/
12
+ connection.run!(user_name, '', "mkdir -p #{dir} && chown #{user_name}:#{user_name} #{dir} && chmod 0755 #{dir} && umask 0002 && chmod g+s #{dir}")
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,48 +1,32 @@
1
- # Reference: http://manpages.ubuntu.com/manpages/precise/en/man8/ufw-framework.8.html
2
- package 'firewall-config' do
3
-
4
- file({
5
- :template => Pvcglue.template_file_name('ufw.rules6.erb'),
6
- :destination => '/lib/ufw/user6.rules',
7
- :create_dirs => false,
8
- :permissions => 0640,
9
- :user => 'root',
10
- :group => 'root'
11
- }) { }
12
-
13
- file({
14
- :template => Pvcglue.template_file_name('ufw.rules.erb'),
15
- :destination => '/lib/ufw/user.rules',
16
- :create_dirs => false,
17
- :permissions => 0640,
18
- :user => 'root',
19
- :group => 'root'
20
- }) { sudo('service ufw restart') }
21
-
22
- end
23
-
24
- package 'firewall-enabled' do
25
- validate do
26
- result = sudo('ufw status verbose')
27
- result =~ /Status: active/ && result =~ /Default: deny \(incoming\), allow \(outgoing\)/
28
- end
29
-
30
- apply do
31
- sudo('ufw --force enable')
32
- end
33
- end
34
-
35
- # TODO: add command line command for this
36
- package 'update-firewall' do
37
- # quick update of firewall settings only. Full bootstrap must be performed first.
38
- depends_on 'firewall-config'
39
- depends_on 'firewall-enabled'
40
- end
41
-
42
-
43
- # TODO: add command line command for this
44
- package 'firewall-status' do
45
- apply do
46
- run "ufw status verbose"
1
+ module Pvcglue
2
+ class Packages
3
+ class Firewall < Pvcglue::Packages
4
+ # Reference: http://manpages.ubuntu.com/manpages/xenial/en/man8/ufw-framework.8.html
5
+ # Examples: https://help.ubuntu.com/community/UFW
6
+ def installed?
7
+ result = connection.run_get_stdout!(:root, '', 'ufw status verbose')
8
+ result =~ /Status: active/ && result =~ /Default: deny \(incoming\), allow \(outgoing\)/
9
+ end
10
+
11
+ def install!
12
+ connection.run!(:root, '', 'ufw disable; ufw --force reset; ufw allow ssh; ufw --force enable')
13
+ # connection.run!(:root, '', 'ufw logging off')
14
+ connection.run!(:root, '', 'ufw logging low')
15
+
16
+ if has_role?(:lb)
17
+ connection.run!(:root, '', 'ufw allow http')
18
+ connection.run!(:root, '', 'ufw allow https')
19
+ end
20
+
21
+ unless has_role?(:manager)
22
+ minion.cloud.minions.each do |other_minion_name, other_minion|
23
+ next if other_minion_name == minion.machine_name
24
+ connection.run!(:root, '', "ufw allow from #{other_minion.private_ip}")
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
47
31
  end
48
32
  end
@@ -0,0 +1,71 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class LoadBalancer < Pvcglue::Packages
4
+ def installed?
5
+ false
6
+ end
7
+
8
+ def install!
9
+ if Pvcglue.cloud.ssl_mode == :acme && !connection.file_exists?(:root, Pvcglue.cloud.nginx_ssl_crt_file_name)
10
+ # Don't include the SSL stuff in the Nginx config until we have a cert,
11
+ # but Nginx has to be configured to get the cert from Let's Encrypt
12
+ Pvcglue.cloud.set_ssl_mode_override(:none)
13
+ end
14
+
15
+ apply_nginx_includes
16
+ apply_nginx_config
17
+ nginx_restart!
18
+
19
+ Pvcglue::Packages::Ssl.apply(minion)
20
+
21
+ if Pvcglue.cloud.ssl_mode_override
22
+ Pvcglue.cloud.set_ssl_mode_override(nil)
23
+ apply_nginx_config
24
+ nginx_restart!
25
+ end
26
+
27
+ sync_maintenance_files
28
+ end
29
+
30
+ def nginx_restart!
31
+ result = connection.run_get_stdout(:root, '', 'service nginx restart')
32
+ if $?.exitstatus == 0
33
+ # Pvcglue.logger.debug { result }
34
+ # true
35
+ else
36
+ Pvcglue.logger.error { 'Unable to (re)start nginx. Getting status...' }
37
+ result = connection.run_get_stdout(:root, '', 'systemctl status nginx.service')
38
+ puts result
39
+ raise
40
+ end
41
+ end
42
+
43
+ def apply_nginx_includes
44
+ connection.mkdir_p(:root, '/etc/nginx/includes')
45
+ connection.write_to_file_from_template(:root, 'letsencrypt-webroot.erb', '/etc/nginx/includes/letsencrypt-webroot')
46
+ end
47
+
48
+ def apply_nginx_config
49
+ connection.write_to_file_from_template(:root, 'lb.nginx.conf.erb', '/etc/nginx/nginx.conf')
50
+ connection.write_to_file_from_template(:root, 'lb.sites-enabled.erb', "/etc/nginx/sites-enabled/#{Pvcglue.cloud.app_and_stage_name}")
51
+ end
52
+
53
+ def post_install_check?
54
+ # TODO: Ping the server as a double check.
55
+ true
56
+ end
57
+
58
+ def sync_maintenance_files
59
+ source_dir = Pvcglue.configuration.app_maintenance_files_dir
60
+ dest_dir = Pvcglue.cloud.maintenance_files_dir
61
+ maintenance_file_name = File.join(source_dir, 'maintenance.html')
62
+ unless File.exists?(maintenance_file_name)
63
+ # TODO: Make this use a template
64
+ `mkdir -p #{source_dir}`
65
+ File.write(maintenance_file_name, '-Maintenance Mode-')
66
+ end
67
+ connection.rsync_up(user_name, '-rzv --exclude=maintenance.on --delete', source_dir, dest_dir, mkdir = true)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,28 @@
1
+ module Pvcglue
2
+ class Packages
3
+ class MaintenanceMode < Pvcglue::Packages
4
+ def installed?
5
+ false
6
+ end
7
+
8
+ def install!
9
+ if options[:maintenance_mode] == 'on'
10
+ connection.run!(user_name, '', "touch #{Pvcglue.cloud.maintenance_mode_file_name}")
11
+ elsif options[:maintenance_mode] == 'off'
12
+ result = connection.run?(user_name, '', "rm #{Pvcglue.cloud.maintenance_mode_file_name}")
13
+ if result.exitstatus == 1
14
+ Pvcglue.logger.warn('Maintenance mode was already off.')
15
+ elsif result.exitstatus != 0
16
+ raise result.inspect
17
+ end
18
+ else
19
+ raise("Invalid maintenance_mode option: #{options[:maintenance_mode]}")
20
+ end
21
+ end
22
+
23
+ def post_install_check?
24
+ true
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,116 +1,118 @@
1
- require 'toml'
2
- apt_package 'htop'
3
- apt_package 'ufw'
4
-
5
- package 'bootstrap-manager' do
6
- # TODO: firewall and ssh port config
7
- depends_on 'authenticate-host'
8
- depends_on 'htop'
9
- # depends_on 'ufw'
10
- #depends_on 'deploy-user'
11
- #depends_on 'sshd-config'
12
- #depends_on 'firewall-config'
13
- depends_on 'pvcglue-user'
14
- depends_on 'manager-copy-id'
15
- end
1
+ module Pvcglue
2
+ class Packages
3
+ class Manager < Pvcglue::Packages
16
4
 
17
- package 'authenticate-host' do
18
- apply do
19
- sudo "ls" # side-effect will add host to known_hosts
20
- end
21
- end
5
+ def initialize(minion = nil, options = {})
6
+ minion = Pvcglue.cloud.manager_minion if minion.nil?
7
+ super
8
+ end
22
9
 
23
- package 'pvcglue-user' do
24
- apply do
25
- # Local variables used to improve readability of bash commands :)
26
- user_name = Pvcglue::Manager.user_name
27
- home_dir = Pvcglue::Manager.home_dir
28
- manager_dir = Pvcglue::Manager.manager_dir
29
- ssh_dir = Pvcglue::Manager.ssh_dir
30
-
31
- sudo "useradd -d #{home_dir} -m -U #{user_name}"
32
- sudo "usermod -s /bin/bash #{user_name}"
33
- sudo "mkdir -p #{manager_dir} && chown #{user_name}:#{user_name} #{manager_dir} && chmod 700 #{manager_dir}"
34
- sudo "mkdir -p #{ssh_dir} && chown #{user_name}:#{user_name} #{ssh_dir} && chmod 700 #{ssh_dir}"
35
- end
10
+ def installed?
11
+ get_minion_state(:manager_installed_at)
12
+ end
36
13
 
37
- remove do
38
- raise "removing user not supported, yet. It needs some 'Are you *really* sure?' stuff."
39
- # user_name = Pvcglue::Manager.user_name
40
- # home_dir = Pvcglue::Manager.home_dir
41
- #sudo "userdel -f #{user_name}"
42
- #sudo "rm -rf #{home_dir}"
43
- end
14
+ def install!
15
+ connection.mkdir_p(user_name, manager_dir, nil, nil, 700)
44
16
 
45
- validate do
46
- user_name = Pvcglue::Manager.user_name
47
- # home_dir = Pvcglue::Manager.home_dir
48
- #sudo "userdel -f #{user_name}"; sudo "rm -rf #{home_dir}"; raise "User has been deleted"
49
- sudo("getent passwd #{user_name}") =~ /^#{user_name}:/
50
- end
51
- end
17
+ connection.ssh!(user_name, '', 'git config --global user.name pvc_manager')
18
+ connection.ssh!(user_name, '', 'git config --global --global user.email pvc_manager@pvc.local')
19
+ connection.ssh!(user_name, '', "git init #{Pvcglue::Manager.manager_dir}")
52
20
 
53
- package 'manager-copy-id' do
54
- validate do
55
- authorized_keys_file_name = Pvcglue::Manager.authorized_keys_file_name
56
- user_key = `cat ~/.ssh/id_rsa.pub`.strip
57
- auth = run("cat #{authorized_keys_file_name}")
58
- auth.include?(user_key)
59
- end
21
+ # TODO: Create example configuration file, if none exists
22
+ connection.write_to_file(user_name, "#{Time.now.utc.to_s}\n", manager_test_filename)
23
+ connection.ssh!(user_name, '', %Q(cd #{manager_dir} && git status))
24
+ git_commit!
25
+ connection.ssh!(user_name, '', %Q(cd #{manager_dir} && git status))
60
26
 
61
- apply do
62
- authorized_keys_file_name = Pvcglue::Manager.authorized_keys_file_name
63
- user_name = Pvcglue::Manager.user_name
64
- copy_id = %Q[cat ~/.ssh/id_rsa.pub | ssh -o BatchMode=yes -o StrictHostKeyChecking=no #{node.get(:user)}@#{node.host} "cat >> #{authorized_keys_file_name}"]
65
- system "#{copy_id}"
66
- run(%Q[cat "" >> #{authorized_keys_file_name}])
67
- sudo "chown #{user_name}:#{user_name} #{authorized_keys_file_name} && chmod 600 #{authorized_keys_file_name}"
68
- end
69
- end
27
+ # https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History
28
+ connection.ssh!(user_name, '', %Q(cd #{manager_dir} && git log --pretty=format:"%h - %an, %ar : %s" && echo))
70
29
 
71
- package 'manager-push' do
72
- apply do
73
- if File.exists?(::Pvcglue.cloud.local_file_name)
74
- # scp foobar.txt your_username@remotehost.edu:/some/remote/directory
75
- cmd = %{scp #{::Pvcglue.cloud.local_file_name} #{node.get(:user)}@#{node.host}:#{::Pvcglue::Manager.manager_file_name}}
76
- puts "Running `#{cmd}`"
30
+ set_minion_state(:manager_installed_at, Time.now.utc)
31
+ end
77
32
 
78
- unless system cmd
79
- raise(Thor::Error, "Error: #{$?}")
33
+ def post_install_check?
34
+ return false unless connection.file_exists?(user_name, manager_dir)
35
+ return false unless working_directory_clean?
36
+ connection.file_exists?(user_name, manager_test_filename)
80
37
  end
81
38
 
82
- run(%Q[chmod 600 #{::Pvcglue::Manager.manager_file_name}])
83
- else
84
- puts "Local file not found: #{::Pvcglue.cloud.local_file_name}"
85
- end
86
- end
87
- end
39
+ def manager_dir
40
+ Pvcglue::Manager.manager_dir
41
+ end
88
42
 
89
- package 'manager-pull' do
90
- apply do
91
- # scp your_username@remotehost.edu:foobar.txt /some/local/directory
92
- cmd = %{scp #{node.get(:user)}@#{node.host}:#{::Pvcglue::Manager.manager_file_name} #{::Pvcglue.cloud.local_file_name}}
93
- puts "Running `#{cmd}`"
43
+ def manager_test_filename
44
+ File.join(manager_dir, 'install.log')
45
+ end
94
46
 
95
- unless system cmd
96
- raise(Thor::Error, "Error: #{$?}")
97
- end
47
+ def self.get_configuration
48
+ new.get_configuration
49
+ end
98
50
 
99
- puts "Saved as: #{::Pvcglue.cloud.local_file_name}"
100
- end
101
- end
51
+ def get_configuration
52
+ # if connection.file_exists?(user_name, ::Pvcglue::Manager.manager_file_name)
53
+ # data = connection.read_from_file(user_name, ::Pvcglue::Manager.manager_file_name)
54
+ # else
55
+ # # raise(Thor::Error, "Remote manager file not found: #{::Pvcglue::Manager.manager_file_name}")
56
+ # raise("Remote manager file not found: #{::Pvcglue::Manager.manager_file_name}")
57
+ # end
58
+ data = '' # to use `data` in block
59
+ Pvcglue.filter_verbose do
60
+ data = connection.read_from_file(user_name, ::Pvcglue::Manager.manager_file_name)
61
+ end
62
+ ::Pvcglue.cloud.data = TOML.parse(data)
63
+ end
64
+
65
+ def self.push_configuration
66
+ new.push_configuration
67
+ end
68
+
69
+ def push_configuration
70
+ connection.upload_file(user_name, ::Pvcglue.cloud.local_file_name, ::Pvcglue::Manager.manager_file_name, nil, nil, '600')
71
+ git_commit!
72
+ raise('Error saving configuration') unless working_directory_clean?
73
+ # TODO: Turn delete back on
74
+ # File.delete(::Pvcglue.cloud.local_file_name)
75
+ end
76
+
77
+ def git_commit!
78
+ connection.ssh!(user_name, '', %Q(cd #{manager_dir} && git add -A && git commit --allow-empty --author="pvc-$PVCGLUE_USER <>" -m "Change configuration"))
79
+ end
80
+
81
+ def working_directory_clean?
82
+ connection.run_get_stdout!(user_name, '', %Q(cd #{manager_dir} && git status)) =~ /working directory clean/
83
+ end
84
+
85
+ def self.pull_configuration
86
+ new.pull_configuration
87
+ # new(Pvcglue.cloud.manager_minion).pull_configuration
88
+ end
89
+
90
+ def pull_configuration
91
+ # TODO: Rename to edit_config_start, and create Thor commands to match
92
+ if connection.file_exists?(user_name, ::Pvcglue::Manager.manager_file_name)
93
+ data = connection.read_from_file(user_name, ::Pvcglue::Manager.manager_file_name)
94
+ else
95
+ data = "# Pvcglue manager configuration file\n\n"
96
+ end
97
+ file_name = ::Pvcglue.cloud.local_file_name
98
+ if File.exist?(file_name)
99
+ backup_file_name = ::Pvcglue.configuration.versioned_filename(file_name)
100
+ File.rename(file_name, backup_file_name)
101
+ Pvcglue.logger.info("Existing local configuration file saved to #{backup_file_name}")
102
+ end
103
+ File.write(file_name, data)
104
+ puts "Configuration saved to #{file_name}. Now edit it and push it back up."
105
+ end
106
+
107
+ def load_secrets
108
+ connection.read_from_file_if_exists?(user_name, ::Pvcglue::Env.stage_env_file_name)
109
+ end
110
+
111
+ def save_secrets(data)
112
+ connection.write_to_file(user_name, data, ::Pvcglue::Env.stage_env_file_name, nil, nil, 600)
113
+ git_commit!
114
+ end
102
115
 
103
- package 'manager-get-config' do
104
- apply do
105
- data = run("cat #{::Pvcglue::Manager.manager_file_name}")
106
- #puts "*"*80
107
- #puts data
108
- #puts "*"*80
109
- if data.empty?
110
- raise "Remote manager file not found: #{::Pvcglue::Manager.manager_file_name}"
111
- else
112
- ::Pvcglue.cloud.data = TOML.parse(data)
113
116
  end
114
117
  end
115
118
  end
116
-