pennyworth-tool 0.0.1
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/.gitignore +8 -0
- data/.hound.yml +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/CONTRIBUTING.md +67 -0
- data/COPYING +674 -0
- data/Gemfile +28 -0
- data/README.md +339 -0
- data/Rakefile +33 -0
- data/bin/pennyworth +26 -0
- data/config/setup.yml +17 -0
- data/examples/README.md +23 -0
- data/examples/kiwi/definitions/base_opensuse13.1_kvm/config.sh +87 -0
- data/examples/kiwi/definitions/base_opensuse13.1_kvm/config.xml +64 -0
- data/examples/kiwi/definitions/base_opensuse13.1_kvm/root/etc/sysconfig/network/ifcfg-eth0 +2 -0
- data/examples/kiwi/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/examples/vagrant/Vagrantfile +14 -0
- data/files/99-libvirt.rules +2 -0
- data/files/image_test-template.xml +43 -0
- data/files/pool-default.xml +6 -0
- data/lib/image_runner.rb +89 -0
- data/lib/pennyworth.rb +65 -0
- data/lib/pennyworth/cli.rb +339 -0
- data/lib/pennyworth/cli_host_controller.rb +107 -0
- data/lib/pennyworth/commands/base_command.rb +96 -0
- data/lib/pennyworth/commands/boot_command.rb +29 -0
- data/lib/pennyworth/commands/build_base_command.rb +103 -0
- data/lib/pennyworth/commands/command.rb +43 -0
- data/lib/pennyworth/commands/down_command.rb +25 -0
- data/lib/pennyworth/commands/import_base_command.rb +112 -0
- data/lib/pennyworth/commands/import_ssh_keys_command.rb +27 -0
- data/lib/pennyworth/commands/list_command.rb +41 -0
- data/lib/pennyworth/commands/setup_command.rb +209 -0
- data/lib/pennyworth/commands/shutdown_command.rb +28 -0
- data/lib/pennyworth/commands/status_command.rb +26 -0
- data/lib/pennyworth/commands/up_command.rb +27 -0
- data/lib/pennyworth/exceptions.rb +39 -0
- data/lib/pennyworth/helper.rb +39 -0
- data/lib/pennyworth/host_config.rb +86 -0
- data/lib/pennyworth/host_runner.rb +133 -0
- data/lib/pennyworth/image_runner.rb +89 -0
- data/lib/pennyworth/libvirt.rb +93 -0
- data/lib/pennyworth/local_command_runner.rb +77 -0
- data/lib/pennyworth/local_runner.rb +34 -0
- data/lib/pennyworth/lock_service.rb +87 -0
- data/lib/pennyworth/remote_command_runner.rb +144 -0
- data/lib/pennyworth/runner.rb +27 -0
- data/lib/pennyworth/settings.rb +42 -0
- data/lib/pennyworth/spec.rb +96 -0
- data/lib/pennyworth/spec_profiler.rb +85 -0
- data/lib/pennyworth/ssh_keys_importer.rb +107 -0
- data/lib/pennyworth/urls.rb +28 -0
- data/lib/pennyworth/vagrant.rb +81 -0
- data/lib/pennyworth/vagrant_command.rb +120 -0
- data/lib/pennyworth/vagrant_runner.rb +44 -0
- data/lib/pennyworth/version.rb +22 -0
- data/lib/pennyworth/vm.rb +62 -0
- data/man/.gitignore +2 -0
- data/man/pennyworth.1.md +28 -0
- data/pennyworth.gemspec +57 -0
- data/prophet/Gemfile +3 -0
- data/prophet/prophet.rb +82 -0
- data/spec/base_command_spec.rb +30 -0
- data/spec/build_base_command_spec.rb +147 -0
- data/spec/cli_host_controller_spec.rb +113 -0
- data/spec/data/hosts.yaml +10 -0
- data/spec/data/kiwi/base_opensuse12.3_kvm.box +1 -0
- data/spec/data/kiwi/base_opensuse13.1_kvm.box +1 -0
- data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/config.sh +1 -0
- data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/config.xml +1 -0
- data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/config.sh +1 -0
- data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/config.xml +1 -0
- data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/spec/data/kiwi2/box_state.yaml +14 -0
- data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/config.sh +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/config.xml +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/config.sh +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/config.xml +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/spec/data/kiwi3/box_state.yaml +13 -0
- data/spec/data/kiwi3/definitions/base_opensuse12.3_kvm/.gitkeep +0 -0
- data/spec/data/kiwi3/definitions/base_opensuse13.1_kvm/.gitkeep +0 -0
- data/spec/data/kiwi3/import_state.yaml +3 -0
- data/spec/data/kiwi4/definitions/base_opensuse12.3_kvm/.gitkeep +0 -0
- data/spec/data/kiwi4/definitions/base_opensuse13.1_kvm/.gitkeep +0 -0
- data/spec/data/kiwi4/import_state.yaml +3 -0
- data/spec/data/kiwi5/import_state.yaml +3 -0
- data/spec/data/vagrant/.gitkeep +0 -0
- data/spec/host_config_spec.rb +197 -0
- data/spec/host_runner_spec.rb +112 -0
- data/spec/image_runner_spec.rb +62 -0
- data/spec/import_base_command_spec.rb +189 -0
- data/spec/local_command_runner_spec.rb +117 -0
- data/spec/local_runner_spec.rb +42 -0
- data/spec/lock_service_spec.rb +95 -0
- data/spec/remote_command_runner_spec.rb +115 -0
- data/spec/settings_spec.rb +26 -0
- data/spec/setup_command_spec.rb +49 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/spec_profiler_spec.rb +63 -0
- data/spec/spec_spec.rb +99 -0
- data/spec/support/command_runner_examples.rb +29 -0
- data/spec/support/runner_examples.rb +34 -0
- data/spec/urls_spec.rb +46 -0
- data/spec/vagrant_command_spec.rb +51 -0
- data/spec/vagrant_runner_spec.rb +40 -0
- data/spec/vagrant_spec.rb +288 -0
- data/spec/vm_spec.rb +56 -0
- metadata +257 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
|
2
|
+
#
|
|
3
|
+
# This program is free software; you can redistribute it and/or
|
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
|
5
|
+
# published by the Free Software Foundation.
|
|
6
|
+
#
|
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
# GNU General Public License for more details.
|
|
11
|
+
#
|
|
12
|
+
# You should have received a copy of the GNU General Public License
|
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
|
14
|
+
#
|
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
|
16
|
+
# you may find current contact information at www.suse.com
|
|
17
|
+
|
|
18
|
+
require "spec_helper.rb"
|
|
19
|
+
|
|
20
|
+
describe Pennyworth::ImportBaseCommand do
|
|
21
|
+
|
|
22
|
+
before(:all) do
|
|
23
|
+
Pennyworth::Cli.settings = Pennyworth::Settings.new
|
|
24
|
+
Pennyworth::Cli.settings.definitions_dir = test_data_dir
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
before(:each) do
|
|
28
|
+
stub_request(:get, /example.com.*import_state.yaml/).
|
|
29
|
+
with(headers: {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
30
|
+
to_return(status: 200, body: File.read(File.join(test_data_dir,
|
|
31
|
+
"/kiwi5/import_state.yaml")), headers: {})
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "without box state file" do
|
|
35
|
+
before(:each) do
|
|
36
|
+
@kiwi_dir = File.join(test_data_dir, "kiwi")
|
|
37
|
+
@cmd = Pennyworth::ImportBaseCommand.new(@kiwi_dir, "http://example.com/pennyworth/")
|
|
38
|
+
allow(Pennyworth::Libvirt).to receive(:ensure_libvirt_env_started)
|
|
39
|
+
allow(@cmd).to receive(:log)
|
|
40
|
+
allow(@cmd).to receive(:write_import_state_file) # Don't write state
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "imports a local box" do
|
|
44
|
+
expect(@cmd).to receive(:base_image_clean).with("base_opensuse12.3_kvm")
|
|
45
|
+
expect_any_instance_of(Pennyworth::Vagrant).to receive(:run).with("box", "add",
|
|
46
|
+
"base_opensuse12.3_kvm", "#{@kiwi_dir}/base_opensuse12.3_kvm.box",
|
|
47
|
+
"--force")
|
|
48
|
+
|
|
49
|
+
@cmd.execute("base_opensuse12.3_kvm", :local => true)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "imports a remote box" do
|
|
53
|
+
allow(@cmd).to receive(:fetch_remote_box_state_file)
|
|
54
|
+
|
|
55
|
+
expect(@cmd).to receive(:base_image_clean).with("base_opensuse13.1_kvm")
|
|
56
|
+
expect_any_instance_of(Pennyworth::Vagrant).to receive(:run).with("box", "add",
|
|
57
|
+
"base_opensuse13.1_kvm",
|
|
58
|
+
"http://example.com/pennyworth/base_opensuse13.1_kvm.box", "--force")
|
|
59
|
+
|
|
60
|
+
@cmd.execute("base_opensuse13.1_kvm")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "url checks" do
|
|
64
|
+
before(:each) do
|
|
65
|
+
@box_state_get = stub_request(:get, /example.com\/pennyworth\/box_state.yaml/)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "fetches the box state file from an url with a trailing slash" do
|
|
69
|
+
cmd = Pennyworth::ImportBaseCommand.new(@kiwi_dir, "http://example.com/pennyworth/")
|
|
70
|
+
cmd.read_remote_box_state_file()
|
|
71
|
+
|
|
72
|
+
assert_requested(@box_state_get)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "fetches the box state file from an url without a trailing slash" do
|
|
76
|
+
cmd = Pennyworth::ImportBaseCommand.new(@kiwi_dir, "http://example.com/pennyworth")
|
|
77
|
+
cmd.read_remote_box_state_file()
|
|
78
|
+
|
|
79
|
+
assert_requested(@box_state_get)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context "with box state file" do
|
|
85
|
+
before(:each) do
|
|
86
|
+
@kiwi_dir = File.join(test_data_dir, "kiwi2")
|
|
87
|
+
@cmd = Pennyworth::ImportBaseCommand.new(@kiwi_dir)
|
|
88
|
+
allow(Pennyworth::Libvirt).to receive(:ensure_libvirt_env_started)
|
|
89
|
+
allow(@cmd).to receive(:log)
|
|
90
|
+
allow(@cmd).to receive(:fetch_remote_box_state_file).and_return(
|
|
91
|
+
File.read(File.join(@kiwi_dir, "box_state.yaml")))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "writes import state file" do
|
|
95
|
+
allow(@cmd).to receive(:base_image_clean)
|
|
96
|
+
allow(@cmd).to receive(:vagrant)
|
|
97
|
+
allow_any_instance_of(Pennyworth::Vagrant).to receive(:run)
|
|
98
|
+
|
|
99
|
+
import_state_file = File.join(@kiwi_dir, "import_state.yaml")
|
|
100
|
+
|
|
101
|
+
FileUtils.rm(import_state_file) if File.exist?(import_state_file)
|
|
102
|
+
|
|
103
|
+
@cmd.execute("base_opensuse13.1_kvm", :local => true)
|
|
104
|
+
@cmd.execute("base_opensuse12.3_kvm", :local => true)
|
|
105
|
+
|
|
106
|
+
expected_content = <<-EOT
|
|
107
|
+
---
|
|
108
|
+
base_opensuse13.1_kvm: 115469c104dcc69455f321eb086ffb11
|
|
109
|
+
base_opensuse12.3_kvm: e4e743b5340686d8488dbce54b5644d8
|
|
110
|
+
EOT
|
|
111
|
+
|
|
112
|
+
expect(File.read(import_state_file)).to eq expected_content
|
|
113
|
+
|
|
114
|
+
FileUtils.rm(import_state_file) if File.exist?(import_state_file)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "reads remote box state file" do
|
|
118
|
+
box_state = @cmd.read_remote_box_state_file
|
|
119
|
+
|
|
120
|
+
expect(box_state["base_opensuse12.3_kvm"]["sources"]["config.sh"]).to eq(
|
|
121
|
+
"c6640ba00ab345b7491b836d517a637b")
|
|
122
|
+
expect(box_state["base_opensuse13.1_kvm"]["target"]).to eq(
|
|
123
|
+
"115469c104dcc69455f321eb086ffb11")
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context "with box and import state files" do
|
|
128
|
+
before(:each) do
|
|
129
|
+
@kiwi_dir = File.join(test_data_dir, "kiwi3")
|
|
130
|
+
@cmd = Pennyworth::ImportBaseCommand.new(@kiwi_dir, "http://example.com/pennyworth/")
|
|
131
|
+
allow(Pennyworth::Libvirt).to receive(:ensure_libvirt_env_started)
|
|
132
|
+
allow(@cmd).to receive(:log)
|
|
133
|
+
allow(@cmd).to receive(:write_import_state_file) # Don't write state
|
|
134
|
+
allow(@cmd).to receive(:fetch_remote_box_state_file).and_return(
|
|
135
|
+
File.read(File.join(@kiwi_dir, "box_state.yaml")))
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "imports changed local box" do
|
|
139
|
+
expect(@cmd).to receive(:base_image_clean)
|
|
140
|
+
expect_any_instance_of(Pennyworth::Vagrant).to receive(:run)
|
|
141
|
+
|
|
142
|
+
@cmd.execute("base_opensuse12.3_kvm", :local => true)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "doesn't import unchanged local box" do
|
|
146
|
+
expect(@cmd).to_not receive(:base_image_clean)
|
|
147
|
+
expect_any_instance_of(Pennyworth::Vagrant).to_not receive(:run)
|
|
148
|
+
|
|
149
|
+
@cmd.execute("base_opensuse13.1_kvm", :local => true)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "imports changed remote box" do
|
|
153
|
+
expect(@cmd).to receive(:base_image_clean)
|
|
154
|
+
expect_any_instance_of(Pennyworth::Vagrant).to receive(:run)
|
|
155
|
+
|
|
156
|
+
@cmd.execute("base_opensuse13.2_kvm")
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "doesn't import unchanged remote box" do
|
|
160
|
+
expect(@cmd).to_not receive(:base_image_clean)
|
|
161
|
+
expect_any_instance_of(Pennyworth::Vagrant).to_not receive(:run)
|
|
162
|
+
|
|
163
|
+
@cmd.execute("base_opensuse13.1_kvm")
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
context "without box state, but with import state files" do
|
|
168
|
+
before(:each) do
|
|
169
|
+
@kiwi_dir = File.join(test_data_dir, "kiwi4")
|
|
170
|
+
@cmd = Pennyworth::ImportBaseCommand.new(@kiwi_dir)
|
|
171
|
+
allow(Pennyworth::Libvirt).to receive(:ensure_libvirt_env_started)
|
|
172
|
+
allow(@cmd).to receive(:log)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "removes imported state after import" do
|
|
176
|
+
expect(@cmd).to receive(:base_image_clean)
|
|
177
|
+
expect_any_instance_of(Pennyworth::Vagrant).to receive(:run)
|
|
178
|
+
|
|
179
|
+
import_state = @cmd.read_import_state_file
|
|
180
|
+
expect(import_state["base_opensuse13.1_kvm"]).to eq "115469c104dcc69455f321eb086ffb11"
|
|
181
|
+
|
|
182
|
+
expect(@cmd).to receive(:write_import_state_file).with(
|
|
183
|
+
{"base_opensuse13.1_kvm"=>nil, "base_opensuse12.3_kvm"=>"old_hash"}
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
@cmd.execute("base_opensuse13.1_kvm", :local => true)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
|
2
|
+
#
|
|
3
|
+
# This program is free software; you can redistribute it and/or
|
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
|
5
|
+
# published by the Free Software Foundation.
|
|
6
|
+
#
|
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
# GNU General Public License for more details.
|
|
11
|
+
#
|
|
12
|
+
# You should have received a copy of the GNU General Public License
|
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
|
14
|
+
#
|
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
|
16
|
+
# you may find current contact information at www.suse.com
|
|
17
|
+
|
|
18
|
+
require "spec_helper"
|
|
19
|
+
|
|
20
|
+
include GivenFilesystemSpecHelpers
|
|
21
|
+
|
|
22
|
+
describe Pennyworth::LocalCommandRunner do
|
|
23
|
+
use_given_filesystem
|
|
24
|
+
let(:command_runner) { Pennyworth::LocalCommandRunner.new }
|
|
25
|
+
|
|
26
|
+
it_behaves_like "a command runner"
|
|
27
|
+
|
|
28
|
+
describe "#run" do
|
|
29
|
+
it "executes commands via Cheetah" do
|
|
30
|
+
expect(Cheetah).to receive(:run).with("bash", "-c", "foo bar", stdout: :capture)
|
|
31
|
+
|
|
32
|
+
command_runner.run("foo bar", stdout: :capture)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "prepends the env variable to the command" do
|
|
36
|
+
runner = Pennyworth::LocalCommandRunner.new(
|
|
37
|
+
env: {
|
|
38
|
+
"MACHINERY_DIR" => "/tmp"
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
expect(runner).to receive(:with_env).with("MACHINERY_DIR" => "/tmp").and_call_original
|
|
42
|
+
expect(Cheetah).to receive(:run).with("bash", "-c", "foo bar", stdout: :capture)
|
|
43
|
+
|
|
44
|
+
runner.run("foo bar", stdout: :capture)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#extract_file" do
|
|
49
|
+
before(:each) do
|
|
50
|
+
@source_file = given_dummy_file "example.file"
|
|
51
|
+
@target = given_directory
|
|
52
|
+
@expected_file = File.join(@target, "example.file")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "extracts the file" do
|
|
56
|
+
command_runner.extract_file(@source_file, @target)
|
|
57
|
+
|
|
58
|
+
expect(File.exists?(File.join(@target, "example.file"))).to be(true)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe "#inject_file" do
|
|
63
|
+
before(:each) do
|
|
64
|
+
@source_file = given_dummy_file "example.file"
|
|
65
|
+
@target = given_directory
|
|
66
|
+
@expected_file = File.join(@target, "example.file")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "injects the file" do
|
|
70
|
+
command_runner.inject_file(@source_file, @target)
|
|
71
|
+
expect(File.exists?(File.join(@target, "example.file"))).to be(true)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "copies the file and sets the owner" do
|
|
75
|
+
expect(FileUtils).to receive(:chown).with("tux", nil, @expected_file)
|
|
76
|
+
|
|
77
|
+
command_runner.inject_file(@source_file, @target, owner: "tux")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "copies the file and sets the group" do
|
|
81
|
+
expect(FileUtils).to receive(:chown).with(nil, "tux", @expected_file)
|
|
82
|
+
|
|
83
|
+
command_runner.inject_file(@source_file, @target, group: "tux")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "copies the file and sets the mode" do
|
|
87
|
+
expect(FileUtils).to receive(:chmod).with("600", @expected_file)
|
|
88
|
+
|
|
89
|
+
command_runner.inject_file(@source_file, @target, mode: "600")
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe "#inject_directory" do
|
|
94
|
+
before(:each) do
|
|
95
|
+
@source_dir = given_directory do
|
|
96
|
+
@source_file = given_dummy_file "example.file"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
@target = given_directory
|
|
100
|
+
@expected_dir = File.join(@target, File.basename(@source_dir))
|
|
101
|
+
@expected_file = File.join(@target, File.basename(@source_dir), "example.file")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "injects the directory" do
|
|
105
|
+
command_runner.inject_directory(@source_dir, @target)
|
|
106
|
+
|
|
107
|
+
expect(Dir.exists?(@expected_dir)).to be(true)
|
|
108
|
+
expect(File.exists?(@expected_file)).to be(true)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "copies the directory and sets the user and group" do
|
|
112
|
+
expect(FileUtils).to receive(:chown_R).with("user", "group", @target)
|
|
113
|
+
|
|
114
|
+
command_runner.inject_directory(@source_dir, @target, owner: "user", group: "group")
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
|
2
|
+
#
|
|
3
|
+
# This program is free software; you can redistribute it and/or
|
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
|
5
|
+
# published by the Free Software Foundation.
|
|
6
|
+
#
|
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
# GNU General Public License for more details.
|
|
11
|
+
#
|
|
12
|
+
# You should have received a copy of the GNU General Public License
|
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
|
14
|
+
#
|
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
|
16
|
+
# you may find current contact information at www.suse.com
|
|
17
|
+
|
|
18
|
+
require "spec_helper"
|
|
19
|
+
|
|
20
|
+
describe Pennyworth::LocalRunner do
|
|
21
|
+
let(:runner) {
|
|
22
|
+
Pennyworth::LocalRunner.new
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
it_behaves_like "a runner"
|
|
26
|
+
|
|
27
|
+
describe "#command_runner" do
|
|
28
|
+
it "returns a LocalCommandRunner" do
|
|
29
|
+
expect(runner.command_runner).to be_a(Pennyworth::LocalCommandRunner)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "forwards the :env and :command_map options to the LocalCommandRunner" do
|
|
33
|
+
opts = {
|
|
34
|
+
env: { "FOO" => "BAR" },
|
|
35
|
+
command_map: { "foo" => "/bar" }
|
|
36
|
+
}
|
|
37
|
+
expect(Pennyworth::LocalCommandRunner).to receive(:new).with(opts)
|
|
38
|
+
|
|
39
|
+
Pennyworth::LocalRunner.new(opts).command_runner
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Copyright (c) 2015 SUSE LLC
|
|
2
|
+
#
|
|
3
|
+
# This program is free software; you can redistribute it and/or
|
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
|
5
|
+
# published by the Free Software Foundation.
|
|
6
|
+
#
|
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
# GNU General Public License for more details.
|
|
11
|
+
#
|
|
12
|
+
# You should have received a copy of the GNU General Public License
|
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
|
14
|
+
#
|
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
|
16
|
+
# you may find current contact information at www.suse.com
|
|
17
|
+
|
|
18
|
+
require "spec_helper"
|
|
19
|
+
|
|
20
|
+
describe Pennyworth::LockService do
|
|
21
|
+
let(:lock_service) { Pennyworth::LockService.new("lock.example.com:9999") }
|
|
22
|
+
|
|
23
|
+
it "creates lock object" do
|
|
24
|
+
expect(lock_service.lock_server_host).to eq("lock.example.com")
|
|
25
|
+
expect(lock_service.lock_server_port).to eq("9999")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "acquires lock" do
|
|
29
|
+
socket = double
|
|
30
|
+
expect(TCPSocket).to receive(:new).and_return(socket)
|
|
31
|
+
expect(socket).to receive(:puts).with("g my_test")
|
|
32
|
+
expect(socket).to receive(:gets).
|
|
33
|
+
and_return("1 Lock Get Success: my_test")
|
|
34
|
+
|
|
35
|
+
expect(lock_service.request_lock("my_test")).to be(true)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "fails to acquire lock" do
|
|
39
|
+
socket = double
|
|
40
|
+
expect(TCPSocket).to receive(:new).and_return(socket)
|
|
41
|
+
expect(socket).to receive(:puts).with("g my_test")
|
|
42
|
+
expect(socket).to receive(:gets).
|
|
43
|
+
and_return("0 Lock Get Failure: my_test")
|
|
44
|
+
|
|
45
|
+
expect(lock_service.request_lock("my_test")).to be(false)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "fails to release non-existing lock" do
|
|
49
|
+
expect {
|
|
50
|
+
lock_service.release_lock("inexisting lock")
|
|
51
|
+
}.to raise_error(Pennyworth::LockError)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "releases lock" do
|
|
55
|
+
socket = double
|
|
56
|
+
expect(TCPSocket).to receive(:new).and_return(socket)
|
|
57
|
+
expect(socket).to receive(:puts).with("g my_test")
|
|
58
|
+
expect(socket).to receive(:gets).
|
|
59
|
+
and_return("1 Lock Get Success: my_test")
|
|
60
|
+
|
|
61
|
+
expect(lock_service.request_lock("my_test")).to be(true)
|
|
62
|
+
|
|
63
|
+
expect(socket).to receive(:close)
|
|
64
|
+
|
|
65
|
+
lock_service.release_lock("my_test")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "returns locked status" do
|
|
69
|
+
socket = double
|
|
70
|
+
expect(TCPSocket).to receive(:new).and_return(socket)
|
|
71
|
+
|
|
72
|
+
expect(socket).to receive(:puts).with("i my_test")
|
|
73
|
+
expect(socket).to receive(:gets).
|
|
74
|
+
and_return("1 Lock Is Locked: my_test")
|
|
75
|
+
|
|
76
|
+
expect(socket).to receive(:puts).with("d my_test")
|
|
77
|
+
expect(socket).to receive(:gets).
|
|
78
|
+
and_return("my_test: 172.16.254.1:49716")
|
|
79
|
+
|
|
80
|
+
expect(lock_service.info("my_test")).
|
|
81
|
+
to eq "'my_test' is locked by 172.16.254.1"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "returns unlocked status" do
|
|
85
|
+
socket = double
|
|
86
|
+
expect(TCPSocket).to receive(:new).and_return(socket)
|
|
87
|
+
|
|
88
|
+
expect(socket).to receive(:puts).with("i my_test")
|
|
89
|
+
expect(socket).to receive(:gets).
|
|
90
|
+
and_return("0 Lock Not Locked: my_test")
|
|
91
|
+
|
|
92
|
+
expect(lock_service.info("my_test")).
|
|
93
|
+
to eq "'my_test' is not locked"
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
|
2
|
+
#
|
|
3
|
+
# This program is free software; you can redistribute it and/or
|
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
|
5
|
+
# published by the Free Software Foundation.
|
|
6
|
+
#
|
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
# GNU General Public License for more details.
|
|
11
|
+
#
|
|
12
|
+
# You should have received a copy of the GNU General Public License
|
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
|
14
|
+
#
|
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
|
16
|
+
# you may find current contact information at www.suse.com
|
|
17
|
+
|
|
18
|
+
require "spec_helper"
|
|
19
|
+
|
|
20
|
+
describe Pennyworth::RemoteCommandRunner do
|
|
21
|
+
let(:ssh_output) { "-rw-r--r-- 1 root root 642 Sep 27 22:06 /etc/hosts" }
|
|
22
|
+
let(:command_runner) { Pennyworth::RemoteCommandRunner.new("1.2.3.4", "root") }
|
|
23
|
+
|
|
24
|
+
it_behaves_like "a command runner"
|
|
25
|
+
|
|
26
|
+
describe "#run" do
|
|
27
|
+
it "calls ssh and returns the command's standard output" do
|
|
28
|
+
expect(Cheetah).to receive(:run).
|
|
29
|
+
and_return(ssh_output)
|
|
30
|
+
|
|
31
|
+
output = command_runner.run("ls", "-l", "/etc/hosts", stdout: :capture)
|
|
32
|
+
|
|
33
|
+
expect(output).to eq (ssh_output)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "executes commands as given user" do
|
|
37
|
+
expect(Cheetah).to receive(:run).
|
|
38
|
+
with(
|
|
39
|
+
"ssh", "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no",
|
|
40
|
+
"root@1.2.3.4", "LC_ALL=C", "su", "-l", "vagrant", "-c", "ls", "-l", "/etc/hosts",
|
|
41
|
+
stdout: :capture).
|
|
42
|
+
and_return(ssh_output)
|
|
43
|
+
|
|
44
|
+
output = command_runner.run("ls", "-l", "/etc/hosts", as: "vagrant", stdout: :capture)
|
|
45
|
+
|
|
46
|
+
expect(output).to eq (ssh_output)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "raises ExecutionFailed in case of errors" do
|
|
50
|
+
expect(Cheetah).to receive(:run).and_raise(Cheetah::ExecutionFailed.new(nil, nil, nil, nil))
|
|
51
|
+
|
|
52
|
+
expect {
|
|
53
|
+
command_runner.run("foo")
|
|
54
|
+
}.to raise_error(Pennyworth::ExecutionFailed)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe "#extract_file" do
|
|
59
|
+
it "calls scp with source and destination as arguments" do
|
|
60
|
+
expect(Cheetah).to receive(:run)
|
|
61
|
+
|
|
62
|
+
command_runner.extract_file("/etc/hosts", "/tmp")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe "#inject_file" do
|
|
67
|
+
it "calls scp with source and destination as arguments" do
|
|
68
|
+
expect(Cheetah).to receive(:run)
|
|
69
|
+
|
|
70
|
+
command_runner.inject_file("/tmp/hosts", "/etc")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "copies the file and sets the owner" do
|
|
74
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args).to include(/scp/) }
|
|
75
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args.join(" ")).to match(/chown.*tux/) }
|
|
76
|
+
|
|
77
|
+
command_runner.inject_file("/tmp/hosts", "/etc", owner: "tux")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "copies the file and sets the group" do
|
|
81
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args).to include(/scp/) }
|
|
82
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args.join(" ")).to match(/chown.*:tux/) }
|
|
83
|
+
|
|
84
|
+
command_runner.inject_file("/tmp/hosts", "/etc", group: "tux")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "copies the file and sets the mode" do
|
|
88
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args).to include(/scp/) }
|
|
89
|
+
expect(command_runner).to receive(:run) do |*args|
|
|
90
|
+
expect(args.join(" ")).to include("chmod 600")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
command_runner.inject_file("/tmp/hosts", "/etc", mode: "600")
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe "#inject_directory" do
|
|
98
|
+
it "calls scp with source and destination as arguments" do
|
|
99
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args).to include(/mkdir -p/) }
|
|
100
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args).to include(/scp/) }
|
|
101
|
+
|
|
102
|
+
command_runner.inject_directory("/tmp/hosts", "/etc")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "copies the directory and sets the user and group" do
|
|
106
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args).to include(/mkdir -p/) }
|
|
107
|
+
expect(Cheetah).to receive(:run) { |*args| expect(args).to include(/scp/) }
|
|
108
|
+
expect(Cheetah).to receive(:run) do |*args|
|
|
109
|
+
expect(args.join(" ")).to include("chown -R user:group")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
command_runner.inject_directory("/tmp/hosts", "/etc", owner: "user", group: "group")
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|