niman 0.0.5 → 0.0.6
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 +4 -4
- data/README.md +24 -6
- data/lib/niman/cli/application.rb +1 -1
- data/lib/niman/library/command.rb +26 -0
- data/lib/niman/library/custom_package.rb +6 -1
- data/lib/niman/nimanfile.rb +5 -0
- data/lib/niman/provisioner.rb +31 -4
- data/lib/niman/vagrant/shell.rb +9 -13
- data/lib/niman/version.rb +1 -1
- data/spec/lib/application_spec.rb +67 -7
- data/spec/lib/provisioner_spec.rb +3 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cec92b45c738e4089f9d9dd278f4c6f84b86e161
|
4
|
+
data.tar.gz: bbbfe3217ab77454b7339aefc5826bf4b5443c91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7233e582d4389918020a9ffb1a6ba067841c1d0101bc6fc562f8d1d55fb473786b0bf88617b1294cb124401591d6b0c78575e31e0e6fd4b2b9e41d574de962db
|
7
|
+
data.tar.gz: 9c5a3030863723f7df305f0c26dc390af35c6f59f53af716b906585d8f0eebcc0db1f11fb58e9e3faa5ecf7036e36f64dca26eeb742c255373922ad5febfb829
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Niman
|
2
2
|
[](https://travis-ci.org/schultyy/Niman)
|
3
|
+
[](https://codeclimate.com/github/schultyy/Niman)
|
3
4
|
|
4
5
|
Niman is a proof-of-concept provisioner.
|
5
6
|
|
@@ -34,6 +35,24 @@ This places a new file `hello.txt` in `/home/bob` with rights 0600.
|
|
34
35
|
|
35
36
|
A `Nimanfile` contains all necessary commands for `niman` to run.
|
36
37
|
|
38
|
+
### Commands
|
39
|
+
|
40
|
+
Niman has support to execute arbitrary commands on the host system:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
Niman::Recipe.configure do |config|
|
44
|
+
config.exec "touch ~/hello.txt"
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
Or if you need sudo privileges:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
Niman::Recipe.configure do |config|
|
52
|
+
config.exec :sudo, "apt-get update"
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
37
56
|
### Packages
|
38
57
|
|
39
58
|
Use a concrete package in your script:
|
@@ -42,7 +61,6 @@ Use a concrete package in your script:
|
|
42
61
|
Niman::Recipe.configure do |config|
|
43
62
|
config.package do |package|
|
44
63
|
package.name = "vim"
|
45
|
-
package.version = "7.4"
|
46
64
|
end
|
47
65
|
end
|
48
66
|
```
|
@@ -56,8 +74,8 @@ Package description:
|
|
56
74
|
#packages/ruby.rb
|
57
75
|
require 'niman'
|
58
76
|
class RubyPackage < Niman::Package
|
59
|
-
|
60
|
-
|
77
|
+
package_name :ubuntu, "ruby1.9.1"
|
78
|
+
package_name :centos, "ruby1.9.1"
|
61
79
|
end
|
62
80
|
```
|
63
81
|
In your `Nimanfile`:
|
@@ -72,14 +90,14 @@ A custom package can have one or more configuration files inside of it:
|
|
72
90
|
```ruby
|
73
91
|
#packages/nginx
|
74
92
|
class NginxPackage < Niman::Package
|
75
|
-
|
93
|
+
package_name :ubuntu, 'nginx'
|
76
94
|
|
77
|
-
|
95
|
+
file '/etc/nginx/nginx.conf' do |config|
|
78
96
|
#general nginx configuration goes here
|
79
97
|
config.content = '...'
|
80
98
|
end
|
81
99
|
|
82
|
-
|
100
|
+
file '/etc/nginx/sites-available/example.com' do |config|
|
83
101
|
config.content = '...'
|
84
102
|
end
|
85
103
|
end
|
@@ -30,7 +30,7 @@ module Niman
|
|
30
30
|
|
31
31
|
resolver = Niman::PackageResolver.new(config.instructions)
|
32
32
|
filehandler = Niman::FileHandler.new(client_shell)
|
33
|
-
provisioner = Niman::Provisioner.new(installer, filehandler, resolver.resolve)
|
33
|
+
provisioner = Niman::Provisioner.new(installer, filehandler, @client_shell, resolver.resolve)
|
34
34
|
this = self
|
35
35
|
provisioner.run do |instruction|
|
36
36
|
this.say "Executing task #{instruction.description}" unless @silent
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Niman
|
2
|
+
module Library
|
3
|
+
class Command
|
4
|
+
include Virtus.model
|
5
|
+
|
6
|
+
attribute :command, String
|
7
|
+
attribute :use_sudo, Symbol, default: :no_sudo
|
8
|
+
|
9
|
+
def valid?
|
10
|
+
!command.empty? && [:no_sudo, :sudo].include?(use_sudo)
|
11
|
+
end
|
12
|
+
|
13
|
+
def errors
|
14
|
+
"command must not be empty"
|
15
|
+
end
|
16
|
+
|
17
|
+
def description
|
18
|
+
if use_sudo == :sudo
|
19
|
+
"sudo #{command}"
|
20
|
+
else
|
21
|
+
command
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -2,7 +2,7 @@ module Niman
|
|
2
2
|
module Library
|
3
3
|
class CustomPackage
|
4
4
|
class << self
|
5
|
-
attr_reader :package_names, :files
|
5
|
+
attr_reader :package_names, :files, :commands
|
6
6
|
|
7
7
|
def valid?
|
8
8
|
!package_names.nil? &&
|
@@ -26,6 +26,11 @@ module Niman
|
|
26
26
|
''
|
27
27
|
end
|
28
28
|
|
29
|
+
def exec(sudo=:no_sudo, command)
|
30
|
+
@commands ||= []
|
31
|
+
@commands << Niman::Library::Command.new(use_sudo: sudo, command: command)
|
32
|
+
end
|
33
|
+
|
29
34
|
def errors
|
30
35
|
return [] if self.valid?
|
31
36
|
package_names.keys.map do |key|
|
data/lib/niman/nimanfile.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'niman/library/file'
|
2
|
+
require 'niman/library/command'
|
2
3
|
|
3
4
|
module Niman
|
4
5
|
class Nimanfile
|
@@ -20,5 +21,9 @@ module Niman
|
|
20
21
|
yield(package) if block_given?
|
21
22
|
@instructions.push(package)
|
22
23
|
end
|
24
|
+
|
25
|
+
def exec(use_sudo = :no_sudo, command)
|
26
|
+
@instructions.push(Niman::Library::Command.new(command: command, use_sudo: use_sudo))
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
data/lib/niman/provisioner.rb
CHANGED
@@ -4,9 +4,10 @@ module Niman
|
|
4
4
|
class Provisioner
|
5
5
|
attr_reader :instructions
|
6
6
|
|
7
|
-
def initialize(installer, filehandler, instructions)
|
7
|
+
def initialize(installer, filehandler, shell, instructions)
|
8
8
|
@installer = installer
|
9
9
|
@filehandler = filehandler
|
10
|
+
@shell = shell
|
10
11
|
@instructions = Array(instructions)
|
11
12
|
end
|
12
13
|
|
@@ -23,16 +24,42 @@ module Niman
|
|
23
24
|
@instructions.each do |instruction|
|
24
25
|
yield(instruction) if block_given?
|
25
26
|
if instruction.respond_to?(:files)
|
26
|
-
instruction
|
27
|
-
|
28
|
-
|
27
|
+
custom_package_files(instruction)
|
28
|
+
end
|
29
|
+
if instruction.respond_to?(:commands)
|
30
|
+
custom_package_exec(instruction)
|
29
31
|
end
|
30
32
|
if instruction.respond_to?(:run)
|
31
33
|
@filehandler.run(instruction)
|
34
|
+
elsif instruction.respond_to?(:command)
|
35
|
+
command(instruction)
|
32
36
|
else
|
33
37
|
@installer.install(instruction)
|
34
38
|
end
|
35
39
|
end
|
36
40
|
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def custom_package_exec(instruction)
|
45
|
+
return if instruction.commands.nil?
|
46
|
+
instruction.commands.each { |cmd| command(cmd) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def custom_package_files(instruction)
|
50
|
+
instruction.files.each do |file|
|
51
|
+
@filehandler.run(file)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def command(instruction)
|
56
|
+
mode = case instruction.use_sudo
|
57
|
+
when :sudo
|
58
|
+
true
|
59
|
+
when :no_sudo
|
60
|
+
false
|
61
|
+
end
|
62
|
+
@shell.exec(instruction.command, mode)
|
63
|
+
end
|
37
64
|
end
|
38
65
|
end
|
data/lib/niman/vagrant/shell.rb
CHANGED
@@ -18,12 +18,10 @@ module VagrantPlugins
|
|
18
18
|
|
19
19
|
def exec(command, use_sudo=false)
|
20
20
|
@machine.ui.info(command, {color: :green})
|
21
|
-
opts = { error_check: false, elevated:
|
22
|
-
|
21
|
+
opts = { error_check: false, elevated: use_sudo }
|
22
|
+
handler = Proc.new do |type, data|
|
23
23
|
if [:stderr, :stdout].include?(type)
|
24
|
-
#Output the data with the proper color based on the stream.
|
25
24
|
color = type == :stdout ? :green : :red
|
26
|
-
# Clear out the newline since we add one
|
27
25
|
data = data.chomp
|
28
26
|
next if data.empty?
|
29
27
|
options = {}
|
@@ -31,6 +29,11 @@ module VagrantPlugins
|
|
31
29
|
@machine.ui.info(data.chomp, options)
|
32
30
|
end
|
33
31
|
end
|
32
|
+
if use_sudo
|
33
|
+
@channel.sudo(command, opts, &handler)
|
34
|
+
else
|
35
|
+
@channel.execute(command, opts, &handler)
|
36
|
+
end
|
34
37
|
end
|
35
38
|
|
36
39
|
def print(message, type)
|
@@ -42,20 +45,13 @@ module VagrantPlugins
|
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
|
-
def create_file(path, content)
|
48
|
+
def create_file(path, content, use_sudo=false)
|
46
49
|
if content.include?("\n")
|
47
50
|
cmd = "cat > #{path} << EOL\n#{content}\nEOL"
|
48
51
|
else
|
49
52
|
cmd = "echo #{content} > #{path}"
|
50
53
|
end
|
51
|
-
|
52
|
-
color = type == :stdout ? :green : :red
|
53
|
-
data = data.chomp
|
54
|
-
next if data.empty?
|
55
|
-
options = {}
|
56
|
-
options[:color] = :green
|
57
|
-
@machine.ui.info(data.chomp, options)
|
58
|
-
end
|
54
|
+
self.exec(cmd, use_sudo)
|
59
55
|
end
|
60
56
|
|
61
57
|
private
|
data/lib/niman/version.rb
CHANGED
@@ -18,6 +18,55 @@ describe Niman::CLI::Application do
|
|
18
18
|
File.delete(Niman::Recipe::DEFAULT_FILENAME)
|
19
19
|
end
|
20
20
|
|
21
|
+
describe "commands" do
|
22
|
+
def write_file(body)
|
23
|
+
nimanfile = <<-EOS
|
24
|
+
Niman::Recipe.configure do |config|
|
25
|
+
#{body}
|
26
|
+
end
|
27
|
+
EOS
|
28
|
+
File.open(Niman::Recipe::DEFAULT_FILENAME, "w") {|h| h.write(nimanfile)}
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'without sudo' do
|
32
|
+
it 'is passed to shell' do
|
33
|
+
allow(shell).to receive(:exec)
|
34
|
+
write_file("config.exec 'touch hello.txt'")
|
35
|
+
application.apply
|
36
|
+
expect(shell).to have_received(:exec).with("touch hello.txt", false)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'does not execute when argument is empty' do
|
40
|
+
write_file("config.exec ''")
|
41
|
+
allow(shell).to receive(:print).with(any_args)
|
42
|
+
application.apply
|
43
|
+
expect(shell).to have_received(:print).with(any_args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
context 'with sudo' do
|
47
|
+
it 'is passed to shell' do
|
48
|
+
allow(shell).to receive(:exec)
|
49
|
+
write_file("config.exec :sudo, 'apt-get update'")
|
50
|
+
application.apply
|
51
|
+
expect(shell).to have_received(:exec).with('apt-get update', true)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does not execute when argument is empty' do
|
55
|
+
write_file("config.exec :sudo, ''")
|
56
|
+
allow(shell).to receive(:print).with(any_args)
|
57
|
+
application.apply
|
58
|
+
expect(shell).to have_received(:print).with(any_args)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'does not execute when sudo_mode is unknown' do
|
62
|
+
write_file("config.exec :foo, 'apt-get update'")
|
63
|
+
allow(shell).to receive(:print).with(any_args)
|
64
|
+
application.apply
|
65
|
+
expect(shell).to have_received(:print).with(any_args)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
21
70
|
describe "create files" do
|
22
71
|
before do
|
23
72
|
nimanfile = <<-EOS
|
@@ -82,15 +131,18 @@ describe Niman::CLI::Application do
|
|
82
131
|
context 'is existant' do
|
83
132
|
before do
|
84
133
|
nginx_package = <<-EOS
|
85
|
-
|
134
|
+
require 'niman'
|
135
|
+
|
136
|
+
class Nginx < Niman::Library::CustomPackage
|
137
|
+
package_name :debian, 'nginx'
|
86
138
|
|
87
|
-
|
88
|
-
|
139
|
+
file '/etc/nginx/nginx.conf' do |config|
|
140
|
+
config.content = 'foo bar'
|
141
|
+
end
|
89
142
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
143
|
+
exec :sudo, 'ln -s /etc/nginx/sites-available/example.org /etc/nginx/sites-enabled/example.org'
|
144
|
+
exec 'touch ~/install_notes.txt'
|
145
|
+
end
|
94
146
|
EOS
|
95
147
|
|
96
148
|
nimanfile = <<-EOS
|
@@ -119,6 +171,14 @@ describe Niman::CLI::Application do
|
|
119
171
|
it 'writes /etc/nginx/nginx.conf' do
|
120
172
|
expect(shell).to have_received(:create_file).with('/etc/nginx/nginx.conf', 'foo bar')
|
121
173
|
end
|
174
|
+
|
175
|
+
it 'links /etc/nginx/sites-available/example.org' do
|
176
|
+
expect(shell).to have_received(:exec).with('ln -s /etc/nginx/sites-available/example.org /etc/nginx/sites-enabled/example.org', true)
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'creates install_notes.txt in home directory' do
|
180
|
+
expect(shell).to have_received(:exec).with('touch ~/install_notes.txt', false)
|
181
|
+
end
|
122
182
|
end
|
123
183
|
end
|
124
184
|
end
|
@@ -4,6 +4,7 @@ require 'niman/installer'
|
|
4
4
|
require 'niman/exceptions'
|
5
5
|
|
6
6
|
describe Niman::Provisioner do
|
7
|
+
let(:shell) { double('Shell') }
|
7
8
|
let(:file) { Niman::Library::File.new(path: '~/hello.txt', content: 'ohai') }
|
8
9
|
let(:vim_package) { Niman::Library::Package.new(name: 'vim') }
|
9
10
|
let(:nginx_package) { Class.new(Niman::Library::CustomPackage) do
|
@@ -15,7 +16,7 @@ describe Niman::Provisioner do
|
|
15
16
|
let(:instructions) { [file,vim_package, nginx_package] }
|
16
17
|
let(:installer) { double(Niman::Installer) }
|
17
18
|
let(:filehandler) { double(Niman::FileHandler) }
|
18
|
-
subject(:provisioner) { Niman::Provisioner.new(installer, filehandler, instructions) }
|
19
|
+
subject(:provisioner) { Niman::Provisioner.new(installer, filehandler, shell, instructions) }
|
19
20
|
|
20
21
|
describe "#initialize" do
|
21
22
|
it 'accepts a list of instructions' do
|
@@ -23,7 +24,7 @@ describe Niman::Provisioner do
|
|
23
24
|
end
|
24
25
|
|
25
26
|
it 'accepts a single instruction' do
|
26
|
-
provisioner = Niman::Provisioner.new(installer, filehandler, file)
|
27
|
+
provisioner = Niman::Provisioner.new(installer, filehandler, shell, file)
|
27
28
|
expect(provisioner.instructions).to eq [file]
|
28
29
|
end
|
29
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: niman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Schulte
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -143,6 +143,7 @@ files:
|
|
143
143
|
- lib/niman/exceptions.rb
|
144
144
|
- lib/niman/filehandler.rb
|
145
145
|
- lib/niman/installer.rb
|
146
|
+
- lib/niman/library/command.rb
|
146
147
|
- lib/niman/library/custom_package.rb
|
147
148
|
- lib/niman/library/file.rb
|
148
149
|
- lib/niman/library/package.rb
|