pawnee 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -34,6 +34,9 @@ This system will:
34
34
  - but deploying should be a separate thing (not like rubber)
35
35
  6. **It should use thor for template stuff**
36
36
  - and just overwrite it so files get copied to remote destinations if needed
37
+ 7. **It should be able to go up to root**
38
+ - you should be able to login as one user and as long as they are a sudoer all
39
+ commands should be able to jump up to root when needed
37
40
 
38
41
 
39
42
  A note on idempotence. Being idempotent is a big selling point for chef. Pawnee strives for idempotence but provides it in different ways. For example, where chef would provide a more dsl like way to declare what to do when changes are made, pawnee tries to avoid too much DSL, so the recipe developer will need to be aware that the task may be run multiple times. We find that either way the recipe developer needs to understand this situation, and with the Pawnee way, its made clearer in the code.
data/docs/TODO.md CHANGED
@@ -9,7 +9,14 @@ TODO: Need to make a clear way for pawnee gems (and recipes) to provide actions
9
9
  TODO: Run actions in threads (across multiple servers)
10
10
  TODO: Test to make sure arguments work directly as well (they probably don't right now)
11
11
  TODO: System to check for and register updates/modifications
12
- TODO: Add apt-get update to package stuff
12
+ TODO: Add apt-get update to package stuff - make it only run update once per all jobs
13
+ TODO: Make it so copied files can be overridden in a rails project
14
+ TODO: Track modified on compile?
15
+ TODO: Should setup self.source_root to point to the templates dir in the gem
16
+ TODO: Add --verbose option that shows the output of any outputs (bundler for example)
17
+ - maybe show stderr by default?
18
+ - maybe option to show on run/exec
19
+ - show stderr when there's a non-0 exit status
13
20
 
14
21
 
15
22
  def setup
@@ -21,7 +21,8 @@ module Pawnee
21
21
  # installed
22
22
  #
23
23
  # :bin_file - the name of an executable that the method can check for in the path
24
- # :configure - a string of options to pass to the ./configure command.
24
+ # :config_options - a string of options to pass to the ./configure command.
25
+ # :skip_configure - skips the configure step
25
26
  #
26
27
  # === Block
27
28
  # You can also pass a block that if it returns true, it will not
@@ -34,7 +35,7 @@ module Pawnee
34
35
  installed = false
35
36
  if options[:bin_file]
36
37
  # Check if the bin file is installed
37
- installed = exec(options[:bin_file]).strip != ''
38
+ installed = exec("which #{options[:bin_file]}").strip != ''
38
39
  else
39
40
  raise "You must pass :bin_file or a block to compile" unless block_given?
40
41
  installed = yield()
@@ -76,7 +77,7 @@ module Pawnee
76
77
 
77
78
  download(url)
78
79
  extract
79
- configure
80
+ configure unless options[:skip_configure]
80
81
  make
81
82
  make_install
82
83
  end
@@ -108,7 +109,7 @@ module Pawnee
108
109
  # action_name<String>:: An action name (used to explain what is happening)
109
110
  def run_with_failure_handler(command, action_name)
110
111
  base.say_status action_name.downcase, ''
111
- stdout, stderr, exit_code, exit_status = base.exec(command, true)
112
+ stdout, stderr, exit_code, exit_status = base.exec(command, :with_codes => true)
112
113
 
113
114
  if exit_code != 0
114
115
  base.say_status :error, "Unable to #{action_name}, see output below", :red
@@ -121,7 +122,7 @@ module Pawnee
121
122
 
122
123
  # Runs ./configure on the files
123
124
  def configure
124
- run_with_failure_handler("cd #{@extracted_path} ; ./configure #{options[:configure] || ''}", 'configure')
125
+ run_with_failure_handler("cd #{@extracted_path} ; ./configure #{options[:config_options] || ''}", 'configure')
125
126
  end
126
127
 
127
128
  # Runs make
@@ -0,0 +1,23 @@
1
+ module Pawnee
2
+ module Actions
3
+ # Adds a :once option that will only do the action the first
4
+ # time it is run (it will check for the text before it injects
5
+ # it each time)
6
+ def insert_into_file(destination, *args, &block)
7
+ if block_given?
8
+ data, config = block, args.shift
9
+ else
10
+ data, config = args.shift, args.shift
11
+ end
12
+
13
+ if config[:once]
14
+ if destination_files.binread(destination)[data]
15
+ # Don't run again, the text is already in place
16
+ return
17
+ end
18
+ end
19
+
20
+ action InjectIntoFile.new(self, destination, data, config)
21
+ end
22
+ end
23
+ end
@@ -31,7 +31,7 @@ module Pawnee
31
31
  def installed_package_version(package_name)
32
32
  packages = nil
33
33
  as_root do
34
- packages = exec("dpkg -l")
34
+ packages = exec("dpkg -l", :no_pty => true)
35
35
  end
36
36
 
37
37
  packages.split(/\n/).grep(/^ii /).each do |package|
@@ -55,17 +55,33 @@ module Pawnee
55
55
  # package_name<String>:: The name of package to be installed
56
56
  # version<String>:: The version of the package
57
57
  def install_package(package_name, version=nil)
58
+ update_package_list
59
+
58
60
  if package_installed?(package_name)
59
61
  say_status "package already installed", package_name
60
62
  else
61
63
  package_name = "#{package_name}=#{version}" if version
64
+ track_modification!
62
65
  as_root do
63
- exec("apt-get -y install #{package_name}")
66
+ exec("DEBIAN_FRONTEND=noninteractive apt-get -q -y install #{package_name}", :no_pty => true)
64
67
  end
65
68
  say_status "installed package", package_name.gsub('=', ' ')
66
69
  end
67
70
  end
68
71
 
72
+ # Updates the package manager to the most recent list of
73
+ # packages. Also only runs this once per group of operations
74
+ # to prevent this from happening too much.
75
+ def update_package_list
76
+ # TODO: this needs to be per server
77
+ unless defined?(@@packages_updated)
78
+ @@packages_updated = true
79
+ as_root do
80
+ exec('DEBIAN_FRONTEND=noninteractive apt-get -q -y update', :no_pty => true)
81
+ end
82
+ end
83
+ end
84
+
69
85
  # Installs a set of packages, use install_package if you
70
86
  # wish to specify a version
71
87
  #
@@ -75,9 +91,22 @@ module Pawnee
75
91
  # packages<Array>:: An array of strings of package names
76
92
  def install_packages(*package_names)
77
93
  packages = nil
94
+ # # TODO: pull in versions and use this to get a better
95
+ #
96
+ # as_root do
97
+ # packages = exec("dpkg --get-selections", :no_pty => true)
98
+ # end
99
+ #
100
+ # installed_package_names = []
101
+ # packages.split(/\n/).each do |package|
102
+ # name, version = package.split(/\s+/)
103
+ # installed_package_names << name
104
+ # end
105
+
106
+
78
107
  as_root do
79
- exec('apt-get -y update')
80
- packages = exec("dpkg -l")
108
+ update_package_list
109
+ packages = exec("dpkg -l", :no_pty => true)
81
110
  end
82
111
 
83
112
  installed_package_names = []
@@ -97,9 +126,10 @@ module Pawnee
97
126
  end
98
127
 
99
128
  if need_to_install_packages.size > 0
129
+ track_modification!
100
130
  as_root do
101
131
  say_status "installing packages", need_to_install_packages.join(', ')
102
- exec("apt-get -y install #{need_to_install_packages.join(' ')}")
132
+ exec("DEBIAN_FRONTEND=noninteractive apt-get -q -y install #{need_to_install_packages.join(' ')}", :no_pty => true)
103
133
  end
104
134
  end
105
135
  end
@@ -112,7 +142,7 @@ module Pawnee
112
142
  if package_installed?(package_name)
113
143
  say_status "removed package", package_name
114
144
  as_root do
115
- exec("apt-get -y remove #{package_name}")
145
+ exec("DEBIAN_FRONTEND=noninteractive apt-get -q -y remove #{package_name}", :no_pty => true)
116
146
  end
117
147
  else
118
148
  say_status "package not removed", package_name
@@ -40,8 +40,8 @@ module Pawnee
40
40
  #
41
41
  #
42
42
  class User < BaseModel
43
- define_attribute_methods [:login, :uid, :gid, :groups, :comment, :shell, :password]
44
- change_attr_accessor [:login, :uid, :gid, :groups, :comment, :shell, :password]
43
+ define_attribute_methods [:login, :uid, :gid, :groups, :comment, :shell, :password, :home]
44
+ change_attr_accessor [:login, :uid, :gid, :groups, :comment, :shell, :password, :home]
45
45
 
46
46
  attr_accessor :base
47
47
 
@@ -66,52 +66,99 @@ module Pawnee
66
66
  return base.run(*args)
67
67
  end
68
68
 
69
+ def passwd_data(find_user)
70
+ passwd_data = base.destination_files.binread('/etc/passwd')
71
+
72
+ if passwd_data
73
+ passwd_data.split(/\n/).each do |line|
74
+ user, *_, home, shell = line.split(':')
75
+
76
+ if user == find_user
77
+ return home, shell
78
+ end
79
+ end
80
+ end
81
+
82
+ return nil, nil
83
+ end
84
+
85
+ def home_for_user(find_user)
86
+ home, shell = passwd_data(find_user)
87
+ return home
88
+ end
89
+
90
+ def shell_for_user(find_user)
91
+ home, shell = passwd_data(find_user)
92
+ return shell
93
+ end
94
+
69
95
  # Pull in the current (starting) state of the attributes
70
96
  # for the User model
71
97
  def read_from_system
72
- @uid, stderr, exit_code, _ = exec("id -u #{login}", true)
98
+ @uid, stderr, exit_code, _ = exec("id -u #{login}", :with_codes => true, :log_stderr => false, :no_pty => true)
73
99
  @uid = @uid.strip
74
100
  if exit_code == 0
75
101
  # The login exists, load in more data
76
- @gid = exec("id -g #{login}").strip
77
- @groups = exec("groups #{login}").gsub(/^[^:]+[:]/, '').strip.split(/ /).sort
102
+ @gid = exec("id -g #{login}", :log_stderr => false, :no_pty => true).strip
103
+
104
+ @groups = exec("groups #{login}", :no_pty => true).gsub(/^[^:]+[:]/, '').strip.split(/ /).sort
105
+ @home = home_for_user(login)
106
+
107
+ # TODO: Load in existing shell
108
+ @shell = shell_for_user(login)
78
109
  self.new_record = false
79
110
 
80
111
  # Reject any ones we just changed, so its as if we did a find with these
81
112
  @changed_attributes = @changed_attributes.reject {|k,v| [:uid, :gid, :groups, :login].include?(k.to_sym) }
113
+ @original_groups_value = @groups
82
114
  else
83
115
  # No user
84
116
  @uid = nil
117
+ @groups ||= []
118
+ @shell ||= '/bin/bash'
119
+ self.shell_will_change!
85
120
  self.new_record = true
86
121
  end
87
122
  end
88
123
 
89
124
  # Write any changes out
90
125
  def save
126
+ # Since groups is an array, we have to manually check to see if
127
+ # its changed, because people can do << to it
128
+ if @original_groups_value != @groups
129
+ # Mark as changed
130
+ self.groups_will_change!
131
+
132
+ @original_groups_value = @groups
133
+ end
134
+
91
135
  if changed?
92
136
  raise "A login must be specified" unless login
93
137
 
94
138
  if new_record?
95
139
  # Just create a new user
96
140
  command = ["useradd"]
97
- base.say_status :create_user, login
141
+ base.say_status :create_user, login, :green
98
142
  else
99
143
  # Modify an existing user
100
144
  command = ["usermod"]
101
- base.say_status :update_user, login
145
+ base.say_status :update_user, login, :green
102
146
  end
103
147
 
104
148
  # Set options
105
149
  command << "-u #{uid}" if uid && uid_changed?
106
150
  command << "-g #{gid}" if gid && gid_changed?
107
- command << "-G #{groups.join(',')}" if groups && groups_changed?
151
+ command << "-G #{groups.join(',')}" if groups && groups_changed? && groups.size != 0
108
152
  command << "-c #{comment.inspect}" if comment && comment_changed?
109
153
  command << "-s #{shell.inspect}" if shell && shell_changed?
110
154
  command << "-p #{password.inspect}" if password && password_changed?
155
+
156
+ # TODO: If update, we need to make the directory first to move things to
157
+ command << "-m -d #{home.inspect}" if home && home_changed?
111
158
  command << login
112
159
 
113
160
  base.as_root do
114
- base.exec(command.join(' '))
161
+ base.exec(command.join(' '), :no_pty => true)
115
162
  end
116
163
  else
117
164
  base.say_status :user_exists, login, :blue
@@ -121,7 +168,7 @@ module Pawnee
121
168
  def destroy
122
169
  self.new_record = true
123
170
  base.as_root do
124
- base.exec("userdel #{login}")
171
+ base.exec("userdel #{login}", :no_pty => true)
125
172
  end
126
173
  end
127
174
  end
@@ -9,6 +9,7 @@ require 'active_support/core_ext/hash/deep_merge'
9
9
  require 'pawnee/roles'
10
10
  require 'pawnee/invocation'
11
11
  require 'pawnee/modified'
12
+ require 'pawnee/ssh_connection'
12
13
 
13
14
  module Pawnee
14
15
  # The pawnee gem provides the Pawnee::Base class, which includes actions
@@ -21,6 +22,7 @@ module Pawnee
21
22
  include Pawnee::Actions
22
23
  include Pawnee::Invocation
23
24
  include Pawnee::Modified
25
+ include Pawnee::SshConnection
24
26
  include Roles
25
27
 
26
28
  attr_accessor :server
@@ -113,7 +115,7 @@ module Pawnee
113
115
 
114
116
  # Guess the gem name based on the class name
115
117
  def self.gem_name
116
- self.name.gsub(/[:][:]Base$/, '').gsub(/^[^:]+[:][:]/, '').gsub('::', '-').downcase
118
+ self.name.gsub(/[:][:]Base$/, '').gsub(/^[^:]+[:][:]/, '').gsub(/([A-Z]+)([A-Z][a-z])/,'\1-\2').gsub(/([a-z\d])([A-Z])/,'\1-\2').downcase
117
119
  end
118
120
 
119
121
  no_tasks {
@@ -122,6 +124,10 @@ module Pawnee
122
124
  def invoke_task(task, *args) #:nodoc:
123
125
  current = @_invocations[self.class]
124
126
 
127
+ # Default force for actions in options
128
+ # TODO: Should this get set in invoke?
129
+ options[:force] ||= true
130
+
125
131
  unless current.include?(task.name)
126
132
  current << task.name
127
133
 
@@ -178,9 +184,15 @@ module Pawnee
178
184
  # Whenever say is used, also print out the server name
179
185
  def say(*args)
180
186
  text = args[0]
181
- text = "[#{server}]:\t" + text
187
+ text = "[#{server}]:\t" + text.to_s if server
182
188
  super(text, *args[1..-1])
183
189
  end
190
+
191
+ def say_status(*args)
192
+ text = args[0]
193
+ text = "[#{server}]:\t" + text.to_s if server
194
+ super(text, *args[1..-1])
195
+ end
184
196
  }
185
197
 
186
198
  private
@@ -220,7 +232,7 @@ module Pawnee
220
232
  super(subclass)
221
233
 
222
234
  # Make sure cli has been loaded at this point
223
- require 'pawnee/cli'
235
+ require 'pawnee/cli' unless defined?(Pawnee) && defined?(Pawnee::CLI)
224
236
 
225
237
  # Skip the main CLI class
226
238
  return if subclass == Pawnee::CLI
@@ -240,6 +252,7 @@ module Pawnee
240
252
  subclass.role(class_name)
241
253
  end
242
254
 
255
+
243
256
  def self.recipes
244
257
  @recipes
245
258
  end
@@ -271,6 +284,8 @@ module Pawnee
271
284
  def self.method_added(meth)
272
285
  super
273
286
 
287
+ require 'pawnee/cli' unless defined?(Pawnee) && defined?(Pawnee::CLI)
288
+
274
289
  # Take all of the setup options and copy them to the main
275
290
  # CLI setup task
276
291
  meth = meth.to_s
@@ -33,17 +33,18 @@ module Pawnee
33
33
  method_option :bin, :type => :boolean, :default => false, :aliases => '-b', :banner => "Generate a binary for your library."
34
34
  def gem(name)
35
35
  # Prefix all gems with pawnee-
36
- name = 'pawnee-' + name.chomp("/") # remove trailing slash if present
37
- folder_name = name.gsub('-', '/')
38
- target = File.join(Dir.pwd, name)
39
- constant_name = name.split('_').map{|p| p[0..0].upcase + p[1..-1] }.join
40
- constant_name = constant_name.split('-').map{|q| q[0..0].upcase + q[1..-1] }.join('::') if constant_name =~ /-/
36
+ dir_name = 'pawnee-' + name.chomp("/") # remove trailing slash if present
37
+ folder_name = "pawnee/" + name
38
+ target = File.join(Dir.pwd, dir_name)
39
+ constant_name = "Pawnee::" + name.split('-').map{|q| q[0..0].upcase + q[1..-1] }.join('')
40
+ puts constant_name
41
41
  constant_array = constant_name.split('::')
42
+ puts constant_array.inspect
42
43
  git_user_name = `git config user.name`.chomp
43
44
  git_user_email = `git config user.email`.chomp
44
45
  opts = {
45
46
  # Don't require the pawnee- when requring though
46
- :name => name.gsub(/^pawnee[-]/, ''),
47
+ :name => name,
47
48
  :constant_name => constant_name,
48
49
  :constant_array => constant_array,
49
50
  :author => git_user_name.empty? ? "TODO: Write your name" : git_user_name,
@@ -54,11 +55,12 @@ module Pawnee
54
55
  template(File.join("newgem/LICENSE.tt"), File.join(target, "LICENSE"), opts)
55
56
  template(File.join("newgem/README.md.tt"), File.join(target, "README.md"), opts)
56
57
  template(File.join("newgem/gitignore.tt"), File.join(target, ".gitignore"), opts)
57
- template(File.join("newgem/newgem.gemspec.tt"), File.join(target, "#{name}.gemspec"), opts)
58
- template(File.join("newgem/lib/pawnee/newgem.rb.tt"), File.join(target, "lib/pawnee/#{name}.rb"), opts)
58
+ template(File.join("newgem/newgem.gemspec.tt"), File.join(target, "#{dir_name}.gemspec"), opts)
59
+ template(File.join("newgem/lib/newgem.rb.tt"), File.join(target, "lib/#{dir_name}.rb"), opts)
59
60
  template(File.join("newgem/lib/pawnee/newgem/version.rb.tt"), File.join(target, "lib/#{folder_name}/version.rb"), opts)
60
61
  template(File.join("newgem/lib/pawnee/newgem/base.rb.tt"), File.join(target, "lib/#{folder_name}/base.rb"), opts)
61
62
  template(File.join("newgem/spec/spec_helper.rb.tt"), File.join(target, "spec/spec_helper.rb"), opts)
63
+ template(File.join("newgem/spec/base_spec.rb.tt"), File.join(target, "spec/base_spec.rb"), opts)
62
64
  template(File.join("newgem/spec/vagrant/Vagrantfile.tt"), File.join(target, "spec/vagrant/Vagrantfile"), opts)
63
65
  template(File.join("newgem/spec/vagrant/vagrant.rb.tt"), File.join(target, "spec/vagrant/vagrant.rb"), opts)
64
66
  if options[:bin]
@@ -9,5 +9,6 @@ module Pawnee
9
9
  @_invocations = config[:invocations] || Hash.new { |h,k| h[k] = [] }
10
10
  @_initializer = [ args, options, config ]
11
11
  end
12
+
12
13
  end
13
14
  end
@@ -3,16 +3,16 @@ require 'thor'
3
3
  # Add setup to the base class
4
4
  module Pawnee
5
5
  class Base < Thor
6
- if defined?(Rails)
6
+ if defined?(Rails) && defined?(Rails::Railtie)
7
7
  class Railtie < Rails::Railtie
8
8
  end
9
9
  end
10
10
 
11
11
  def self.setup(gem_name)
12
12
  # Setup the railtie
13
- require "#{gem_name.gsub(/^pawnee[-]/, '')}/base"
13
+ require "pawnee/#{gem_name.gsub(/^pawnee[-]/, '')}/base"
14
14
 
15
- if defined?(Rails)
15
+ if defined?(Rails) && defined?(Rails::Railtie)
16
16
  Railtie.initializer "#{gem_name}.configure_rails_initialization" do
17
17
  gem_recipie_name = gem_name.gsub(/^pawnee[-]/, '')
18
18
  require "#{gem_recipie_name}/base"
@@ -0,0 +1,26 @@
1
+ module Pawnee
2
+ module SshConnection
3
+ # Reconnects to the remote server (using net/ssh).
4
+ # This is useful since often things in linux don't take effect
5
+ # until the user creates a new login shell (adding a user to
6
+ # a group for example)
7
+ def reconnect!
8
+ host = self.destination_connection.host
9
+ options = self.destination_connection.options
10
+ user = options[:user]
11
+
12
+ # Close the existing connection
13
+ self.destination_connection.close
14
+
15
+ # Reconnect
16
+ new_connection = Net::SSH.start(host, user, options)
17
+
18
+ # Copy the instance variables to the old conection so we can keep using
19
+ # the same session without reassigning references
20
+ self.destination_connection.instance_variables.each do |variable_name|
21
+ value = new_connection.instance_variable_get(variable_name)
22
+ self.destination_connection.instance_variable_set(variable_name, value)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,4 +1,4 @@
1
- require "<%= config[:name] %>/version"
1
+ require "pawnee/<%= config[:name] %>/version"
2
2
  require 'pawnee/base'
3
3
 
4
4
  <%- config[:constant_array].each_with_index do |c,i| -%>
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
13
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
14
  gem.name = "pawnee-<%=config[:name]%>"
15
- gem.require_paths = ["lib/pawnee"]
15
+ gem.require_paths = ["lib"]
16
16
  gem.add_runtime_dependency 'pawnee'
17
17
 
18
18
  # Pawnee development dependencies - versions for these will
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'pawnee/<%=config[:name]%>/base'
3
+
4
+ describe Pawnee::<%=config[:name].capitalize %>::Base do
5
+ it "should install <%=config[:name]%>" do
6
+ connection = VagrantManager.connect
7
+
8
+ Pawnee::Base.invoke_roles(:setup, ['<%=config[:name]%>'], {:servers => [connection], :roles => ['<%=config[:name]%>']})
9
+
10
+ connection.close unless connection.closed?
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module Pawnee
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -10,16 +10,11 @@ describe "compile actions" do
10
10
  end
11
11
 
12
12
  it 'should install a package' do
13
- @base.install_packages('libpcre3', 'libpcre3-dev', 'libpcrecpp0', 'libssl-dev', 'zlib1g-dev')
14
- @base.as_root do
15
- @base.exec('rm /usr/local/sbin/nginx')
16
- end
13
+ @base.exec('which redis-server').should == ''
17
14
 
18
- @base.exec('which nginx').should == ''
15
+ @base.compile('http://redis.googlecode.com/files/redis-2.4.15.tar.gz', '/home/vagrant/redis-server/', {:skip_configure => true, :bin_file => 'redis-server'})
19
16
 
20
- @base.compile('http://nginx.org/download/nginx-1.2.0.tar.gz', '/home/vagrant/nginx/', {configure: '--sbin-path=/usr/local/sbin', :bin_file => 'nginx'})
21
-
22
- @base.exec('which nginx').should_not == ''
17
+ @base.exec('which redis-server').should_not == ''
23
18
  end
24
19
 
25
20
  end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'pawnee/base'
3
+
4
+
5
+ # NOTE: These are designed to run in order on vagrant
6
+ describe "inject into file" do
7
+ before do
8
+ @base = Pawnee::Base.new
9
+ @base.destination_connection = VagrantManager.connect
10
+ end
11
+
12
+ it "should only inject once if the once option is specified" do
13
+
14
+ end
15
+
16
+ end
@@ -10,7 +10,7 @@ describe "user actions" do
10
10
  end
11
11
 
12
12
  def user_exists?(login)
13
- _, _, exit_code, _ = @base.exec("id -u #{login}", true)
13
+ _, _, exit_code, _ = @base.exec("id -u #{login}", :with_codes => true)
14
14
  return exit_code == 0
15
15
  end
16
16
 
@@ -32,8 +32,8 @@ describe "user actions" do
32
32
  end
33
33
 
34
34
  it "should modify a user" do
35
- # @base.should_receive(:exec).any_number_of_times.ordered.with('id -u blue', true).and_return(["1002\n", '', 0, nil])
36
- # @base.should_receive(:exec).any_number_of_times.ordered.with('id -u blue', true).and_return(["1002\n", '', 0, nil])
35
+ # @base.should_receive(:exec).any_number_of_times.ordered.with('id -u blue', :with_codes => true).and_return(["1002\n", '', 0, nil])
36
+ # @base.should_receive(:exec).any_number_of_times.ordered.with('id -u blue', :with_codes => true).and_return(["1002\n", '', 0, nil])
37
37
  # @base.should_receive(:exec).any_number_of_times.ordered.with('id -g blue').and_return("1002\n")
38
38
  # @base.should_receive(:exec).any_number_of_times.ordered.with('groups blue').and_return("blue: blue")
39
39
  # @base.should_receive(:exec).once.ordered.with('useradd -c "comment" blue').and_return('')
@@ -44,6 +44,9 @@ describe "user actions" do
44
44
  )
45
45
  end
46
46
 
47
+ # TODO: Test when there is no groups
48
+ # TODO: Test default shell
49
+
47
50
  it "should delete a user" do
48
51
  user_exists?('blue').should == true
49
52
 
data/spec/base_spec.rb CHANGED
@@ -106,7 +106,7 @@ describe Pawnee::Base do
106
106
  'servers' => [
107
107
  {'domain' => 'test1.com', 'roles' => ['red']},
108
108
  {'domain' => 'test2.com', 'roles' => ['blue', 'red']}
109
- ]
109
+ ], 'force' => true
110
110
  }
