bard-new 0.1.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 +7 -0
- data/.github/workflows/ci.yml +42 -0
- data/.gitignore +4 -0
- data/CLAUDE.md +55 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +179 -0
- data/README.md +107 -0
- data/Rakefile +8 -0
- data/bard-new.gemspec +25 -0
- data/features/new.feature +12 -0
- data/features/provision.feature +10 -0
- data/features/step_definitions/bard_new_steps.rb +64 -0
- data/features/support/bard-coverage +16 -0
- data/features/support/env.rb +22 -0
- data/features/support/new_server.rb +136 -0
- data/features/support/provision_server.rb +282 -0
- data/lib/bard/new/cli/new.rb +102 -0
- data/lib/bard/new/cli/provision.rb +32 -0
- data/lib/bard/new/provision/app.rb +9 -0
- data/lib/bard/new/provision/apt.rb +15 -0
- data/lib/bard/new/provision/authorizedkeys.rb +23 -0
- data/lib/bard/new/provision/base.rb +17 -0
- data/lib/bard/new/provision/data.rb +23 -0
- data/lib/bard/new/provision/deploy.rb +9 -0
- data/lib/bard/new/provision/http.rb +15 -0
- data/lib/bard/new/provision/logrotation.rb +27 -0
- data/lib/bard/new/provision/masterkey.rb +17 -0
- data/lib/bard/new/provision/mysql.rb +21 -0
- data/lib/bard/new/provision/nginx.rb +31 -0
- data/lib/bard/new/provision/repo.rb +71 -0
- data/lib/bard/new/provision/rvm.rb +20 -0
- data/lib/bard/new/provision/ssh.rb +79 -0
- data/lib/bard/new/provision/swapfile.rb +21 -0
- data/lib/bard/new/provision/user.rb +43 -0
- data/lib/bard/new/rails_template.rb +213 -0
- data/lib/bard/new/version.rb +5 -0
- data/lib/bard/plugins/new.rb +2 -0
- data/spec/acceptance/docker/Dockerfile.new +68 -0
- data/spec/acceptance/docker/Dockerfile.provision +41 -0
- data/spec/acceptance/docker/entrypoint-new.sh +3 -0
- data/spec/acceptance/docker/test_key +27 -0
- data/spec/acceptance/docker/test_key.pub +1 -0
- data/spec/bard/new/cli/new_spec.rb +85 -0
- data/spec/bard/new/cli/provision_spec.rb +40 -0
- data/spec/bard/new/provision/app_spec.rb +33 -0
- data/spec/bard/new/provision/apt_spec.rb +39 -0
- data/spec/bard/new/provision/authorizedkeys_spec.rb +40 -0
- data/spec/bard/new/provision/base_spec.rb +34 -0
- data/spec/bard/new/provision/data_spec.rb +54 -0
- data/spec/bard/new/provision/deploy_spec.rb +33 -0
- data/spec/bard/new/provision/http_spec.rb +57 -0
- data/spec/bard/new/provision/logrotation_spec.rb +34 -0
- data/spec/bard/new/provision/masterkey_spec.rb +62 -0
- data/spec/bard/new/provision/mysql_spec.rb +55 -0
- data/spec/bard/new/provision/nginx_spec.rb +81 -0
- data/spec/bard/new/provision/repo_spec.rb +208 -0
- data/spec/bard/new/provision/rvm_spec.rb +49 -0
- data/spec/bard/new/provision/ssh_spec.rb +242 -0
- data/spec/bard/new/provision/swapfile_spec.rb +33 -0
- data/spec/bard/new/provision/user_spec.rb +103 -0
- data/spec/spec_helper.rb +19 -0
- metadata +214 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-----BEGIN OPENSSH PRIVATE KEY-----
|
|
2
|
+
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
|
|
27
|
+
-----END OPENSSH PRIVATE KEY-----
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6+euShWHoAhIGGpQ62a9N/pMyir8OjqL9rKfVqqz1iZs3nu01WdhcQoFDXkcvluq5jQDgVx/mY7vcvKscZ1Q4OslLq9mjgnzByjITIrE4LZRhXmywJSe2rXd14ThZUd9LKQwSj3PdTtvEVLC3BTwQJhAcotvg4GZBviGn+cO/HgQznniVoFQHIabx+BIo6VgYR1YTQoAVWwp+RFbwCJHZG1DkLWEhP/MKYejTVZO0cym7JmThzGkGVLfHPrCwPrV/pKAyEzRfnvmN9X8zGFsN3cUaTEiTyQzbgO0t8tb2J1hYMPbl19C5crd5BkMne9ygpr7Zbvdd8d18GsAau+Np bard-test-key
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "bard new" do
|
|
4
|
+
let(:cli) { Bard::CLI.new }
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
allow(cli).to receive(:puts)
|
|
8
|
+
allow(cli).to receive(:exit)
|
|
9
|
+
allow(cli).to receive(:run!)
|
|
10
|
+
allow(cli).to receive(:green).and_return("")
|
|
11
|
+
allow(cli).to receive(:red).and_return("")
|
|
12
|
+
allow(cli).to receive(:yellow).and_return("")
|
|
13
|
+
allow(File).to receive(:read).and_return("master_key_content")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "#new" do
|
|
17
|
+
context "with --skip-github and --skip-stage" do
|
|
18
|
+
let(:cli) { Bard::CLI.new([], skip_github: true, skip_stage: true) }
|
|
19
|
+
|
|
20
|
+
before do
|
|
21
|
+
allow(cli).to receive(:new_create_project)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "skips github and stage steps" do
|
|
25
|
+
expect(cli).not_to receive(:new_push_to_github)
|
|
26
|
+
expect(cli).not_to receive(:new_stage)
|
|
27
|
+
cli.new("testproject")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "with invalid project name" do
|
|
32
|
+
before do
|
|
33
|
+
allow(cli).to receive(:new_create_project)
|
|
34
|
+
allow(cli).to receive(:new_push_to_github)
|
|
35
|
+
allow(cli).to receive(:new_stage)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should reject names starting with uppercase" do
|
|
39
|
+
expect(cli).to receive(:puts).with(/Invalid project name/)
|
|
40
|
+
expect(cli).to receive(:exit).with(1)
|
|
41
|
+
|
|
42
|
+
cli.new("InvalidProject")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should reject names with special characters" do
|
|
46
|
+
expect(cli).to receive(:puts).with(/Invalid project name/)
|
|
47
|
+
expect(cli).to receive(:exit).with(1)
|
|
48
|
+
|
|
49
|
+
cli.new("invalid-project")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should reject names starting with numbers" do
|
|
53
|
+
expect(cli).to receive(:puts).with(/Invalid project name/)
|
|
54
|
+
expect(cli).to receive(:exit).with(1)
|
|
55
|
+
|
|
56
|
+
cli.new("1invalidproject")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe "#new_ruby_version" do
|
|
62
|
+
it "returns the ruby version" do
|
|
63
|
+
expect(cli.send(:new_ruby_version)).to eq("ruby-4.0.2")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "#new_template_path" do
|
|
68
|
+
it "returns the path to the rails template" do
|
|
69
|
+
expect(cli.send(:new_template_path)).to match(/rails_template\.rb$/)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe "#install_and_extract_version" do
|
|
74
|
+
it "correctly installs a gem and extracts its version", skip: !!ENV["CI"] do
|
|
75
|
+
cmd = cli.send :new_build_bash_env do
|
|
76
|
+
<<~SH
|
|
77
|
+
#{cli.send(:new_build_gem_install, "bundler", "~> 2.0")}
|
|
78
|
+
echo ${GEM_VERSION}
|
|
79
|
+
SH
|
|
80
|
+
end
|
|
81
|
+
result = `#{cmd}`.strip
|
|
82
|
+
expect(result).to match(/^2\.\d+\.\d+/)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "bard provision" do
|
|
4
|
+
let(:config) { { production: double("production", ssh: "user@example.com") } }
|
|
5
|
+
let(:cli) { Bard::CLI.new }
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
allow(cli).to receive(:config).and_return(config)
|
|
9
|
+
allow(cli).to receive(:options).and_return({ steps: ["SSH", "User"] })
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "PROVISION_STEPS constant" do
|
|
13
|
+
it "defines the provisioning steps" do
|
|
14
|
+
expect(Bard::CLI::PROVISION_STEPS).to include("SSH", "User", "Apt", "MySQL", "Deploy")
|
|
15
|
+
expect(Bard::CLI::PROVISION_STEPS).to be_a(Array)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#provision" do
|
|
20
|
+
it "should run provision steps" do
|
|
21
|
+
expect(Bard::Provision).to receive(:const_get).with("SSH").and_return(double("ssh_step", call: true))
|
|
22
|
+
expect(Bard::Provision).to receive(:const_get).with("User").and_return(double("user_step", call: true))
|
|
23
|
+
|
|
24
|
+
cli.provision
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should use production ssh by default" do
|
|
28
|
+
allow(Bard::Provision).to receive(:const_get).and_return(double("step", call: true))
|
|
29
|
+
|
|
30
|
+
cli.provision
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should accept custom ssh_url" do
|
|
34
|
+
custom_ssh = "root@newserver.com"
|
|
35
|
+
allow(Bard::Provision).to receive(:const_get).and_return(double("step", call: true))
|
|
36
|
+
|
|
37
|
+
cli.provision(custom_ssh)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/app"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::App do
|
|
6
|
+
let(:config) { { production: double("production") } }
|
|
7
|
+
let(:ssh_url) { "user@example.com" }
|
|
8
|
+
let(:provision_server) { double("provision_server") }
|
|
9
|
+
let(:app) { Bard::Provision::App.new(config, ssh_url) }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
allow(app).to receive(:provision_server).and_return(provision_server)
|
|
13
|
+
allow(app).to receive(:print)
|
|
14
|
+
allow(app).to receive(:puts)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#call" do
|
|
18
|
+
it "runs bin/setup on the server" do
|
|
19
|
+
expect(provision_server).to receive(:run!).with("bin/setup")
|
|
20
|
+
|
|
21
|
+
app.call
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "prints status messages" do
|
|
25
|
+
allow(provision_server).to receive(:run!)
|
|
26
|
+
|
|
27
|
+
expect(app).to receive(:print).with("App:")
|
|
28
|
+
expect(app).to receive(:puts).with(" ✓")
|
|
29
|
+
|
|
30
|
+
app.call
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/apt"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::Apt do
|
|
6
|
+
let(:config) { { production: double("production") } }
|
|
7
|
+
let(:ssh_url) { "user@example.com" }
|
|
8
|
+
let(:provision_server) { double("provision_server") }
|
|
9
|
+
let(:apt) { Bard::Provision::Apt.new(config, ssh_url) }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
allow(apt).to receive(:provision_server).and_return(provision_server)
|
|
13
|
+
allow(apt).to receive(:print)
|
|
14
|
+
allow(apt).to receive(:puts)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#call" do
|
|
18
|
+
it "updates and installs packages on the server" do
|
|
19
|
+
expected_commands = [
|
|
20
|
+
%(echo "\\$nrconf{restart} = \\"a\\";" | sudo tee /etc/needrestart/conf.d/90-autorestart.conf),
|
|
21
|
+
"sudo apt-get update -y",
|
|
22
|
+
"sudo apt-get upgrade -y",
|
|
23
|
+
"sudo apt-get install -y curl build-essential libsodium-dev"
|
|
24
|
+
].join("; ")
|
|
25
|
+
|
|
26
|
+
expect(provision_server).to receive(:run!).with(expected_commands, home: true)
|
|
27
|
+
|
|
28
|
+
apt.call
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "prints status messages" do
|
|
32
|
+
allow(provision_server).to receive(:run!)
|
|
33
|
+
expect(apt).to receive(:print).with("Apt:")
|
|
34
|
+
expect(apt).to receive(:puts).with(" ✓")
|
|
35
|
+
|
|
36
|
+
apt.call
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/authorizedkeys"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::AuthorizedKeys do
|
|
6
|
+
let(:config) { { production: double("production") } }
|
|
7
|
+
let(:ssh_url) { "user@example.com" }
|
|
8
|
+
let(:provision_server) { double("provision_server") }
|
|
9
|
+
let(:authorized_keys) { Bard::Provision::AuthorizedKeys.new(config, ssh_url) }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
allow(authorized_keys).to receive(:provision_server).and_return(provision_server)
|
|
13
|
+
allow(authorized_keys).to receive(:print)
|
|
14
|
+
allow(authorized_keys).to receive(:puts)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#call" do
|
|
18
|
+
it "adds authorized keys to the server" do
|
|
19
|
+
expect(provision_server).to receive(:run!).at_least(:once).with(/grep -F -q/, home: true)
|
|
20
|
+
|
|
21
|
+
authorized_keys.call
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "prints status messages" do
|
|
25
|
+
allow(provision_server).to receive(:run!)
|
|
26
|
+
expect(authorized_keys).to receive(:print).with("Authorized Keys:")
|
|
27
|
+
expect(authorized_keys).to receive(:puts).with(" ✓")
|
|
28
|
+
|
|
29
|
+
authorized_keys.call
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "KEYS constant" do
|
|
34
|
+
it "should have predefined SSH keys" do
|
|
35
|
+
expect(Bard::Provision::AuthorizedKeys::KEYS).to be_a(Hash)
|
|
36
|
+
expect(Bard::Provision::AuthorizedKeys::KEYS).not_to be_empty
|
|
37
|
+
expect(Bard::Provision::AuthorizedKeys::KEYS.keys.first).to match(/@/)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
|
|
4
|
+
describe Bard::Provision do
|
|
5
|
+
let(:config) { { production: double("production", key: :production) } }
|
|
6
|
+
let(:ssh_url) { "user@example.com" }
|
|
7
|
+
let(:provision) { Bard::Provision.new(config, ssh_url) }
|
|
8
|
+
|
|
9
|
+
describe ".call" do
|
|
10
|
+
it "creates a new instance and calls it" do
|
|
11
|
+
expect_any_instance_of(Bard::Provision).to receive(:call)
|
|
12
|
+
Bard::Provision.call(config, ssh_url)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "#target" do
|
|
17
|
+
it "returns the production target from config" do
|
|
18
|
+
expect(provision.send(:target)).to eq(config[:production])
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "#provision_server" do
|
|
23
|
+
it "returns a target with the provision ssh_url" do
|
|
24
|
+
target = config[:production]
|
|
25
|
+
allow(target).to receive(:ssh).and_return(nil)
|
|
26
|
+
duped = double("duped_target")
|
|
27
|
+
allow(target).to receive(:dup).and_return(duped)
|
|
28
|
+
allow(duped).to receive(:ssh)
|
|
29
|
+
|
|
30
|
+
result = provision.send(:provision_server)
|
|
31
|
+
expect(result).to eq(duped)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/data"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::Data do
|
|
6
|
+
let(:target) { double("target", key: :production) }
|
|
7
|
+
let(:config) { double("config", data: ["uploads", "assets"]) }
|
|
8
|
+
let(:ssh_url) { "user@example.com" }
|
|
9
|
+
let(:provision_server) { double("provision_server") }
|
|
10
|
+
let(:data_provisioner) { Bard::Provision::Data.new(config, ssh_url) }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
allow(data_provisioner).to receive(:target).and_return(target)
|
|
14
|
+
allow(data_provisioner).to receive(:config).and_return(config)
|
|
15
|
+
allow(data_provisioner).to receive(:provision_server).and_return(provision_server)
|
|
16
|
+
allow(data_provisioner).to receive(:print)
|
|
17
|
+
allow(data_provisioner).to receive(:puts)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "#call" do
|
|
21
|
+
it "dumps, transfers, and loads database data" do
|
|
22
|
+
expect(target).to receive(:run!).with("bin/rake db:dump")
|
|
23
|
+
expect(target).to receive(:copy_file).with("db/data.sql.gz", to: provision_server, verbose: false)
|
|
24
|
+
expect(provision_server).to receive(:run!).with("bin/rake db:load")
|
|
25
|
+
|
|
26
|
+
allow(target).to receive(:copy_dir)
|
|
27
|
+
|
|
28
|
+
data_provisioner.call
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "synchronizes configured data directories" do
|
|
32
|
+
allow(target).to receive(:run!)
|
|
33
|
+
allow(target).to receive(:copy_file)
|
|
34
|
+
allow(provision_server).to receive(:run!)
|
|
35
|
+
|
|
36
|
+
expect(target).to receive(:copy_dir).with("uploads", to: provision_server, verbose: false)
|
|
37
|
+
expect(target).to receive(:copy_dir).with("assets", to: provision_server, verbose: false)
|
|
38
|
+
|
|
39
|
+
data_provisioner.call
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "prints status messages" do
|
|
43
|
+
allow(target).to receive(:run!)
|
|
44
|
+
allow(target).to receive(:copy_file)
|
|
45
|
+
allow(target).to receive(:copy_dir)
|
|
46
|
+
allow(provision_server).to receive(:run!)
|
|
47
|
+
|
|
48
|
+
expect(data_provisioner).to receive(:print).with("Data:")
|
|
49
|
+
expect(data_provisioner).to receive(:puts).with(" ✓")
|
|
50
|
+
|
|
51
|
+
data_provisioner.call
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/deploy"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::Deploy do
|
|
6
|
+
let(:config) { { production: double("production") } }
|
|
7
|
+
let(:ssh_url) { "user@example.com" }
|
|
8
|
+
let(:provision_server) { double("provision_server") }
|
|
9
|
+
let(:deploy) { Bard::Provision::Deploy.new(config, ssh_url) }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
allow(deploy).to receive(:provision_server).and_return(provision_server)
|
|
13
|
+
allow(deploy).to receive(:print)
|
|
14
|
+
allow(deploy).to receive(:puts)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#call" do
|
|
18
|
+
it "runs bin/setup on the server" do
|
|
19
|
+
expect(provision_server).to receive(:run!).with("bin/setup")
|
|
20
|
+
|
|
21
|
+
deploy.call
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "prints status messages" do
|
|
25
|
+
allow(provision_server).to receive(:run!)
|
|
26
|
+
|
|
27
|
+
expect(deploy).to receive(:print).with("Deploy:")
|
|
28
|
+
expect(deploy).to receive(:puts).with(" ✓")
|
|
29
|
+
|
|
30
|
+
deploy.call
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/http"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::HTTP do
|
|
6
|
+
let(:target) { double("target", url: "https://example.com") }
|
|
7
|
+
let(:config) { { production: target } }
|
|
8
|
+
let(:ssh_url) { "user@example.com" }
|
|
9
|
+
let(:provision_server) { double("provision_server") }
|
|
10
|
+
let(:http) { Bard::Provision::HTTP.new(config, ssh_url) }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
allow(http).to receive(:target).and_return(target)
|
|
14
|
+
allow(http).to receive(:provision_server).and_return(provision_server)
|
|
15
|
+
allow(provision_server).to receive_message_chain(:ssh_uri, :host).and_return("192.168.1.100")
|
|
16
|
+
allow(http).to receive(:print)
|
|
17
|
+
allow(http).to receive(:puts)
|
|
18
|
+
allow(http).to receive(:system)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe "#call" do
|
|
22
|
+
context "when HTTP test passes" do
|
|
23
|
+
it "shows success message" do
|
|
24
|
+
allow(http).to receive(:system).and_return(true)
|
|
25
|
+
|
|
26
|
+
expect(http).to receive(:puts).with(" ✓")
|
|
27
|
+
|
|
28
|
+
http.call
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "when HTTP test fails" do
|
|
33
|
+
it "shows failure message" do
|
|
34
|
+
allow(http).to receive(:system).and_return(false)
|
|
35
|
+
|
|
36
|
+
expect(http).to receive(:puts).with(" !!! not serving a rails app from 192.168.1.100")
|
|
37
|
+
|
|
38
|
+
http.call
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "prints status header" do
|
|
43
|
+
allow(http).to receive(:system).and_return(true)
|
|
44
|
+
|
|
45
|
+
expect(http).to receive(:print).with("HTTP:")
|
|
46
|
+
|
|
47
|
+
http.call
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "tests the correct URL" do
|
|
51
|
+
expected_command = /curl -sf --resolve example\.com:80:192\.168\.1\.100 http:\/\/example\.com -o \/dev\/null/
|
|
52
|
+
expect(http).to receive(:system).with(expected_command)
|
|
53
|
+
|
|
54
|
+
http.call
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/logrotation"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::LogRotation do
|
|
6
|
+
let(:target) { double("target", project_name: "test_app") }
|
|
7
|
+
let(:config) { double("config", project_name: "test_app", :[] => target) }
|
|
8
|
+
let(:ssh_url) { "user@example.com" }
|
|
9
|
+
let(:provision_server) { double("provision_server") }
|
|
10
|
+
let(:logrotation) { Bard::Provision::LogRotation.new(config, ssh_url) }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
allow(logrotation).to receive(:target).and_return(target)
|
|
14
|
+
allow(logrotation).to receive(:provision_server).and_return(provision_server)
|
|
15
|
+
allow(logrotation).to receive(:print)
|
|
16
|
+
allow(logrotation).to receive(:puts)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#call" do
|
|
20
|
+
it "sets up log rotation config on the target" do
|
|
21
|
+
expect(provision_server).to receive(:run!).with(/file=\/etc\/logrotate\.d\/test_app/, quiet: true)
|
|
22
|
+
|
|
23
|
+
logrotation.call
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "prints status messages" do
|
|
27
|
+
allow(provision_server).to receive(:run!)
|
|
28
|
+
expect(logrotation).to receive(:print).with("Log Rotation:")
|
|
29
|
+
expect(logrotation).to receive(:puts).with(" ✓")
|
|
30
|
+
|
|
31
|
+
logrotation.call
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/masterkey"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::MasterKey do
|
|
6
|
+
let(:local) { double("local") }
|
|
7
|
+
let(:config) { { production: double("production"), local: local } }
|
|
8
|
+
let(:ssh_url) { "user@example.com" }
|
|
9
|
+
let(:provision_server) { double("provision_server") }
|
|
10
|
+
let(:master_key) { Bard::Provision::MasterKey.new(config, ssh_url) }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
allow(master_key).to receive(:provision_server).and_return(provision_server)
|
|
14
|
+
allow(master_key).to receive(:print)
|
|
15
|
+
allow(master_key).to receive(:puts)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#call" do
|
|
19
|
+
context "when master.key exists locally" do
|
|
20
|
+
before do
|
|
21
|
+
allow(File).to receive(:exist?).with("config/master.key").and_return(true)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "uploads master.key if not present on server" do
|
|
25
|
+
allow(provision_server).to receive(:run).with("[ -f config/master.key ]", quiet: true).and_return(false)
|
|
26
|
+
|
|
27
|
+
expect(Bard::Copy).to receive(:file).with("config/master.key", from: local, to: provision_server)
|
|
28
|
+
|
|
29
|
+
master_key.call
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "skips upload if master.key already exists on server" do
|
|
33
|
+
allow(provision_server).to receive(:run).with("[ -f config/master.key ]", quiet: true).and_return(true)
|
|
34
|
+
|
|
35
|
+
expect(Bard::Copy).not_to receive(:file)
|
|
36
|
+
|
|
37
|
+
master_key.call
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context "when master.key doesn't exist locally" do
|
|
42
|
+
before do
|
|
43
|
+
allow(File).to receive(:exist?).with("config/master.key").and_return(false)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "skips the upload" do
|
|
47
|
+
expect(Bard::Copy).not_to receive(:file)
|
|
48
|
+
|
|
49
|
+
master_key.call
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "prints status messages" do
|
|
54
|
+
allow(File).to receive(:exist?).and_return(false)
|
|
55
|
+
|
|
56
|
+
expect(master_key).to receive(:print).with("Master Key:")
|
|
57
|
+
expect(master_key).to receive(:puts).with(" ✓")
|
|
58
|
+
|
|
59
|
+
master_key.call
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "bard/new/provision/base"
|
|
3
|
+
require "bard/new/provision/mysql"
|
|
4
|
+
|
|
5
|
+
describe Bard::Provision::MySQL do
|
|
6
|
+
let(:config) { { production: double("production") } }
|
|
7
|
+
let(:ssh_url) { "user@example.com" }
|
|
8
|
+
let(:provision_server) { double("provision_server") }
|
|
9
|
+
let(:mysql) { Bard::Provision::MySQL.new(config, ssh_url) }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
allow(mysql).to receive(:provision_server).and_return(provision_server)
|
|
13
|
+
allow(mysql).to receive(:print)
|
|
14
|
+
allow(mysql).to receive(:puts)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#call" do
|
|
18
|
+
context "when MySQL is not responding" do
|
|
19
|
+
it "installs MySQL" do
|
|
20
|
+
allow(mysql).to receive(:mysql_responding?).and_return(false)
|
|
21
|
+
|
|
22
|
+
expect(provision_server).to receive(:run!).with(/DEBIAN_FRONTEND=noninteractive.*apt-get install -y mysql-server/, home: true)
|
|
23
|
+
|
|
24
|
+
mysql.call
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "when MySQL is already responding" do
|
|
29
|
+
it "skips installation" do
|
|
30
|
+
allow(mysql).to receive(:mysql_responding?).and_return(true)
|
|
31
|
+
|
|
32
|
+
expect(provision_server).not_to receive(:run!)
|
|
33
|
+
|
|
34
|
+
mysql.call
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "prints status messages" do
|
|
39
|
+
allow(mysql).to receive(:mysql_responding?).and_return(true)
|
|
40
|
+
|
|
41
|
+
expect(mysql).to receive(:print).with("MySQL:")
|
|
42
|
+
expect(mysql).to receive(:puts).with(" ✓")
|
|
43
|
+
|
|
44
|
+
mysql.call
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#mysql_responding?" do
|
|
49
|
+
it "checks if MySQL service is active" do
|
|
50
|
+
expect(provision_server).to receive(:run).with("sudo systemctl is-active --quiet mysql", home: true, quiet: true)
|
|
51
|
+
|
|
52
|
+
mysql.mysql_responding?
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|