bard 1.0.0 → 1.0.2

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +5 -0
  3. data/features/bard_check.feature +1 -1
  4. data/features/bard_push.feature +1 -1
  5. data/features/step_definitions/global_steps.rb +4 -4
  6. data/features/support/env.rb +1 -1
  7. data/features/support/io.rb +1 -1
  8. data/lib/bard/ci/github_actions.rb +3 -6
  9. data/lib/bard/ci/local.rb +0 -2
  10. data/lib/bard/ci.rb +10 -12
  11. data/lib/bard/cli/ci.rb +51 -0
  12. data/lib/bard/cli/data.rb +45 -0
  13. data/lib/bard/cli/deploy.rb +64 -0
  14. data/lib/bard/cli/hurt.rb +20 -0
  15. data/lib/bard/cli/install.rb +16 -0
  16. data/lib/bard/cli/master_key.rb +17 -0
  17. data/lib/bard/cli/open.rb +13 -0
  18. data/lib/bard/cli/ping.rb +18 -0
  19. data/lib/bard/cli/provision.rb +15 -0
  20. data/lib/bard/cli/run.rb +24 -0
  21. data/lib/bard/cli/setup.rb +45 -0
  22. data/lib/bard/cli/ssh.rb +14 -0
  23. data/lib/bard/cli/stage.rb +27 -0
  24. data/lib/bard/cli/vim.rb +13 -0
  25. data/lib/bard/cli.rb +21 -246
  26. data/lib/bard/command.rb +8 -6
  27. data/lib/bard/config.rb +2 -11
  28. data/lib/bard/copy.rb +15 -40
  29. data/lib/bard/git.rb +2 -4
  30. data/lib/bard/ping.rb +0 -1
  31. data/lib/bard/provision/apt.rb +16 -0
  32. data/lib/bard/provision/http.rb +1 -15
  33. data/lib/bard/provision/mysql.rb +0 -2
  34. data/lib/bard/provision/passenger.rb +2 -4
  35. data/lib/bard/provision/repo.rb +2 -2
  36. data/lib/bard/provision/rvm.rb +3 -2
  37. data/lib/bard/provision/ssh.rb +17 -10
  38. data/lib/bard/provision/user.rb +1 -0
  39. data/lib/bard/provision.rb +4 -21
  40. data/lib/bard/server.rb +29 -7
  41. data/lib/bard/version.rb +1 -1
  42. data/spec/bard/ci_spec.rb +10 -0
  43. data/spec/bard/config_spec.rb +83 -0
  44. data/spec/bard/server_spec.rb +127 -0
  45. metadata +24 -3
  46. /data/lib/bard/provision/{master_key.rb → masterkey.rb} +0 -0
data/lib/bard/cli.rb CHANGED
@@ -1,17 +1,9 @@
1
1
  # this file gets loaded in the CLI context, not the Rails boot context
2
2
 
3
3
  require "thor"
4
- require "bard/git"
5
- require "bard/ci"
6
- require "bard/copy"
7
- require "bard/github"
8
- require "bard/ping"
9
4
  require "bard/config"
10
5
  require "bard/command"
11
- require "bard/provision"
12
6
  require "term/ansicolor"
13
- require "open3"
14
- require "uri"
15
7
 
16
8
  module Bard
17
9
  class CLI < Thor
@@ -19,244 +11,24 @@ module Bard
19
11
 
20
12
  class_option :verbose, type: :boolean, aliases: :v
21
13
 
