Skip to content

Commit

Permalink
Merge pull request #33 from openSUSE/chroot_support
Browse files Browse the repository at this point in the history
Chroot support
  • Loading branch information
jreidinger committed Dec 18, 2015
2 parents 8b67ab4 + 8525ef3 commit c917969
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Features
* Thread-safety
* Allows overriding environment variables
* Optional logging for easy debugging
* Running on changed root ( requires chroot permission )

Non-features
------------
Expand Down Expand Up @@ -226,6 +227,15 @@ Dir.chdir("/workspace") do
end
```

### Changing System Root

If a command needs to be executed in different system root then the `:chroot`
option can be used:

```ruby
Cheetah.run("/usr/bin/inspect", chroot: "/mnt/target_system")
```

### More Information

For more information, see the
Expand Down
27 changes: 25 additions & 2 deletions lib/cheetah.rb
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ def log_stream_line(stream, line)
stdout: nil,
stderr: nil,
logger: nil,
env: {}
env: {},
chroot: "/"
}

READ = 0 # @private
Expand Down Expand Up @@ -308,6 +309,8 @@ class << self
# @option options [Hash] :env ({})
# Allows to update ENV for the time of running the command. if key maps to nil value it
# is deleted from ENV.
# @option options [String] :chroot ("/")
# Allows to run on different system root.
#
# @example
# Cheetah.run("tar", "xzf", "foo.tar.gz")
Expand Down Expand Up @@ -487,9 +490,25 @@ def from_pipe(stream, pipe)
pipe[WRITE].close
end

def chroot_step(options)
return options if [nil, "/"].include?(options[:chroot])

options = options.dup
# delete chroot option otherwise in pipe will chroot each fork recursivelly
root = options.delete(:chroot)
Dir.chroot(root)
# curdir can be outside chroot which is considered as security problem
Dir.chdir("/")

options
end

def fork_commands_recursive(commands, pipes, options)
fork do
begin
# support chrooting
options = chroot_step(options)

if commands.size == 1
from_pipe(STDIN, pipes[:stdin])
else
Expand Down Expand Up @@ -521,7 +540,11 @@ def fork_commands_recursive(commands, pipes, options)
with_env(options[:env]) do
exec([command, command], *args)
end
rescue SystemCallError
rescue SystemCallError => e
# depends when failed, if pipe is already redirected or not, so lets find it
output = pipes[:stderr][WRITE].closed? ? STDERR : pipes[:stderr][WRITE]
output.puts e.message

exit!(127)
end
end
Expand Down

0 comments on commit c917969

Please sign in to comment.