niman 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0dd2e66a5efe87391ae8ea496cf819c14cc611bb
4
- data.tar.gz: 51bddf363cae6f579f3906cb2a86e62a13243e8d
3
+ metadata.gz: cec92b45c738e4089f9d9dd278f4c6f84b86e161
4
+ data.tar.gz: bbbfe3217ab77454b7339aefc5826bf4b5443c91
5
5
  SHA512:
6
- metadata.gz: 09b62fb72deb43fdb3455b3b11460bdc66eaf3dafd74f9f891481ffd35c4a981e659385d0e3336f241251afc80bd4fffe1ce6531f41b2d55a892ffdabb716603
7
- data.tar.gz: 519dbe2cf887550e5c498c5c8a5af914c23cb4b90516155e3ce36650e00149be3ef2e33efa66a06937614cdf43fa917d4cef93247e1bbaf0805d6500c790fcda
6
+ metadata.gz: 7233e582d4389918020a9ffb1a6ba067841c1d0101bc6fc562f8d1d55fb473786b0bf88617b1294cb124401591d6b0c78575e31e0e6fd4b2b9e41d574de962db
7
+ data.tar.gz: 9c5a3030863723f7df305f0c26dc390af35c6f59f53af716b906585d8f0eebcc0db1f11fb58e9e3faa5ecf7036e36f64dca26eeb742c255373922ad5febfb829
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Niman
2
2
  [![Build Status](https://travis-ci.org/schultyy/Niman.svg?branch=master)](https://travis-ci.org/schultyy/Niman)
3
+ [![Code Climate](https://codeclimate.com/github/schultyy/Niman/badges/gpa.svg)](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
- package :ubuntu, "ruby1.9.1"
60
- package :centos, "ruby1.9.1"
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
- package :ubuntu, 'nginx'
93
+ package_name :ubuntu, 'nginx'
76
94
 
77
- configuration '/etc/nginx/nginx.conf' do |config|
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
- configuration '/etc/nginx/sites-available/example.com' do |config|
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|
@@ -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
@@ -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.files.each do |file|
27
- @filehandler.run(file)
28
- end
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
@@ -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: true }
22
- @channel.sudo(command, opts) do |type, data|
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
- @channel.sudo(cmd) do |type, data|
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
@@ -1,3 +1,3 @@
1
1
  module Niman
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -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
- require 'niman'
134
+ require 'niman'
135
+
136
+ class Nginx < Niman::Library::CustomPackage
137
+ package_name :debian, 'nginx'
86
138
 
87
- class Nginx < Niman::Library::CustomPackage
88
- package_name :debian, 'nginx'
139
+ file '/etc/nginx/nginx.conf' do |config|
140
+ config.content = 'foo bar'
141
+ end
89
142
 
90
- file '/etc/nginx/nginx.conf' do |config|
91
- config.content = 'foo bar'
92
- end
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.5
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-17 00:00:00.000000000 Z
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