mixlib-shellout 2.0.1 → 2.1.0

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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NGM3NmFiYjNlN2IwZTI3YWNiNTJiYWViODg3MTlhYTNlZjZiMzlkNg==
5
- data.tar.gz: !binary |-
6
- ZmQ5NDI4Nzc0MzJiOGYxNzQ1NDZkODYwZTRhZmQ4OTQ1YjYxMmVhYQ==
2
+ SHA1:
3
+ metadata.gz: f89036d9e49a1aa022ad2a3a386c7c470c47bae3
4
+ data.tar.gz: 28a237b3cf0725a1deb0871f2a1b30a76f505025
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NjU0MjZkMDFkNDAwMDQ3Y2I3NTJkZTVhMTQ5MTc3MzY1MTBhMzU0ZWZlYjAx
10
- NjBlMTU2ZmRiODAyNjI4ODlkOWEzYmFiNzJjNzc3YTg5NWQ4MzVmZDViM2Iw
11
- YWQyMWIyNTcxYjUxNjVjNTk4YjdiNGJkYjc2NmE4YzhhYjlkZjI=
12
- data.tar.gz: !binary |-
13
- MmE4ZjAxOGU0ZGM3OTY3M2EyZmExMjJkODI1ZDE0YmQwZDU4ZGY0YzQyYThh
14
- MzI1NDdkMTc3MGFkNGQwZDA5NmJjMzg2NmFhNWQzOWExMDczZTFkZWQ5NzVh
15
- YWVlNjRlNTEyN2VlMDU1YTY3M2I5NDFlZDI3NTk2OTU5ZTk1YWQ=
6
+ metadata.gz: 7c06cca58cd3c1192c1d591e95c4ddd79961de7eca1a4f255ef70443c4c4dd323f8a07db4f0681d58f759fc3048ffa03081956d1277cdf8b356be86a6a9d7358
7
+ data.tar.gz: f9964010b07fc39958ff65ff37b4906c6f1867ab7262e4dbc2c4df32500de257536c50007e02466869f495ae260c284eb78a9d7d9b6cf90b0affdabc1943c044
data/README.md CHANGED
@@ -39,7 +39,7 @@ Invoke crontab to edit user cron:
39
39
  ## Windows Impersonation Example
40
40
  Invoke "whoami.exe" to demonstrate running a command as another user:
41
41
 
42
- whomai = Mixlib::ShellOut.new("whoami.exe", :user => "username", :domain => "DOMAIN", :password => "password")
42
+ whoami = Mixlib::ShellOut.new("whoami.exe", :user => "username", :domain => "DOMAIN", :password => "password")
43
43
  whoami.run_command
44
44
 
45
45
  ## Platform Support
@@ -40,8 +40,13 @@ module Mixlib
40
40
  attr_accessor :user
41
41
  attr_accessor :domain
42
42
  attr_accessor :password
43
+ # TODO remove
43
44
  attr_accessor :with_logon
44
45
 
46
+ # Whether to simulate logon as the user. Normally set via options passed to new
47
+ # Always enabled on windows
48
+ attr_accessor :login
49
+
45
50
  # Group the command will run as. Normally set via options passed to new
46
51
  attr_accessor :group
47
52
 
@@ -141,6 +146,8 @@ module Mixlib
141
146
  # child process. Generally this is used to copy data from the child to
142
147
  # the parent's stdout so that users may observe the progress of
143
148
  # long-running commands.
149
+ # * +login+: Whether to simulate a login (set secondary groups, primary group, environment
150
+ # variables etc) as done by the OS in an actual login
144
151
  # === Examples:
145
152
  # Invoke find(1) to search for .rb files:
146
153
  # find = Mixlib::ShellOut.new("find . -name '*.rb'")
@@ -164,6 +171,7 @@ module Mixlib
164
171
  @cwd = nil
165
172
  @valid_exit_codes = [0]
166
173
  @terminate_reason = nil
174
+ @timeout = nil
167
175
 
168
176
  if command_args.last.is_a?(Hash)