22
- desc "data --from=production --to=local", "copy database and assets from from to to"
23
- option :from, default: "production"
24
- option :to, default: "local"
25
- def data
26
- from = config[options[:from]]
27
- to = config[options[:to]]
28
-
29
- if to.key == :production
30
- url = to.ping.first
31
- puts yellow "WARNING: You are about to push data to production, overwriting everything that is there!"
32
- answer = ask("If you really want to do this, please type in the full HTTPS url of the production server:")
33
- if answer != url
34
- puts red("!!! ") + "Failed! We expected #{url}. Is this really where you want to overwrite all the data?"
35
- exit 1
36
- end
37
- end
38
-
39
- puts "Dumping #{from.key} database to file..."
40
- from.run! "bin/rake db:dump"
41
-
42
- puts "Transfering file from #{from.key} to #{to.key}..."
43
- from.copy_file "db/data.sql.gz", to: to, verbose: true
44
-
45
- puts "Loading file into #{to.key} database..."
46
- to.run! "bin/rake db:load"
47
-
48
- config.data.each do |path|
49
- puts "Synchronizing files in #{path}..."
50
- from.copy_dir path, to: to, verbose: true
51
- end
52
- end
53
-
54
- desc "master_key --from=production --to=local", "copy master key from from to to"
55
- option :from, default: "production"
56
- option :to, default: "local"
57
- def master_key
58
- from = config[options[:from]]
59
- to = config[options[:to]]
60
- from.copy_file "config/master.key", to:
61
- end
62
-
63
- desc "stage [branch=HEAD]", "pushes current branch, and stages it"
64
- def stage branch=Git.current_branch
65
- unless config.servers.key?(:production)
66
- raise Thor::Error.new("`bard stage` is disabled until a production server is defined. Until then, please use `bard deploy` to deploy to the staging server.")
67
- end
68
-
69
- run! "git push -u origin #{branch}", verbose: true
70
- config[:staging].run! "git fetch && git checkout -f origin/#{branch} && bin/setup"
71
- puts green("Stage Succeeded")
72
-
73
- ping :staging
74
- end
75
-
76
- option :"skip-ci", type: :boolean
77
- option :"local-ci", type: :boolean
78
- desc "deploy [TO=production]", "checks that current branch is a ff with master, checks with ci, merges into master, deploys to target, and then deletes branch."
79
- def deploy to=:production
80
- branch = Git.current_branch
81
-
82
- if branch == "master"
83
- if !Git.up_to_date_with_remote?(branch)
84
- run! "git push origin #{branch}:#{branch}"
85
- end
86
- invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]
87
-
88
- else
89
- run! "git fetch origin master:master"
90
-
91
- unless Git.fast_forward_merge?("origin/master", branch)
92
- puts "The master branch has advanced. Attempting rebase..."
93
- run! "git rebase origin/master"
94
- end
95
-
96
- run! "git push -f origin #{branch}:#{branch}"
97
-
98
- invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]
99
-
100
- run! "git push origin #{branch}:master"
101
- run! "git fetch origin master:master"
102
- end
103
-
104
- if `git remote` =~ /\bgithub\b/
105
- run! "git push github"
106
- end
107
-
108
- config[to].run! "git pull origin master && bin/setup"
109
-
110
- puts green("Deploy Succeeded")
111
-
112
- if branch != "master"
113
- puts "Deleting branch: #{branch}"
114
- run! "git push --delete origin #{branch}"
115
-
116
- if branch == Git.current_branch
117
- run! "git checkout master"
118
- end
119
-
120
- run! "git branch -D #{branch}"
121
- end
122
-
123
- ping to
124
- end
125
-
126
- option :"local-ci", type: :boolean
127
- option :status, type: :boolean
128
- desc "ci [branch=HEAD]", "runs ci against BRANCH"
129
- def ci branch=Git.current_branch
130
- ci = CI.new(project_name, branch, local: options["local-ci"])
131
- if ci.exists?
132
- return puts ci.status if options["status"]
133
-
134
- puts "Continuous integration: starting build on #{branch}..."
135
-
136
- success = ci.run do |elapsed_time, last_time|
137
- if last_time
138
- percentage = (elapsed_time.to_f / last_time.to_f * 100).to_i
139
- output = " Estimated completion: #{percentage}%"
140
- else
141
- output = " No estimated completion time. Elapsed time: #{elapsed_time} sec"
142
- end
143
- print "\x08" * output.length
144
- print output
145
- $stdout.flush
146
- end
147
-
148
- if success
149
- puts
150
- puts "Continuous integration: success!"
151
- puts "Deploying..."
152
- else
153
- puts
154
- puts ci.last_response
155
- puts ci.console
156
- puts red("Automated tests failed!")
157
- exit 1
158
- end
159
-
160
- else
161
- puts red("No CI found for #{project_name}!")
162
- puts "Re-run with --skip-ci to bypass CI, if you absolutely must, and know what you're doing."
163
- exit 1
164
- end
165
- end
166
-
167
- desc "open [server=production]", "opens the url in the web browser."
168
- def open server=:production
169
- exec "xdg-open #{config[server].ping.first}"
170
- end
171
-
172
- option :home, type: :boolean
173
- desc "ssh [to=production]", "logs into the specified server via SSH"
174
- def ssh to=:production
175
- config[to].exec! "exec $SHELL -l", home: options[:home]
176
- end
177
-
178
- desc "install", "copies bin/setup and bin/ci scripts into current project."
179
- def install
180
- install_files_path = File.expand_path(File.join(__dir__, "../../install_files/*"))
181
- system "cp -R #{install_files_path} bin/"
182
- github_files_path = File.expand_path(File.join(__dir__, "../../install_files/.github"))
183
- system "cp -R #{github_files_path} ./"
184
- end
185
-
186
- desc "provision [ssh_url]", "takes an ssh url to a raw ubuntu 22.04 install, and readies it in the shape of :production"
187
- def provision ssh_url
188
- Provision.call(config, ssh_url.dup) # dup unfreezes the string for later mutation
189
- end
190
-
191
- desc "setup", "installs app in nginx"
192
- def setup
193
- path = "/etc/nginx/sites-available/#{project_name}"
194
- dest_path = path.sub("sites-available", "sites-enabled")
195
- server_name = case ENV["RAILS_ENV"]
196
- when "production"
197
- (config[:production].ping.map do |str|
198
- "*.#{URI.parse(str).host}"
199
- end + ["_"]).join(" ")
200
- when "staging" then "#{project_name}.botandrose.com"
201
- else "#{project_name}.localhost"
202
- end
203
-
204
- system "sudo tee #{path} >/dev/null <<-EOF
205
- server {
206
- listen 80;
207
- server_name #{server_name};
208
-
209
- root #{Dir.pwd}/public;
210
- passenger_enabled on;
211
-
212
- location ~* \\.(ico|css|js|gif|jp?g|png|webp) {
213
- access_log off;
214
- if (\\$request_filename ~ \"-[0-9a-f]{32}\\.\") {
215
- expires max;
216
- add_header Cache-Control public;
217
- }
218
- }
219
- gzip_static on;
220
- }
221
- EOF"
222
- system "sudo ln -sf #{path} #{dest_path}" if !File.exist?(dest_path)
223
- system "sudo service nginx restart"
224
- end
225
-
226
- desc "ping [server=production]", "hits the server over http to verify that its up."
227
- def ping server=:production
228
- server = config[server]
229
- down_urls = Bard::Ping.call(config[server])
230
- down_urls.each { |url| puts "#{url} is down!" }
231
- exit 1 if down_urls.any?
232
- end
233
-
234
- # HACK: we don't use Thor::Base#run, so its okay to stomp on it here
235
- original_verbose, $VERBOSE = $VERBOSE, nil
236
- Thor::THOR_RESERVED_WORDS -= ["run"]
237
- $VERBOSE = original_verbose
238
-
239
- desc "run <command>", "run the given command on production"
240
- def run *args
241
- server = config[:production]
242
- server.run! *args, verbose: true
243
- end
244
-
245
- desc "hurt <command>", "reruns a command until it fails"
246
- def hurt *args
247
- 1.upto(Float::INFINITY) do |count|
248
- puts "Running attempt #{count}"
249
- system *args
250
- unless $?.success?
251
- puts "Ran #{count-1} times before failing"
252
- break
253
- end
254
- end
255
- end
256
-
257
- desc "vim [branch=master]", "open all files that have changed since master"
258
- def vim branch="master"
259
- exec "vim -p `git diff #{branch} --name-only | grep -v sass$ | tac`"
14
+ {
15
+ data: "Data",
16
+ stage: "Stage",
17
+ deploy: "Deploy",
18
+ ci: "CI",
19
+ master_key: "MasterKey",
20
+ setup: "Setup",
21
+ run: "Run",
22
+ open: "Open",
23
+ ssh: "SSH",
24
+ install: "Install",
25
+ provision: "Provision",
26
+ ping: "Ping",
27
+ hurt: "Hurt",
28
+ vim: "Vim",
29
+ }.each do |command, klass|
30
+ require "bard/cli/#{command}"
31
+ include const_get(klass)
260
32
  end
