omnibus 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +9 -0
- data/LICENSE +201 -0
- data/NOTICE +9 -0
- data/README.md +186 -0
- data/Rakefile +7 -0
- data/bin/makeself-header.sh +401 -0
- data/bin/makeself.sh +407 -0
- data/bin/omnibus +11 -0
- data/lib/omnibus.rb +280 -0
- data/lib/omnibus/build_version.rb +281 -0
- data/lib/omnibus/builder.rb +323 -0
- data/lib/omnibus/clean_tasks.rb +30 -0
- data/lib/omnibus/cli.rb +35 -0
- data/lib/omnibus/cli/application.rb +136 -0
- data/lib/omnibus/cli/base.rb +112 -0
- data/lib/omnibus/cli/build.rb +66 -0
- data/lib/omnibus/cli/cache.rb +60 -0
- data/lib/omnibus/config.rb +186 -0
- data/lib/omnibus/exceptions.rb +54 -0
- data/lib/omnibus/fetcher.rb +184 -0
- data/lib/omnibus/fetchers.rb +22 -0
- data/lib/omnibus/fetchers/git_fetcher.rb +212 -0
- data/lib/omnibus/fetchers/net_fetcher.rb +191 -0
- data/lib/omnibus/fetchers/path_fetcher.rb +65 -0
- data/lib/omnibus/fetchers/s3_cache_fetcher.rb +42 -0
- data/lib/omnibus/health_check.rb +260 -0
- data/lib/omnibus/library.rb +70 -0
- data/lib/omnibus/overrides.rb +69 -0
- data/lib/omnibus/project.rb +566 -0
- data/lib/omnibus/reports.rb +99 -0
- data/lib/omnibus/s3_cacher.rb +136 -0
- data/lib/omnibus/software.rb +430 -0
- data/lib/omnibus/templates/Berksfile.erb +3 -0
- data/lib/omnibus/templates/Gemfile.erb +4 -0
- data/lib/omnibus/templates/README.md.erb +102 -0
- data/lib/omnibus/templates/Vagrantfile.erb +95 -0
- data/lib/omnibus/templates/gitignore.erb +8 -0
- data/lib/omnibus/templates/omnibus.rb.example.erb +5 -0
- data/lib/omnibus/templates/package_scripts/makeselfinst.erb +27 -0
- data/lib/omnibus/templates/package_scripts/postinst.erb +17 -0
- data/lib/omnibus/templates/package_scripts/postrm.erb +9 -0
- data/lib/omnibus/templates/project.rb.erb +21 -0
- data/lib/omnibus/templates/software/c-example.rb.erb +42 -0
- data/lib/omnibus/templates/software/erlang-example.rb.erb +38 -0
- data/lib/omnibus/templates/software/ruby-example.rb.erb +24 -0
- data/lib/omnibus/util.rb +61 -0
- data/lib/omnibus/version.rb +20 -0
- data/omnibus.gemspec +34 -0
- data/spec/build_version_spec.rb +228 -0
- data/spec/data/overrides/bad_line.overrides +3 -0
- data/spec/data/overrides/good.overrides +5 -0
- data/spec/data/overrides/with_dupes.overrides +4 -0
- data/spec/data/software/erchef.rb +40 -0
- data/spec/overrides_spec.rb +114 -0
- data/spec/software_spec.rb +71 -0
- data/spec/spec_helper.rb +28 -0
- metadata +239 -0
@@ -0,0 +1,102 @@
|
|
1
|
+
# <%= config[:name] %> Omnibus project
|
2
|
+
|
3
|
+
This project creates full-stack platform-specific packages for
|
4
|
+
`<%= config[:name] %>`!
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
We'll assume you have Ruby 1.9+ and Bundler installed. First ensure all
|
9
|
+
required gems are installed and ready to use:
|
10
|
+
|
11
|
+
```shell
|
12
|
+
$ bundle install --binstubs
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
### Build
|
18
|
+
|
19
|
+
You create a platform-specific package using the `build project` command:
|
20
|
+
|
21
|
+
```shell
|
22
|
+
$ bin/omnibus build project <%= config[:name] %>
|
23
|
+
```
|
24
|
+
|
25
|
+
The platform/architecture type of the package created will match the platform
|
26
|
+
where the `build project` command is invoked. So running this command on say a
|
27
|
+
MacBook Pro will generate a Mac OS X specific package. After the build
|
28
|
+
completes packages will be available in `pkg/`.
|
29
|
+
|
30
|
+
### Clean
|
31
|
+
|
32
|
+
You can clean up all temporary files generated during the build process with
|
33
|
+
the `clean` command:
|
34
|
+
|
35
|
+
```shell
|
36
|
+
$ bin/omnibus clean
|
37
|
+
```
|
38
|
+
|
39
|
+
Adding the `--purge` purge option removes __ALL__ files generated during the
|
40
|
+
build including the project install directory (`/opt/<%= config[:name] %>`) and
|
41
|
+
the package cache directory (`/var/cache/omnibus/pkg`):
|
42
|
+
|
43
|
+
```shell
|
44
|
+
$ bin/omnibus clean --purge
|
45
|
+
```
|
46
|
+
|
47
|
+
### Help
|
48
|
+
|
49
|
+
Full help for the Omnibus command line interface can be accessed with the
|
50
|
+
`help` command:
|
51
|
+
|
52
|
+
```shell
|
53
|
+
$ bin/omnibus help
|
54
|
+
```
|
55
|
+
|
56
|
+
## Vagrant-based Virtualized Build Lab
|
57
|
+
|
58
|
+
Every Omnibus project ships will a project-specific
|
59
|
+
[Berksfile](http://berkshelf.com/) and [Vagrantfile](http://www.vagrantup.com/)
|
60
|
+
that will allow you to build your projects on the following platforms:
|
61
|
+
|
62
|
+
* CentOS 5 64-bit
|
63
|
+
* CentOS 6 64-bit
|
64
|
+
* Ubuntu 10.04 64-bit
|
65
|
+
* Ubuntu 11.04 64-bit
|
66
|
+
* Ubuntu 12.04 64-bit
|
67
|
+
|
68
|
+
Please note this build-lab is only meant to get you up and running quickly;
|
69
|
+
there's nothing inherent in Omnibus that restricts you to just building CentOS
|
70
|
+
or Ubuntu packages. See the Vagrantfile to add new platforms to your build lab.
|
71
|
+
|
72
|
+
The only requirements for standing up this virtualized build lab are:
|
73
|
+
|
74
|
+
* VirtualBox - native packages exist for most platforms and can be downloaded
|
75
|
+
from the [VirtualBox downloads page](https://www.virtualbox.org/wiki/Downloads).
|
76
|
+
* Vagrant 1.1+ - native packages exist for most platforms and can be downloaded
|
77
|
+
from the [Vagrant downloads page](http://downloads.vagrantup.com/).
|
78
|
+
|
79
|
+
The [berkshelf-vagrant](https://github.com/RiotGames/berkshelf-vagrant) and
|
80
|
+
[vagrant-omnibus](https://github.com/schisamo/vagrant-omnibus) Vagrant plugins
|
81
|
+
are also required and can be installed easily with the following commands:
|
82
|
+
|
83
|
+
```shell
|
84
|
+
$ vagrant plugin install berkshelf-vagrant
|
85
|
+
$ vagrant plugin install vagrant-omnibus
|
86
|
+
```
|
87
|
+
|
88
|
+
Once the pre-requisites are installed you can build your package across all
|
89
|
+
platforms with the following command:
|
90
|
+
|
91
|
+
```shell
|
92
|
+
$ vagrant up
|
93
|
+
```
|
94
|
+
|
95
|
+
If you would like to build a package for a single platform the command looks like this:
|
96
|
+
|
97
|
+
```shell
|
98
|
+
$ vagrant up PLATFORM
|
99
|
+
```
|
100
|
+
|
101
|
+
The complete list of valid platform names can be viewed with the
|
102
|
+
`vagrant status` command.
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
# vi: set ft=ruby :
|
3
|
+
|
4
|
+
require "vagrant"
|
5
|
+
|
6
|
+
if Vagrant::VERSION < "1.2.0"
|
7
|
+
raise "The Omnibus Build Lab is only compatible with Vagrant 1.2+"
|
8
|
+
end
|
9
|
+
|
10
|
+
host_project_path = File.expand_path("..", __FILE__)
|
11
|
+
guest_project_path = "/home/vagrant/#{File.basename(host_project_path)}"
|
12
|
+
project_name = "<%= config[:name] %>"
|
13
|
+
|
14
|
+
Vagrant.configure("2") do |config|
|
15
|
+
|
16
|
+
config.vm.hostname = "#{project_name}-omnibus-build-lab"
|
17
|
+
|
18
|
+
config.vm.define 'ubuntu-10.04' do |c|
|
19
|
+
c.berkshelf.berksfile_path = "./Berksfile"
|
20
|
+
c.vm.box = "opscode-ubuntu-10.04"
|
21
|
+
c.vm.box_url = "http://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-10.04_chef-11.2.0.box"
|
22
|
+
end
|
23
|
+
|
24
|
+
config.vm.define 'ubuntu-11.04' do |c|
|
25
|
+
c.berkshelf.berksfile_path = "./Berksfile"
|
26
|
+
c.vm.box = "opscode-ubuntu-11.04"
|
27
|
+
c.vm.box_url = "http://opscode-vm.s3.amazonaws.com/vagrant/boxes/opscode-ubuntu-11.04.box"
|
28
|
+
end
|
29
|
+
|
30
|
+
config.vm.define 'ubuntu-12.04' do |c|
|
31
|
+
c.berkshelf.berksfile_path = "./Berksfile"
|
32
|
+
c.vm.box = "canonical-ubuntu-12.04"
|
33
|
+
c.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box"
|
34
|
+
end
|
35
|
+
|
36
|
+
config.vm.define 'centos-5' do |c|
|
37
|
+
c.berkshelf.berksfile_path = "./Berksfile"
|
38
|
+
c.vm.box = "opscode-centos-5.8"
|
39
|
+
c.vm.box_url = "http://opscode-vm.s3.amazonaws.com/vagrant/opscode_centos-5.8_chef-11.2.0.box"
|
40
|
+
end
|
41
|
+
|
42
|
+
config.vm.define 'centos-6' do |c|
|
43
|
+
c.berkshelf.berksfile_path = "./Berksfile"
|
44
|
+
c.vm.box = "opscode-centos-6.3"
|
45
|
+
c.vm.box_url = "http://opscode-vm.s3.amazonaws.com/vagrant/opscode_centos-6.3_chef-11.2.0.box"
|
46
|
+
end
|
47
|
+
|
48
|
+
config.vm.provider :virtualbox do |vb|
|
49
|
+
# Give enough horsepower to build without taking all day.
|
50
|
+
vb.customize [
|
51
|
+
"modifyvm", :id,
|
52
|
+
"--memory", "1536",
|
53
|
+
"--cpus", "2"
|
54
|
+
]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Ensure a recent version of the Chef Omnibus packages are installed
|
58
|
+
config.omnibus.chef_version = :latest
|
59
|
+
|
60
|
+
# Enable the berkshelf-vagrant plugin
|
61
|
+
config.berkshelf.enabled = true
|
62
|
+
# The path to the Berksfile to use with Vagrant Berkshelf
|
63
|
+
config.berkshelf.berksfile_path = "./Berksfile"
|
64
|
+
|
65
|
+
config.ssh.max_tries = 40
|
66
|
+
config.ssh.timeout = 120
|
67
|
+
config.ssh.forward_agent = true
|
68
|
+
|
69
|
+
host_project_path = File.expand_path("..", __FILE__)
|
70
|
+
guest_project_path = "/home/vagrant/#{File.basename(host_project_path)}"
|
71
|
+
|
72
|
+
config.vm.synced_folder host_project_path, guest_project_path
|
73
|
+
|
74
|
+
# prepare VM to be an Omnibus builder
|
75
|
+
config.vm.provision :chef_solo do |chef|
|
76
|
+
chef.json = {
|
77
|
+
"omnibus" => {
|
78
|
+
"build_user" => "vagrant",
|
79
|
+
"build_dir" => guest_project_path,
|
80
|
+
"install_dir" => "/opt/#{project_name}"
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
chef.run_list = [
|
85
|
+
"recipe[omnibus::default]"
|
86
|
+
]
|
87
|
+
end
|
88
|
+
|
89
|
+
config.vm.provision :shell, :inline => <<-OMNIBUS_BUILD
|
90
|
+
export PATH=/usr/local/bin:$PATH
|
91
|
+
cd #{guest_project_path}
|
92
|
+
su vagrant -c "bundle install --binstubs"
|
93
|
+
su vagrant -c "bin/omnibus build project #{project_name}"
|
94
|
+
OMNIBUS_BUILD
|
95
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# Install a full <%= config[:name] %>
|
4
|
+
#
|
5
|
+
|
6
|
+
PROGNAME=`basename $0`
|
7
|
+
INSTALLER_DIR=`dirname $0`
|
8
|
+
DEST_DIR=<%= config[:install_path] %>
|
9
|
+
CONFIG_DIR=/etc/<%= config[:name] %>
|
10
|
+
USAGE="usage: $0"
|
11
|
+
|
12
|
+
error_exit()
|
13
|
+
{
|
14
|
+
echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
|
15
|
+
exit 1
|
16
|
+
}
|
17
|
+
|
18
|
+
# move the actual files into place
|
19
|
+
rm -rf $DEST_DIR/* || error_exit "Cannot remove contents of $DEST_DIR"
|
20
|
+
mkdir -p $DEST_DIR || error_exit "Cannot create $DEST_DIR"
|
21
|
+
cp -R $INSTALLER_DIR $DEST_DIR || error_exit "Cannot install to $DEST_DIR"
|
22
|
+
rm -f $DEST_DIR/$PROGNAME
|
23
|
+
|
24
|
+
# You may want to symlink your packages bin files into /usr/bin
|
25
|
+
# ln -sf $DEST_DIR/bin/<%= config[:name] %> /usr/bin || error_exit "Cannot link <%= config[:name] %> to /usr/bin"
|
26
|
+
|
27
|
+
exit 0
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# Perform necessary <%= config[:name] %> setup steps
|
4
|
+
# after package is installed.
|
5
|
+
#
|
6
|
+
|
7
|
+
PROGNAME=$(basename $0)
|
8
|
+
|
9
|
+
function error_exit
|
10
|
+
{
|
11
|
+
echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
|
12
|
+
exit 1
|
13
|
+
}
|
14
|
+
|
15
|
+
echo "Thank you for installing <%= config[:name] %>!"
|
16
|
+
|
17
|
+
exit 0
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
name "<%= config[:name] %>"
|
3
|
+
maintainer "CHANGE ME"
|
4
|
+
homepage "CHANGEME.com"
|
5
|
+
|
6
|
+
replaces "<%= config[:name] %>"
|
7
|
+
install_path "<%= config[:install_path] %>"
|
8
|
+
build_version Omnibus::BuildVersion.new.semver
|
9
|
+
build_iteration 1
|
10
|
+
|
11
|
+
# creates required build directories
|
12
|
+
dependency "preparation"
|
13
|
+
|
14
|
+
# <%= config[:name] %> dependencies/components
|
15
|
+
# dependency "somedep"
|
16
|
+
|
17
|
+
# version manifest file
|
18
|
+
dependency "version-manifest"
|
19
|
+
|
20
|
+
exclude "\.git*"
|
21
|
+
exclude "bundler\/git"
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# This is an example software definition for a C project.
|
2
|
+
#
|
3
|
+
# Lots of software definitions for popular open source software
|
4
|
+
# already exist in `opscode-omnibus`:
|
5
|
+
#
|
6
|
+
# https://github.com/opscode/omnibus-software/tree/master/config/software
|
7
|
+
#
|
8
|
+
name "c-example"
|
9
|
+
version "1.0.0"
|
10
|
+
|
11
|
+
dependency "zlib"
|
12
|
+
dependency "openssl"
|
13
|
+
|
14
|
+
source :url => "http://itchy.neckbeard.se/download/c-example-1.0.0.tar.gz",
|
15
|
+
:md5 => "8e23151f569fb54afef093ac0695077d"
|
16
|
+
|
17
|
+
relative_path 'c-example-1.0.0'
|
18
|
+
|
19
|
+
env = {
|
20
|
+
"LDFLAGS" => "-L#{install_dir}/embedded/lib -I#{install_dir}/embedded/include",
|
21
|
+
"CFLAGS" => "-L#{install_dir}/embedded/lib -I#{install_dir}/embedded/include",
|
22
|
+
"LD_RUN_PATH" => "#{install_dir}/embedded/lib"
|
23
|
+
}
|
24
|
+
|
25
|
+
build do
|
26
|
+
command ["./configure",
|
27
|
+
"--prefix=#{install_dir}/embedded",
|
28
|
+
"--disable-debug",
|
29
|
+
"--enable-optimize",
|
30
|
+
"--disable-ldap",
|
31
|
+
"--disable-ldaps",
|
32
|
+
"--disable-rtsp",
|
33
|
+
"--enable-proxy",
|
34
|
+
"--disable-dependency-tracking",
|
35
|
+
"--enable-ipv6",
|
36
|
+
"--without-libidn",
|
37
|
+
"--with-ssl=#{install_dir}/embedded",
|
38
|
+
"--with-zlib=#{install_dir}/embedded"].join(" "), :env => env
|
39
|
+
|
40
|
+
command "make -j #{max_build_jobs}", :env => env
|
41
|
+
command "make install"
|
42
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# This is an example software definition for an Erlang project.
|
2
|
+
#
|
3
|
+
# Lots of software definitions for popular open source software
|
4
|
+
# already exist in `opscode-omnibus`:
|
5
|
+
#
|
6
|
+
# https://github.com/opscode/omnibus-software/tree/master/config/software
|
7
|
+
#
|
8
|
+
name "erlang-example"
|
9
|
+
version "1.0.0"
|
10
|
+
|
11
|
+
dependency "erlang"
|
12
|
+
dependency "rebar"
|
13
|
+
dependency "rsync"
|
14
|
+
|
15
|
+
source :git => "git://github.com/example/erlang.git"
|
16
|
+
|
17
|
+
relative_path "erlang-example"
|
18
|
+
|
19
|
+
env = {
|
20
|
+
"PATH" => "#{install_dir}/embedded/bin:#{ENV["PATH"]}",
|
21
|
+
"LDFLAGS" => "-L#{install_dir}/embedded/lib -I#{install_dir}/embedded/include",
|
22
|
+
"CFLAGS" => "-L#{install_dir}/embedded/lib -I#{install_dir}/embedded/include",
|
23
|
+
"LD_RUN_PATH" => "#{install_dir}/embedded/lib"
|
24
|
+
}
|
25
|
+
|
26
|
+
build do
|
27
|
+
command "make distclean", :env => env
|
28
|
+
command "make rel", :env => env
|
29
|
+
command "mkdir -p #{install_dir}/embedded/service/example-erlang"
|
30
|
+
command ["#{install_dir}/embedded/bin/rsync",
|
31
|
+
"-a",
|
32
|
+
"--delete",
|
33
|
+
"--exclude=.git/***",
|
34
|
+
"--exclude=.gitignore",
|
35
|
+
"./rel/erlang-example/",
|
36
|
+
"#{install_dir}/embedded/service/erlang-example/"].join(" ")
|
37
|
+
command "rm -rf #{install_dir}/embedded/service/erlang-example/log"
|
38
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This is an example software definition for a Ruby project.
|
2
|
+
#
|
3
|
+
# Lots of software definitions for popular open source software
|
4
|
+
# already exist in `opscode-omnibus`:
|
5
|
+
#
|
6
|
+
# https://github.com/opscode/omnibus-software/tree/master/config/software
|
7
|
+
#
|
8
|
+
name "ruby-example"
|
9
|
+
version "1.0.0"
|
10
|
+
|
11
|
+
dependency "ruby"
|
12
|
+
dependency "rubygems"
|
13
|
+
dependency "bundler"
|
14
|
+
dependency "rsync"
|
15
|
+
|
16
|
+
source :git => "git://github.com/example/ruby.git"
|
17
|
+
|
18
|
+
relative_path "ruby-example"
|
19
|
+
|
20
|
+
build do
|
21
|
+
bundle "install --path=#{install_dir}/embedded/service/gem"
|
22
|
+
command "mkdir -p #{install_dir}/embedded/service/ruby-example"
|
23
|
+
command "#{install_dir}/embedded/bin/rsync -a --delete --exclude=.git/*** --exclude=.gitignore ./ #{install_dir}/embedded/service/ruby-example/"
|
24
|
+
end
|
data/lib/omnibus/util.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Seth Chisamore (<schisamo@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'mixlib/shellout'
|
20
|
+
|
21
|
+
module Omnibus
|
22
|
+
#
|
23
|
+
# @author Seth Chisamore (<schisamo@opscode.com>)
|
24
|
+
#
|
25
|
+
module Util
|
26
|
+
# Shells out and runs +command+.
|
27
|
+
#
|
28
|
+
# @param command [String]
|
29
|
+
# @param opts [Hash] the options passed to the initializer of the
|
30
|
+
# +Mixlib::ShellOut+ instance.
|
31
|
+
# @return [Mixlib::ShellOut] the underlying +Mixlib::ShellOut+ instance
|
32
|
+
# which which has +stdout+, +stderr+, +status+, and +exitstatus+
|
33
|
+
# populated with results of the command.
|
34
|
+
#
|
35
|
+
def shellout(command, opts={})
|
36
|
+
STDOUT.sync = true
|
37
|
+
default_options = {
|
38
|
+
:live_stream => STDOUT,
|
39
|
+
:timeout => 7200, # 2 hours
|
40
|
+
:environment => {}
|
41
|
+
}
|
42
|
+
cmd = Mixlib::ShellOut.new(command, default_options.merge(opts))
|
43
|
+
cmd.run_command
|
44
|
+
cmd
|
45
|
+
end
|
46
|
+
|
47
|
+
# Similar to +shellout+ method except it raises an exception if the
|
48
|
+
# command fails.
|
49
|
+
#
|
50
|
+
# @see #shellout
|
51
|
+
#
|
52
|
+
# @raise [Mixlib::ShellOut::ShellCommandFailed] if +exitstatus+ is not in
|
53
|
+
# the list of +valid_exit_codes+.
|
54
|
+
#
|
55
|
+
def shellout!(command, opts={})
|
56
|
+
cmd = shellout(command, opts)
|
57
|
+
cmd.error!
|
58
|
+
cmd
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|