111
111
 
112
112
  Pawnee::Base.should_receive(:config_options).at_least(:once).and_return(config_options)
@@ -130,7 +130,7 @@ describe Pawnee::Base do
130
130
  'servers' => [
131
131
  {'domain' => 'test1.com', 'roles' => ['red']},
132
132
  {'domain' => 'test2.com', 'roles' => ['red']}
133
- ]
133
+ ], 'force' => true
134
134
  }
135
135
 
136
136
  Pawnee::Base.should_receive(:config_options).at_least(:once).and_return(options)
@@ -151,7 +151,7 @@ describe Pawnee::Base do
151
151
  'servers' => [
152
152
  {'domain' => 'test1.com', 'roles' => ['red']},
153
153
  {'domain' => 'test2.com', 'roles' => ['red', 'blue']}
154
- ]
154
+ ], 'force' => true
155
155
  }
156
156
 
157
157
  Pawnee::Base.should_receive(:config_options).at_least(:once).and_return(options)
data/spec/spec_helper.rb CHANGED
@@ -20,7 +20,7 @@ RSpec.configure do |config|
20
20
  unless ENV['TRAVIS']
21
21
  # Rollback the server
22
22
  puts "Roll back test server"
23
- `cd spec/vagrant/ ; BUNDLE_GEMFILE=../../Gemfile bundle exec vagrant sandbox rollback`
23
+ # `cd spec/vagrant/ ; BUNDLE_GEMFILE=../../Gemfile bundle exec vagrant sandbox rollback`
24
24
  end
