rouster 0.67 → 0.68
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +5 -0
- data/Vagrantfile +5 -10
- data/examples/bootstrap.rb +94 -14
- data/lib/rouster.rb +21 -13
- data/lib/rouster/vagrant.rb +16 -0
- data/test/unit/testing/test_meets_constraint.rb +1 -6
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2922e8289682a6859c9e8425df652eb5af74b93
|
4
|
+
data.tar.gz: 2862b48d598fd179b986458f214232f65ca483cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34ce58498c46e4eccc008177db64cefdfc5e1f4ae66df0e7a34cd1abbac60b2bd12929f6b60e31b418153deb7c9a946c6c955f0d210c6fc3d9851a9dbc319485
|
7
|
+
data.tar.gz: 40599a85f744aea565ce406870890b8ad92620cc7aba21f02e4eb721aa3368d80208c176790e003a650e4e00f7afdb268cf0b167fa22732900bed1ba8e10b85c
|
data/Rakefile
CHANGED
@@ -39,26 +39,31 @@ end
|
|
39
39
|
Rake::TestTask.new(:test => :vdestroy) do |t|
|
40
40
|
t.libs << 'lib'
|
41
41
|
t.test_files = FileList['test/**/test_*.rb']
|
42
|
+
t.verbose = true
|
42
43
|
end
|
43
44
|
|
44
45
|
Rake::TestTask.new do |t|
|
45
46
|
t.name = 'unit'
|
46
47
|
t.libs << 'lib'
|
47
48
|
t.test_files = FileList['test/unit/**/test_*.rb']
|
49
|
+
t.verbose = true
|
48
50
|
end
|
49
51
|
|
50
52
|
Rake::TestTask.new(:functional => :vdestroy) do |t|
|
51
53
|
t.libs << 'lib'
|
52
54
|
t.test_files = FileList['test/functional/**/test_*.rb']
|
55
|
+
t.verbose = true
|
53
56
|
end
|
54
57
|
|
55
58
|
Rake::TestTask.new(:deltas => :vdestroy) do |t|
|
56
59
|
t.libs << 'lib'
|
57
60
|
t.test_files = FileList['test/functional/deltas/test_*.rb']
|
61
|
+
t.verbose = true
|
58
62
|
end
|
59
63
|
|
60
64
|
Rake::TestTask.new do |t|
|
61
65
|
t.name = 'puppet'
|
62
66
|
t.libs << 'lib'
|
63
67
|
t.test_files = FileList['test/puppet/test*.rb']
|
68
|
+
t.verbose = true
|
64
69
|
end
|
data/Vagrantfile
CHANGED
@@ -10,21 +10,16 @@ boxes = {
|
|
10
10
|
:box_url => 'http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210.box',
|
11
11
|
},
|
12
12
|
|
13
|
-
:ubuntu12
|
14
|
-
|
15
|
-
|
13
|
+
:ubuntu12 => {
|
14
|
+
:box_name => 'ubuntu12',
|
15
|
+
:box_url => 'http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210.box',
|
16
16
|
},
|
17
17
|
|
18
|
-
:ubuntu13
|
18
|
+
:ubuntu13 => {
|
19
19
|
:box_name => 'ubuntu13',
|
20
20
|
:box_url => 'http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-1310-x64-virtualbox-puppet.box',
|
21
21
|
},
|
22
22
|
|
23
|
-
:centos7 => {
|
24
|
-
:box_name => 'centos7b',
|
25
|
-
:box_url => 'https://atlas.hashicorp.com/centos/boxes/7/versions/1610.01/providers/virtualbox.box',
|
26
|
-
},
|
27
|
-
|
28
23
|
}
|
29
24
|
|
30
25
|
Vagrant::Config.run do |config|
|
@@ -33,7 +28,7 @@ Vagrant::Config.run do |config|
|
|
33
28
|
|
34
29
|
worker.vm.box = hash[:box_name]
|
35
30
|
worker.vm.box_url = hash[:box_url]
|
36
|
-
worker.vm.host_name = hash[:
|
31
|
+
worker.vm.host_name = hash[:box_name]
|
37
32
|
worker.vm.network :hostonly, sprintf('10.0.1.%s', rand(253).to_i + 2)
|
38
33
|
worker.ssh.forward_agent = true
|
39
34
|
|
data/examples/bootstrap.rb
CHANGED
@@ -4,30 +4,110 @@ require 'rouster'
|
|
4
4
|
require 'rouster/puppet'
|
5
5
|
require 'rouster/tests'
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
app = Rouster.new(:name => 'app', :verbosity => 4, :sudo => true)
|
8
|
+
ppm = Rouster.new(:name => 'ppm', :verbosity => 1, :sudo => true)
|
9
9
|
|
10
|
-
|
10
|
+
# passthrough boxes do not need to specify a name
|
11
|
+
# commented out currently because passthrough is not MVP
|
12
|
+
#lpt = Rouster.new(:passthrough => 'local', :verbosity => 4)
|
13
|
+
#rpt = Rouster.new(:passthrough => 'remote', :verbosity => 4, :sshkey => '~/.ssh/id_dsa')
|
14
|
+
|
15
|
+
workers = [app]
|
11
16
|
|
12
17
|
workers.each do |w|
|
13
18
|
p '%s config: ' % w.name
|
14
19
|
p w
|
15
20
|
|
16
|
-
p 'uptime: %s' % w.run('uptime')
|
17
|
-
p 'os type: %s' % w.os_type
|
18
|
-
p 'os version: %s' % w.os_version(w.os_type)
|
19
|
-
|
20
21
|
p 'status: %s' % w.status()
|
22
|
+
p 'upping the box'
|
23
|
+
w.up()
|
21
24
|
|
22
|
-
p '
|
23
|
-
p w.
|
25
|
+
p sprintf('%s status: %s', w.name, w.status())
|
26
|
+
p sprintf('%s available via ssh: %s', w.name, w.is_available_via_ssh?())
|
24
27
|
|
25
|
-
p '
|
26
|
-
w.
|
28
|
+
p 'suspending the box'
|
29
|
+
w.suspend()
|
27
30
|
|
28
|
-
p 'status: %s'
|
29
|
-
p '
|
31
|
+
p sprintf('%s status: %s', w.name, w.status())
|
32
|
+
p sprintf('%s available via ssh: %s', w.name, w.is_available_via_ssh?())
|
33
|
+
|
34
|
+
p 'bringing the box back'
|
35
|
+
w.up()
|
36
|
+
|
37
|
+
p sprintf('%s status: %s', w.name, w.status())
|
38
|
+
p sprintf('%s available via ssh: %s', w.name, w.is_available_via_ssh?())
|
39
|
+
|
40
|
+
## expected success
|
41
|
+
p sprintf('is_dir?(/tmp): %s', w.is_dir?('/tmp'))
|
42
|
+
p sprintf('is_exectuable?(/sbin/service: %s', w.is_executable?('/sbin/service'))
|
43
|
+
p sprintf('is_file?(/etc/hosts): %s', w.is_file?('/etc/hosts'))
|
44
|
+
p sprintf('is_group?(root): %s', w.is_group?('root'))
|
45
|
+
p sprintf('is_in_file?(/etc/hosts, puppet): %s', w.is_in_file?('/etc/hosts', 'puppet'))
|
46
|
+
p sprintf('is_in_path?(ping): %s', w.is_in_path?('ping'))
|
47
|
+
p sprintf('is_package?(libpcap): %s', w.is_package?('libpcap'))
|
48
|
+
p sprintf('is_port_open?(9999): %s', w.is_port_open?(9999))
|
49
|
+
p sprintf('is_port_active?(22): %s', w.is_port_active?(22))
|
50
|
+
p sprintf('is_process_running?(sshd): %s', w.is_process_running?('sshd'))
|
51
|
+
p sprintf('is_readable?(/etc/hosts): %s', w.is_readable?('/etc/hosts'))
|
52
|
+
p sprintf('is_service?(iptables): %s', w.is_service?('iptables'))
|
53
|
+
p sprintf('is_service_running?(iptables): %s', w.is_service_running?('iptables'))
|
54
|
+
p sprintf('is_user?(root): %s', w.is_user?('root'))
|
55
|
+
p sprintf('is_writeable?(/etc/hosts): %s', w.is_writeable?('/etc/hosts'))
|
56
|
+
|
57
|
+
## expected failure
|
58
|
+
p sprintf('is_dir?(/dne): %s', w.is_dir?('/dne'))
|
59
|
+
p sprintf('is_executable?(fizzybang): %s', w.is_executable?('fizzybang'))
|
60
|
+
p sprintf('is_file?(/dne/fizzy): %s', w.is_file?('/dne/fizzy'))
|
61
|
+
p sprintf('is_group?(three-amigos): %s', w.is_group?('three-amigos'))
|
62
|
+
p sprintf('is_in_file?(/etc/hosts, this content is not there): %s', w.is_in_file?('/etc/hosts', 'this content is not there'))
|
63
|
+
p sprintf('is_in_file?(/dne/fizzy, this file is not there): %s', w.is_in_file?('/dne/fizzy', 'this file is not there'))
|
64
|
+
p sprintf('is_in_path?(fizzy): %s', w.is_in_path?('fizzy'))
|
65
|
+
p sprintf('is_package?(fizzybang): %s', w.is_package?('fizzybang'))
|
66
|
+
p sprintf('is_port_open?(123, udp): %s', w.is_port_open?(123, 'udp'))
|
67
|
+
p sprintf('is_port_open?(22): %s', w.is_port_open?(22))
|
68
|
+
p sprintf('is_process_running?(fizzy): %s', w.is_process_running?('fizzy'))
|
69
|
+
p sprintf('is_readable?(/dne/fizzy): %s', w.is_readable?('/dne/fizzy'))
|
70
|
+
p sprintf('is_service?(syslogd): %s', w.is_service?('syslogd'))
|
71
|
+
p sprintf('is_service_running?(smartd): %s', w.is_service_running?('smartd'))
|
72
|
+
p sprintf('is_user?(toor): %s', w.is_user?('toor'))
|
73
|
+
#p sprintf('is_writable?(/etc/hosts): %s', w.is_writeable?('/etc/hosts')) # running as sudo, so everything is writeable -- can we test this with a file in a path that DNE?
|
74
|
+
|
75
|
+
# put a file on the box and then bring it back
|
76
|
+
w.put(__FILE__, '/tmp/foobar')
|
77
|
+
w.get('/tmp/foobar', 'foobar_from_piab_host.tmp')
|
78
|
+
|
79
|
+
# output should be the same
|
80
|
+
p sprintf('%s uname -a via run: %s', w.name, w.run('uname -a'))
|
81
|
+
p sprintf('%s uname -a via output: %s', w.name, w.get_output())
|
82
|
+
|
83
|
+
begin
|
84
|
+
p sprintf('%s fizzy: %s', w.name, w.run('fizzy'))
|
85
|
+
rescue => e
|
86
|
+
p e
|
87
|
+
end
|
88
|
+
|
89
|
+
begin
|
90
|
+
p sprintf('%s ls /dne/ %s', w.name, w.run('ls /dne/'))
|
91
|
+
rescue => e
|
92
|
+
p e
|
93
|
+
end
|
94
|
+
|
95
|
+
p sprintf('%s ls /dne/ expected exit code 2: %s', w.name, w.run('ls /dne/', 2))
|
96
|
+
|
97
|
+
# tear the box down
|
98
|
+
p 'destroying the box'
|
99
|
+
w.destroy()
|
100
|
+
|
101
|
+
p sprintf('%s status: %s', w.name, w.status())
|
102
|
+
p sprintf('%s available via ssh: %s', w.name, w.is_available_via_ssh?())
|
103
|
+
|
104
|
+
# bring it back again
|
105
|
+
p 'upping the box again'
|
106
|
+
w.up()
|
107
|
+
|
108
|
+
p sprintf('%s status: %s', w.name, w.status())
|
109
|
+
p sprintf('%s available via ssh: %s', w.name, w.is_available_via_ssh?())
|
30
110
|
|
31
111
|
end
|
32
112
|
|
33
|
-
exit
|
113
|
+
exit
|
data/lib/rouster.rb
CHANGED
@@ -12,7 +12,7 @@ require 'rouster/vagrant'
|
|
12
12
|
class Rouster
|
13
13
|
|
14
14
|
# sporadically updated version number
|
15
|
-
VERSION = 0.
|
15
|
+
VERSION = 0.68
|
16
16
|
|
17
17
|
# custom exceptions -- what else do we want them to include/do?
|
18
18
|
class ArgumentError < StandardError; end # thrown by methods that take parameters from users
|
@@ -41,6 +41,7 @@ class Rouster
|
|
41
41
|
# * [sudo] - boolean of whether or not to prefix commands run in VM with 'sudo', default is true
|
42
42
|
# * [vagrantfile] - the full or relative path to the Vagrantfile to use, if not specified, will look for one in 5 directories above current location
|
43
43
|
# * [vagrant_concurrency] - boolean controlling whether Rouster will attempt to run `vagrant *` if another vagrant process is already running, default is false
|
44
|
+
# * [vagrant_reboot] - particularly sticky systems restart better if Vagrant does it for us, default is false
|
44
45
|
# * [verbosity] - an integer representing console level logging, or an array of integers representing console,file level logging - DEBUG (0) < INFO (1) < WARN (2) < ERROR (3) < FATAL (4)
|
45
46
|
def initialize(opts = nil)
|
46
47
|
@cache_timeout = opts[:cache_timeout].nil? ? false : opts[:cache_timeout]
|
@@ -53,6 +54,7 @@ class Rouster
|
|
53
54
|
@unittest = opts[:unittest].nil? ? false : opts[:unittest]
|
54
55
|
@vagrantfile = opts[:vagrantfile].nil? ? traverse_up(Dir.pwd, 'Vagrantfile', 5) : opts[:vagrantfile]
|
55
56
|
@vagrant_concurrency = opts[:vagrant_concurrency].nil? ? false : opts[:vagrant_concurrency]
|
57
|
+
@vagrant_reboot = opts[:vagrant_reboot].nil? ? false : opts[:vagrant_reboot]
|
56
58
|
|
57
59
|
# TODO kind of want to invert this, 0 = trace, 1 = debug, 2 = info, 3 = warning, 4 = error
|
58
60
|
# could do `fixed_ordering = [4, 3, 2, 1, 0]` and use user input as index instead, so an input of 4 (which should be more verbose), yields 0
|
@@ -653,19 +655,25 @@ class Rouster
|
|
653
655
|
return nil
|
654
656
|
end
|
655
657
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
658
|
+
if @vagrant_reboot
|
659
|
+
# leading vagrant handle this through 'reload --no-provision'
|
660
|
+
self.reload
|
661
|
+
else
|
662
|
+
# trying to do it ourselves
|
663
|
+
case os_type
|
664
|
+
when :osx
|
665
|
+
self.run('shutdown -r now', expected_exitcodes)
|
666
|
+
when :rhel, :ubuntu
|
667
|
+
if os_type.eql?(:rhel) and os_version(os_type).match(/7/)
|
668
|
+
self.run('shutdown --halt --reboot now', expected_exitcodes << 256)
|
669
|
+
else
|
670
|
+
self.run('shutdown -rf now')
|
671
|
+
end
|
672
|
+
when :solaris
|
673
|
+
self.run('shutdown -y -i5 -g0', expected_exitcodes)
|
662
674
|
else
|
663
|
-
|
664
|
-
|
665
|
-
when :solaris
|
666
|
-
self.run('shutdown -y -i5 -g0', expected_exitcodes)
|
667
|
-
else
|
668
|
-
raise InternalError.new(sprintf('unsupported OS[%s]', @ostype))
|
675
|
+
raise InternalError.new(sprintf('unsupported OS[%s]', @ostype))
|
676
|
+
end
|
669
677
|
end
|
670
678
|
|
671
679
|
@ssh, @ssh_info = nil # severing the SSH tunnel, getting ready in case this box is brought back up on a different port
|
data/lib/rouster/vagrant.rb
CHANGED
@@ -159,6 +159,22 @@ class Rouster
|
|
159
159
|
return status
|
160
160
|
end
|
161
161
|
|
162
|
+
##
|
163
|
+
# reload
|
164
|
+
#
|
165
|
+
# runs `vagrant reload <name> [--no-provision]` from the Vagrantfile path
|
166
|
+
# +no_provision+ Boolean whether or not to stop reprovisioning
|
167
|
+
def reload(no_provision = true)
|
168
|
+
|
169
|
+
if self.is_passthrough?
|
170
|
+
@logger.warn(sprintf('calling [vagrant reload] on a passthrough host is a noop', face))
|
171
|
+
return nil
|
172
|
+
end
|
173
|
+
|
174
|
+
@logger.info('reload()')
|
175
|
+
self.vagrant(sprintf('reload %s %s', @name, no_provision ? '--no-provision' : ''))
|
176
|
+
end
|
177
|
+
|
162
178
|
##
|
163
179
|
# suspend
|
164
180
|
#
|
@@ -18,11 +18,6 @@ class TestMeetsConstraint < Test::Unit::TestCase
|
|
18
18
|
@app.facts = fake_facts
|
19
19
|
end
|
20
20
|
|
21
|
-
def test_multiple_positive
|
22
|
-
assert(@app.meets_constraint?([['is_virtual', 'true'], ['timezone', 'PDT',]]))
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
21
|
def test_positive
|
27
22
|
|
28
23
|
assert(@app.meets_constraint?('is_virtual', 'true'))
|
@@ -57,4 +52,4 @@ class TestMeetsConstraint < Test::Unit::TestCase
|
|
57
52
|
# noop
|
58
53
|
end
|
59
54
|
|
60
|
-
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rouster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.68'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Conor Horan-Kates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -220,4 +220,3 @@ signing_key:
|
|
220
220
|
specification_version: 4
|
221
221
|
summary: Rouster is an abstraction layer for Vagrant
|
222
222
|
test_files: []
|
223
|
-
has_rdoc:
|