169
177
  parse_options(command_args.pop)
@@ -192,6 +200,7 @@ module Mixlib
192
200
 
193
201
  # The uid that the subprocess will switch to. If the user attribute was
194
202
  # given as a username, it is converted to a uid by Etc.getpwnam
203
+ # TODO migrate to shellout/unix.rb
195
204
  def uid
196
205
  return nil unless user
197
206
  user.kind_of?(Integer) ? user : Etc.getpwnam(user.to_s).uid
@@ -199,9 +208,11 @@ module Mixlib
199
208
 
200
209
  # The gid that the subprocess will switch to. If the group attribute is
201
210
  # given as a group name, it is converted to a gid by Etc.getgrnam
211
+ # TODO migrate to shellout/unix.rb
202
212
  def gid
203
- return nil unless group
204
- group.kind_of?(Integer) ? group : Etc.getgrnam(group.to_s).gid
213
+ return group.kind_of?(Integer) ? group : Etc.getgrnam(group.to_s).gid if group
214
+ return Etc.getpwuid(uid).gid if using_login?
215
+ return nil
205
216
  end
206
217
 
207
218
  def timeout
@@ -322,7 +333,8 @@ module Mixlib
322
333
  self.log_tag = setting
323
334
  when 'environment', 'env'
324
335
  self.environment = setting || {}
325
-
336
+ when 'login'
337
+ self.login = setting
326
338
  else
327
339
  raise InvalidCommandOption, "option '#{option.inspect}' is not a valid option for #{self.class.name}"
328
340
  end
@@ -332,6 +344,9 @@ module Mixlib
332
344
  end
333
345
 
334
346
  def validate_options(opts)
347
+ if login && !user
348
+ raise InvalidCommandOption, "cannot set login without specifying a user"
349
+ end
335
350
  super
336
351
  end
337
352
  end
@@ -30,6 +30,47 @@ module Mixlib
30
30
  # No options to validate, raise exceptions here if needed
31
31
  end
32
32
 
33
+ # Whether we're simulating a login shell
34
+ def using_login?
35
+ return login && user
36
+ end
37
+
38
+ # Helper method for sgids
39
+ def all_seconderies
40
+ ret = []
41
+ Etc.endgrent
42
+ while ( g = Etc.getgrent ) do
43
+ ret << g
44
+ end
45
+ Etc.endgrent
46
+ return ret
47
+ end
48
+
49
+ # The secondary groups that the subprocess will switch to.
50
+ # Currently valid only if login is used, and is set
51
+ # to the user's secondary groups
52
+ def sgids
53
+ return nil unless using_login?
54
+ user_name = Etc.getpwuid(uid).name
55
+ all_seconderies.select{|g| g.mem.include?(user_name)}.map{|g|g.gid}
56
+ end
57
+
58
+ # The environment variables that are deduced from simulating logon
59
+ # Only valid if login is used
60
+ def logon_environment
61
+ return {} unless using_login?
62
+ entry = Etc.getpwuid(uid)
63
+ # According to `man su`, the set fields are:
64
+ # $HOME, $SHELL, $USER, $LOGNAME, $PATH, and $IFS
65
+ # Values are copied from "shadow" package in Ubuntu 14.10
66
+ {'HOME'=>entry.dir, 'SHELL'=>entry.shell, 'USER'=>entry.name, 'LOGNAME'=>entry.name, 'PATH'=>'/sbin:/bin:/usr/sbin:/usr/bin', 'IFS'=>"\t\n"}
67
+ end
68
+
69
+ # Merges the two environments for the process
70
+ def process_environment
71
+ logon_environment.merge(self.environment)
72
+ end
73
+
33
74
  # Run the command, writing the command's standard out and standard error
34
75
  # to +stdout+ and +stderr+, and saving its exit status object to +status+
35
76
  # === Returns
@@ -63,8 +104,8 @@ module Mixlib
63
104
  # CHEF-3390: Marshall.load on Ruby < 1.8.7p369 also has a GC bug related