25
25
  end
26
26
  end
@@ -1 +1 @@
1
- {"active":{"default":"9a7fbb28-386f-478a-b11c-6ce30056d085"}}
1
+ {"active":{"default":"c90bb8aa-bba5-4bdf-98e8-5097a58829c8"}}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pawnee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-17 00:00:00.000000000 Z
12
+ date: 2012-06-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -258,6 +258,7 @@ files:
258
258
  - lib/pawnee/pawnee/actions.rb
259
259
  - lib/pawnee/pawnee/actions/base_model.rb
260
260
  - lib/pawnee/pawnee/actions/compile.rb
261
+ - lib/pawnee/pawnee/actions/inject_into_file.rb
261
262
  - lib/pawnee/pawnee/actions/package.rb
262
263
  - lib/pawnee/pawnee/actions/user.rb
263
264
  - lib/pawnee/pawnee/base.rb
@@ -268,16 +269,17 @@ files:
268
269
  - lib/pawnee/pawnee/railtie.rb
269
270
  - lib/pawnee/pawnee/roles.rb
270
271
  - lib/pawnee/pawnee/setup.rb
272
+ - lib/pawnee/pawnee/ssh_connection.rb
271
273
  - lib/pawnee/pawnee/templates/newgem/Gemfile.tt
272
274
  - lib/pawnee/pawnee/templates/newgem/LICENSE.tt