261
33
 
262
34
  def self.exit_on_failure? = true
@@ -273,6 +45,9 @@ EOF"
273
45
 
274
46
  def run!(...)
275
47
  Bard::Command.run!(...)
48
+ rescue Bard::Command::Error => e
49
+ puts red("!!! ") + "Running command failed: #{yellow(e.message)}"
50
+ exit 1
276
51
  end
277
52
  end
278
53
  end
data/lib/bard/command.rb CHANGED
@@ -1,5 +1,9 @@
1
+ require "open3"
2
+
1
3
  module Bard
2
4
  class Command < Struct.new(:command, :on, :home)
5
+ class Error < RuntimeError; end
6
+
3
7
  def self.run! command, on: :local, home: false, verbose: false, quiet: false
4
8
  new(command, on, home).run! verbose:, quiet:
5
9
  end
@@ -14,9 +18,7 @@ module Bard
14
18
 
15
19
  def run! verbose: false, quiet: false
16
20
  if !run(verbose:, quiet:)
17
- raise "Running command failed: #{full_command}"
18
- # puts red("!!! ") + "Running command failed: #{yellow(command)}"
19
- # exit 1
21
+ raise Error.new(full_command)
20
22
  end
21
23
  end
22
24
 
@@ -49,7 +51,6 @@ module Bard
49
51
  end