64
105
  # to Marshall.load, so try disabling GC first.
65
106
  propagate_pre_exec_failure
66
- get_child_pgid
67
107
 
108
+ @status = nil
68
109
  @result = nil
69
110
  @execution_time = 0
70
111
 
@@ -107,18 +148,6 @@ module Mixlib
107
148
 
108
149
  private
109
150
 
110
- def get_child_pgid
111
- # The behavior of Process.getpgid (see also getpgid(2) ) when the
112
- # argument is the pid of a zombie isn't well specified. On Linux it
113
- # works, on OS X it returns ESRCH (which ruby turns into Errno::ESRCH).
114
- #
115
- # If the child dies very quickly, @child_pid may be a zombie, so handle
116
- # ESRCH here.
117
- @child_pgid = -Process.getpgid(@child_pid)
118
- rescue Errno::ESRCH, Errno::EPERM
119
- @child_pgid = nil
120
- end
121
-
122
151
  def set_user
123
152
  if user
124
153
  Process.uid = uid
@@ -133,8 +162,15 @@ module Mixlib
133
162
  end
134
163
  end
135
164
 
165
+ def set_secondarygroups
166
+ if sgids
167
+ Process.groups = sgids
168
+ end
169
+ end
170
+
136
171
  def set_environment
137
- environment.each do |env_var,value|
172
+ # user-set variables should override the login ones
173
+ process_environment.each do |env_var,value|
138
174
  ENV[env_var] = value
139
175
  end
140
176
  end
@@ -147,14 +183,10 @@ module Mixlib
147
183
  Dir.chdir(cwd) if cwd
148
184
  end
149
185
 
150
- # Process group id of the child. Returned as a negative value so you can
151
- # put it directly in arguments to kill, wait, etc.
152
- #
153
- # This may be nil if the child dies before the parent can query the
154
- # system for its pgid (on some systems it is an error to get the pgid of
155
- # a zombie).
186
+ # Since we call setsid the child_pgid will be the child_pid, set to negative here
187
+ # so it can be directly used in arguments to kill, wait, etc.
156
188
  def child_pgid
157
- @child_pgid
189
+ -@child_pid
158
190
  end
159
191
 
160
192
  def initialize_ipc
@@ -288,13 +320,14 @@ module Mixlib
288
320
  # support the "ONESHOT" optimization (where sh -c does exec without
289
321
  # forking). To support cleaning up all the children, we need to
290
322
  # ensure they're in a unique process group.
291
- # We cannot use setsid here since getpgid fails on AIX with EPERM
292
- # when parent and child have different sessions and the parent tries to get the process group,
293
- # hence we just create a new process group, and have the same session.
294
- Process.setpgrp
323
+ #
324
+ # We use setsid here to abandon our controlling tty and get a new session
325
+ # and process group that are set to the pid of the child process.
326
+ Process.setsid
295
327
 
296
328
  configure_subprocess_file_descriptors
297
329
 
330
+ set_secondarygroups
298
331
  set_group
299
332
  set_user
300
333
  set_environment
@@ -1,5 +1,5 @@
1
1
  module Mixlib
2
2
  class ShellOut
3
- VERSION = "2.0.1"
3
+ VERSION = "2.1.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-shellout
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Opscode
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-19 00:00:00.000000000 Z
11
+ date: 2015-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '3.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.0'
26
+ version: '3.0'
27
27
  description: Run external commands on Unix or Windows
28
28
  email: info@opscode.com
29
29
  executables: []
@@ -49,17 +49,17 @@ require_paths:
49
49
  - lib
50
50
  required_ruby_version: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.9.3
55
55
  required_rubygems_version: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - ! '>='
57
+ - - ">="
58
58
  - !ruby/object:Gem::Version
59
59
  version: '0'
60
60
  requirements: []
61
61
  rubyforge_project:
62
- rubygems_version: 2.4.1
62
+ rubygems_version: 2.4.6
63
63
  signing_key:
64
64
  specification_version: 4
65
65
  summary: Run external commands on Unix or Windows