273
275
  - lib/pawnee/pawnee/templates/newgem/README.md.tt
274
276
  - lib/pawnee/pawnee/templates/newgem/Rakefile.tt
275
- - lib/pawnee/pawnee/templates/newgem/bin/newgem.tt
276
277
  - lib/pawnee/pawnee/templates/newgem/gitignore.tt
277
- - lib/pawnee/pawnee/templates/newgem/lib/pawnee/newgem.rb.tt
278
+ - lib/pawnee/pawnee/templates/newgem/lib/newgem.rb.tt
278
279
  - lib/pawnee/pawnee/templates/newgem/lib/pawnee/newgem/base.rb.tt
279
280
  - lib/pawnee/pawnee/templates/newgem/lib/pawnee/newgem/version.rb.tt
280
281
  - lib/pawnee/pawnee/templates/newgem/newgem.gemspec.tt
282
+ - lib/pawnee/pawnee/templates/newgem/spec/base_spec.rb.tt
281
283
  - lib/pawnee/pawnee/templates/newgem/spec/spec_helper.rb.tt
282
284
  - lib/pawnee/pawnee/templates/newgem/spec/vagrant/Vagrantfile.tt
283
285
  - lib/pawnee/pawnee/templates/newgem/spec/vagrant/vagrant.rb.tt