50
52
 
51
53
  def remote_command quiet: false
52
- uri = on.ssh_uri
53
54
  ssh_key = on.ssh_key ? "-i #{on.ssh_key} " : ""
54
55
  cmd = command
55
56
  if on.env
@@ -58,10 +59,11 @@ module Bard
58
59
  unless home
59
60
  cmd = "cd #{on.path} && #{cmd}"
60
61
  end
61
- cmd = "ssh -tt #{ssh_key}#{"-p#{uri.port} " if uri.port}#{uri.user}@#{uri.host} '#{cmd}'"
62
+ uri = on.ssh_uri
63
+ cmd = "ssh -tt #{ssh_key} -p#{uri.port} #{uri.user}@#{uri.host} '#{cmd}'"
62
64
  if on.gateway
63
65
  uri = on.ssh_uri(:gateway)
64
- cmd = "ssh -tt #{" -p#{uri.port} " if uri.port}#{uri.user}@#{uri.host} \"#{cmd}\""
66
+ cmd = "ssh -tt -p#{uri.port} #{uri.user}@#{uri.host} \"#{cmd}\""
65
67
  end
66
68
  cmd += " 2>&1" if quiet
67
69
  cmd
data/lib/bard/config.rb CHANGED
@@ -12,13 +12,6 @@ module Bard
12
12
  "./",
13
13
  false,
14
14
  ),
15
- theia: Server.new(
16
- project_name,
17
- :theia,
18
- "gubito@gubs.pagekite.me",
19
- "Sites/#{project_name}",
20
- false,
21
- ),
22
15
  gubs: Server.new(
23
16
  project_name,
24
17
  :gubs,
@@ -40,7 +33,7 @@ module Bard
40
33
  ),
41
34
  }
42
35
  if path && File.exist?(path)
43
- source = File.read(File.expand_path(path))
36
+ source = File.read(path)
44
37
  end
45
38
  if source
46
39
  instance_eval source
@@ -51,9 +44,7 @@ module Bard
51
44
 
52
45
  def server key, &block
53
46
  key = key.to_sym
54
- @servers[key] ||= Server.new(project_name, key)
55
- @servers[key].instance_eval &block if block_given?
56
- @servers[key]
47
+ @servers[key] = Server.define(project_name, key, &block)
57
48
  end
