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 +5 -13
- data/README.md +1 -1
- data/lib/mixlib/shellout.rb +18 -3
- data/lib/mixlib/shellout/unix.rb +58 -25
- data/lib/mixlib/shellout/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZmQ5NDI4Nzc0MzJiOGYxNzQ1NDZkODYwZTRhZmQ4OTQ1YjYxMmVhYQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f89036d9e49a1aa022ad2a3a386c7c470c47bae3
|
4
|
+
data.tar.gz: 28a237b3cf0725a1deb0871f2a1b30a76f505025
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
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
|
-
|
42
|
+
whoami = Mixlib::ShellOut.new("whoami.exe", :user => "username", :domain => "DOMAIN", :password => "password")
|
43
43
|
whoami.run_command
|
44
44
|
|
45
45
|
## Platform Support
|
data/lib/mixlib/shellout.rb
CHANGED
@@ -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
|
204
|
-
|
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
|
data/lib/mixlib/shellout/unix.rb
CHANGED
@@ -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
|
-
|
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
|
-
#
|
151
|
-
#
|
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
|
-
|
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
|
-
#
|
292
|
-
#
|
293
|
-
#
|
294
|
-
Process.
|
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
|
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
|
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:
|
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: '
|
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: '
|
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.
|
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
|