@@ -285,6 +287,7 @@ files:
285
287
  - pawnee.gemspec
286
288
  - spec/actions/compile_spec.rb
287
289
  - spec/actions/file_spec.rb
290
+ - spec/actions/inject_into_file_spec.rb
288
291
  - spec/actions/package_spec.rb
289
292
  - spec/actions/user_spec.rb
290
293
  - spec/base_spec.rb
@@ -307,7 +310,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
307
310
  version: '0'
308
311
  segments:
309
312
  - 0
310
- hash: 4305242221210104072
313
+ hash: 2154589448393807289
311
314
  required_rubygems_version: !ruby/object:Gem::Requirement
312
315
  none: false
313
316
  requirements:
@@ -316,7 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
316
319
  version: '0'
317
320
  segments:
318
321
  - 0
319
- hash: 4305242221210104072
322
+ hash: 2154589448393807289
320
323
  requirements: []
321
324
  rubyforge_project:
322
325
  rubygems_version: 1.8.22
@@ -326,6 +329,7 @@ summary: Better server provisioing
326
329
  test_files:
327
330
  - spec/actions/compile_spec.rb
328
331
  - spec/actions/file_spec.rb
332
+ - spec/actions/inject_into_file_spec.rb
329
333
  - spec/actions/package_spec.rb
330
334
  - spec/actions/user_spec.rb
331
335
  - spec/base_spec.rb
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require '<%= config[:name] %>'