58
49
 
59
50
  def [] key
data/lib/bard/copy.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require "uri"
2
+ require "bard/command"
3
+
1
4
  module Bard
2
5
  class Copy < Struct.new(:path, :from, :to, :verbose)
3
6
  def self.file path, from:, to:, verbose: false
@@ -19,33 +22,20 @@ module Bard
19
22
  end
20
23
 
21
24
  def scp_using_local direction, server
22
- uri = URI.parse("ssh://#{server.gateway}")
23
- port = uri.port ? "-p#{uri.port}" : ""
24
- gateway = server.gateway ? "-oProxyCommand='ssh #{port} #{uri.user}@#{uri.host} -W %h:%p'" : ""
25
+ gateway = server.gateway ? "-oProxyCommand='ssh #{server.ssh_uri(:gateway)} -W %h:%p'" : ""
25
26
 
26
27
  ssh_key = server.ssh_key ? "-i #{server.ssh_key}" : ""
27
28
 
28
- uri = URI.parse("ssh://#{server.ssh}")
29
- port = uri.port ? "-P#{uri.port}" : ""
30
- from_and_to = [path, "#{uri.user}@#{uri.host}:#{server.path}/#{path}"]
31
-
29
+ from_and_to = [path, server.scp_uri(path)]
32
30
  from_and_to.reverse! if direction == :from
33
- command = "scp #{gateway} #{ssh_key} #{port} #{from_and_to.join(" ")}"
34
31
 
32
+ command = ["scp", gateway, ssh_key, *from_and_to].join(" ")
35
33
  Bard::Command.run! command, verbose: verbose
36
34
  end
37
35
 
38
36
  def scp_as_mediator
39
37
  raise NotImplementedError if from.gateway || to.gateway || from.ssh_key || to.ssh_key
40
-
41
- from_uri = URI.parse("ssh://#{from.ssh}")
42
- from_str = "scp://#{from_uri.user}@#{from_uri.host}:#{from_uri.port || 22}/#{from.path}/#{path}"
43
-
44
- to_uri = URI.parse("ssh://#{to.ssh}")
45
- to_str = "scp://#{to_uri.user}@#{to_uri.host}:#{to_uri.port || 22}/#{to.path}/#{path}"
46
-
47
- command = "scp -o ForwardAgent=yes #{from_str} #{to_str}"
48
-
38
+ command = "scp -o ForwardAgent=yes #{from.scp_uri(path)} #{to.scp_uri(path)}"
49
39
  Bard::Command.run! command, verbose: verbose
50
40
  end
51
41
 
@@ -55,46 +45,31 @@ module Bard
55
45
  elsif to.key == :local
56
46
  rsync_using_local :from, from
57
47
  else
58
- rsync_as_mediator from, to
48
+ rsync_as_mediator
59
49
  end
60
50
  end
61
51
 
62
52
  def rsync_using_local direction, server
63
- uri = URI.parse("ssh://#{server.gateway}")
64
- port = uri.port ? "-p#{uri.port}" : ""
65
- gateway = server.gateway ? "-oProxyCommand=\"ssh #{port} #{uri.user}@#{uri.host} -W %h:%p\"" : ""
53
+ gateway = server.gateway ? "-oProxyCommand=\"ssh #{server.ssh_uri(:gateway)} -W %h:%p\"" : ""
66
54
 
67
55
  ssh_key = server.ssh_key ? "-i #{server.ssh_key}" : ""
68
- uri = URI.parse("ssh://#{server.ssh}")
69
- port = uri.port ? "-p#{uri.port}" : ""
70
- ssh = "-e'ssh #{ssh_key} #{port} #{gateway}'"
56
+ ssh = "-e'ssh #{gateway} -p#{server.ssh_uri.port || 22}'"
71
57
 
72
- dest_path = path.dup
73
- dest_path = "./#{dest_path}"
74
- from_and_to = [dest_path, "#{uri.user}@#{uri.host}:#{server.path}/#{path}"]
58
+ from_and_to = ["./#{path}", server.rsync_uri(path)]
75
59
  from_and_to.reverse! if direction == :from
76
60
  from_and_to[-1].sub! %r(/[^/]+$), '/'
77
61
 
78
62
  command = "rsync #{ssh} --delete --info=progress2 -az #{from_and_to.join(" ")}"
79
-
80
63
  Bard::Command.run! command, verbose: verbose
81
64
  end
82
65
 
83
- def rsync_as_mediator from, to
66
+ def rsync_as_mediator
84
67
  raise NotImplementedError if from.gateway || to.gateway || from.ssh_key || to.ssh_key
85
68
 
86
- dest_path = path.dup
87
- dest_path = "./#{dest_path}"
88
-
89
- from_uri = URI.parse("ssh://#{from.ssh}")
90
- from_str = "-p#{from_uri.port || 22} #{from_uri.user}@#{from_uri.host}"
91
-
92
- to_uri = URI.parse("ssh://#{to.ssh}")
93
- to_str = "#{to_uri.user}@#{to_uri.host}:#{to.path}/#{path}"
94
- to_str.sub! %r(/[^/]+$), '/'
95
-
96
- command = %(ssh -A #{from_str} 'rsync -e \"ssh -A -p#{to_uri.port || 22} -o StrictHostKeyChecking=no\" --delete --info=progress2 -az #{from.path}/#{path} #{to_str}')
69
+ from_str = "-p#{from.ssh_uri.port || 22} #{from.ssh_uri.user}@#{from.ssh_uri.host}"
70
+ to_str = to.rsync_uri(path).sub(%r(/[^/]+$), '/')
97
71
 
72
+ command = %(ssh -A #{from_str} 'rsync -e \"ssh -A -p#{to.ssh_uri.port || 22} -o StrictHostKeyChecking=no\" --delete --info=progress2 -az #{from.path}/#{path} #{to_str}')
98
73
  Bard::Command.run! command, verbose: verbose
99
74
  end
100
75
  end
data/lib/bard/git.rb CHANGED
@@ -8,10 +8,6 @@ module Bard
8
8
  ref.sub(/refs\/heads\//, '') # refs/heads/master ... we want "master"
9
9
  end
10
10
 
11
- def current_sha
12
- sha_of("HEAD")
13
- end
14
-
15
11
  def fast_forward_merge?(root, branch)
16
12
  root_head = sha_of(root)
17
13
  branch_head = sha_of(branch)
@@ -23,6 +19,8 @@ module Bard
23
19
  sha_of(branch) == sha_of("origin/#{branch}")
24
20
  end
25
21
 
22
+ private
23
+
26
24
  def sha_of ref
27
25
  `git rev-parse #{ref}`.chomp
28
26
  end
data/lib/bard/ping.rb CHANGED
@@ -9,7 +9,6 @@ module Bard
9
9
 
10
10
  def call
11
11
  server.ping.reject do |url|
12
- next true if url == false
13
12
  response = get_response_with_redirect(url) rescue nil
14
13
  response.is_a?(Net::HTTPSuccess)
15
14
  end
@@ -0,0 +1,16 @@
1
+ # apt sanity
2
+
3
+ class Bard::Provision::Apt < Bard::Provision
4
+ def call
5
+ print "Apt:"
6
+ provision_server.run! [
7
+ %(echo "\\$nrconf{restart} = \\"a\\";" | sudo tee /etc/needrestart/conf.d/90-autorestart.conf),
8
+ "sudo apt-get update -y",
9
+ "sudo apt-get upgrade -y",
10
+ "sudo apt-get install -y curl",
11
+ ].join("; "), home: true
12
+
13
+ puts " ✓"
14
+ end
15
+ end
16
+
@@ -4,25 +4,11 @@ class Bard::Provision::HTTP < Bard::Provision
4
4
  def call
5
5
  print "HTTP:"
6
6
  target_host = URI.parse(server.ping.first).host
7
- if system "curl -s --resolve #{target_host}:80:#{provision_server.ssh_uri.host} http://#{target_host} -I | grep -i \"x-powered-by: phusion passenger\""
7
+ if system "curl -s --resolve #{target_host}:80:#{provision_server.ssh_uri.host} http://#{target_host} -I | grep -i \"x-powered-by: phusion passenger\" >/dev/null 2>&1"
8
8
  puts " ✓"
9
9
  else
10
10
  puts " !!! not serving a rails app from #{provision_server.ssh_uri.host}"
11
11
  end
12
12
  end
13
-
14
- private
15
-
16
- def ssh_available? ssh_uri, port: ssh_uri.port
17
- system "nc -zv #{ssh_uri.host} #{port} 2>/dev/null"
18
- end
19
-
20
- def ssh_known_host? ssh_uri
21
- system "grep -q \"$(ssh-keyscan -t ed25519 -p#{ssh_uri.port || 22} #{ssh_uri.host} 2>/dev/null | cut -d ' ' -f 2-3)\" ~/.ssh/known_hosts"
22
- end
23
-
24
- def add_ssh_known_host! ssh_uri
25
- system "ssh-keyscan -p#{ssh_uri.port || 22} -H #{ssh_uri.host} >> ~/.ssh/known_hosts"
26
- end
27
13
  end
28
14
 
@@ -19,5 +19,3 @@ class Bard::Provision::MySQL < Bard::Provision
19
19
  end
20
20
  end
21
21
 
22
-
23
-
@@ -6,16 +6,14 @@ class Bard::Provision::Passenger < Bard::Provision
6
6
  if !http_responding?
7
7
  print " Installing nginx & Passenger,"
8
8
  provision_server.run! [
9
- %(echo "\\$nrconf{restart} = \\"a\\";" | sudo tee /etc/needrestart/conf.d/90-autorestart.conf),
10
9
  %(grep -qxF "RAILS_ENV=production" /etc/environment || echo "RAILS_ENV=production" | sudo tee -a /etc/environment),
11
10
  %(grep -qxF "EDITOR=vim" /etc/environment || echo "EDITOR=vim" | sudo tee -a /etc/environment),
12
- "sudo apt-get update -y",
13
- "sudo apt-get upgrade -y",
14
- "sudo apt-get install -y vim dirmngr gnupg apt-transport-https ca-certificates curl",
11
+ "sudo apt-get install -y vim dirmngr gnupg apt-transport-https ca-certificates",
15
12
  "curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/phusion.gpg >/dev/null",
16
13
  %(echo "deb https://oss-binaries.phusionpassenger.com/apt/passenger jammy main" | sudo tee /etc/apt/sources.list.d/passenger.list),
17
14
  "sudo apt-get update -y",
18
15
  "sudo apt-get install -y nginx libnginx-mod-http-passenger",
16
+ "sudo rm /etc/nginx/sites-enabled/default",
19
17
  ].join("; "), home: true
20
18
  end
21
19
 
@@ -37,9 +37,9 @@ class Bard::Provision::Repo < Bard::Provision
37
37
  github_url = "git@github.com:botandrosedesign/#{project_name}"
38
38
  provision_server.run [
39
39
  "needle=$(ssh-keyscan -t ed25519 github.com 2>/dev/null | cut -d \" \" -f 2-3)",
40
- "grep -q \"$needle\" ~/.ssh/known_hosts || ssh-keyscan -H github.com >> ~/.ssh/known_hosts",
40
+ "grep -q \"$needle\" ~/.ssh/known_hosts || ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null",
41
41
  "git ls-remote #{github_url}",
42
- ].join("; "), home: true
42
+ ].join("; "), home: true, quiet: true
43
43
  end
44
44
 
45
45
  def project_name
@@ -10,8 +10,9 @@ class Bard::Provision::RVM < Bard::Provision
10
10
  "gpg --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB",
11
11
  "curl -sSL https://get.rvm.io | bash -s stable",
12
12
  ].join("; ")
13
- print " Installing Ruby #{File.read(".ruby-version")},"
14
- provision_server.run! "rvm install ."
13
+ version = File.read(".ruby-version").chomp
14
+ print " Installing Ruby #{version},"
15
+ provision_server.run! "rvm install #{version}"
15
16
  end
16
17
 
17
18
  puts " ✓"
@@ -5,16 +5,16 @@ class Bard::Provision::SSH < Bard::Provision
5
5
  def call
6
6
  print "SSH:"
7
7
 
8
- if !ssh_available?(provision_server.ssh_uri, port: server.ssh_uri.port)
8
+ if !ssh_available?(provision_server.ssh_uri, port: target_port)
9
9
  if !ssh_available?(provision_server.ssh_uri)
10
- raise "can't find SSH on port #{server.ssh_uri.port} or #{provision_server.ssh_uri.port}"
10
+ raise "can't find SSH on port #{target_port} or #{provision_server.ssh_uri.port || 22}"
11
11
  end
12
12
  if !ssh_known_host?(provision_server.ssh_uri)
13
13
  print " Adding known host,"
14
14
  add_ssh_known_host!(provision_server.ssh_uri)
15
15
  end
16
- print " Reconfiguring port to #{server.ssh_uri.port},"
17
- provision.server.run! %(echo "Port #{server.ssh_uri.port}" | sudo tee /etc/ssh/sshd_config.d/port_22022.conf; sudo service ssh restart), home: true
16
+ print " Reconfiguring port to #{target_port},"
17
+ provision_server.run! %(echo "Port #{target_port}" | sudo tee /etc/ssh/sshd_config.d/port_#{target_port}.conf; sudo service ssh restart), home: true
18
18
  end
19
19
 
20
20
  if !ssh_known_host?(provision_server.ssh_uri)
@@ -22,23 +22,30 @@ class Bard::Provision::SSH < Bard::Provision
22
22
  add_ssh_known_host!(provision_server.ssh_uri)
23
23
  end
24
24
 
25
- # provision with new port from now on
25
+ # provision with new target port from now on
26
26
  ssh_url.gsub!(/:\d+$/, "")
27
- ssh_url << ":#{server.ssh_uri.port}"
27
+ ssh_url << ":#{target_port}"
28
28
  puts " ✓"
29
29
  end
30
-
30
+
31
31
  private
32
32
 
33
- def ssh_available? ssh_uri, port: ssh_uri.port
33
+ def target_port
34
+ server.ssh_uri.port || 22
35
+ end
36
+
37
+ def ssh_available? ssh_uri, port: nil
38
+ port ||= ssh_uri.port || 22
34
39
  system "nc -zv #{ssh_uri.host} #{port} 2>/dev/null"
35
40
  end
36
41
 
37
42
  def ssh_known_host? ssh_uri
38
- system "grep -q \"$(ssh-keyscan -t ed25519 -p#{ssh_uri.port || 22} #{ssh_uri.host} 2>/dev/null | cut -d ' ' -f 2-3)\" ~/.ssh/known_hosts"
43
+ port ||= ssh_uri.port || 22
44
+ system "grep -q \"$(ssh-keyscan -t ed25519 -p#{port} #{ssh_uri.host} 2>/dev/null | cut -d ' ' -f 2-3)\" ~/.ssh/known_hosts"
39
45
  end
40
46
 
41
47
  def add_ssh_known_host! ssh_uri
42
- system "ssh-keyscan -p#{ssh_uri.port || 22} -H #{ssh_uri.host} >> ~/.ssh/known_hosts"
48
+ port ||= ssh_uri.port || 22
49
+ system "ssh-keyscan -p#{port} -H #{ssh_uri.host} >> ~/.ssh/known_hosts 2>/dev/null"
43
50
  end
44
51
  end
@@ -16,6 +16,7 @@ class Bard::Provision::User < Bard::Provision
16
16
  "sudo mkdir -p ~#{new_user}/.ssh",
17
17
  "sudo cp ~/.ssh/authorized_keys ~#{new_user}/.ssh/authorized_keys",
18
18
  "sudo chown -R #{new_user}:#{new_user} ~#{new_user}/.ssh",
19
+ "sudo chmod +rx ~#{new_user}", # so nginx and passenger can read it
19
20
  ].join("; "), home: true
20
21
  end
21
22