engineyard-local 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +23 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +62 -0
- data/README.md +115 -0
- data/Rakefile +15 -0
- data/bin/ey-local +4 -0
- data/config/dna.json +206 -0
- data/config/locales/en.yml +57 -0
- data/config/settings.yml +18 -0
- data/config/solo.rb +7 -0
- data/engineyard-local.gemspec +24 -0
- data/install/deb/README.md +72 -0
- data/install/deb/Rakefile +157 -0
- data/install/deb/Vagrantfile +10 -0
- data/install/deb/install.sh +32 -0
- data/install/osx/README.md +23 -0
- data/install/osx/Rakefile +39 -0
- data/install/osx/engineyard-local/engineyard-local.pkgproj +812 -0
- data/install/osx/images/eylocal_installer.png +0 -0
- data/install/osx/scripts/log.sh +3 -0
- data/install/osx/scripts/postinstall +57 -0
- data/install/osx/scripts/rvm_install.sh +34 -0
- data/lib/engineyard-local.rb +42 -0
- data/lib/engineyard-local/command.rb +65 -0
- data/lib/engineyard-local/command/base.rb +15 -0
- data/lib/engineyard-local/command/exec.rb +11 -0
- data/lib/engineyard-local/command/group.rb +86 -0
- data/lib/engineyard-local/command/helpers.rb +23 -0
- data/lib/engineyard-local/command/list.rb +29 -0
- data/lib/engineyard-local/command/rails.rb +19 -0
- data/lib/engineyard-local/command/up.rb +87 -0
- data/lib/engineyard-local/command/vagrant_action.rb +11 -0
- data/lib/engineyard-local/errors.rb +10 -0
- data/lib/engineyard-local/middleware.rb +28 -0
- data/lib/engineyard-local/middleware/bundle.rb +40 -0
- data/lib/engineyard-local/middleware/chef.rb +44 -0
- data/lib/engineyard-local/middleware/default_provisioner.rb +34 -0
- data/lib/engineyard-local/middleware/dna.rb +80 -0
- data/lib/engineyard-local/middleware/exec.rb +27 -0
- data/lib/engineyard-local/middleware/helpers.rb +4 -0
- data/lib/engineyard-local/middleware/helpers/executable.rb +27 -0
- data/lib/engineyard-local/middleware/helpers/network.rb +20 -0
- data/lib/engineyard-local/middleware/helpers/rvm.rb +37 -0
- data/lib/engineyard-local/middleware/helpers/uploadable.rb +14 -0
- data/lib/engineyard-local/middleware/network.rb +64 -0
- data/lib/engineyard-local/middleware/rails.rb +3 -0
- data/lib/engineyard-local/middleware/rails/command.rb +31 -0
- data/lib/engineyard-local/middleware/rails/db.rb +36 -0
- data/lib/engineyard-local/middleware/rails/install.rb +36 -0
- data/lib/engineyard-local/middleware/rails/new.rb +31 -0
- data/lib/engineyard-local/middleware/tag.rb +33 -0
- data/lib/engineyard-local/ui.rb +33 -0
- data/lib/engineyard-local/version.rb +5 -0
- data/lib/engineyard-local/virtualbox.rb +35 -0
- data/lib/vagrant_init.rb +1 -0
- data/test/engineyard-local/command/group_test.rb +34 -0
- data/test/engineyard-local/command/up_test.rb +70 -0
- data/test/engineyard-local/command_test.rb +40 -0
- data/test/engineyard-local/middelware/bundle_test.rb +32 -0
- data/test/engineyard-local/middelware/default_provisioner_test.rb +35 -0
- data/test/engineyard-local/middelware/exec_test.rb +19 -0
- data/test/engineyard-local/middelware/network_test.rb +94 -0
- data/test/engineyard-local/middelware/rails/command_test.rb +24 -0
- data/test/engineyard-local/middelware/rails/db_test.rb +23 -0
- data/test/engineyard-local/middelware/rails/install_test.rb +24 -0
- data/test/engineyard-local/ui_test.rb +22 -0
- data/test/engineyard-local/virtualbox_test.rb +34 -0
- data/test/integration/up_test.rb +28 -0
- data/test/test_helper.rb +78 -0
- metadata +178 -0
Binary file
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# pull in our logging
|
4
|
+
source log.sh
|
5
|
+
|
6
|
+
# the assumed install directory for the package. This should be provided
|
7
|
+
# as a setting from the ruby project by including a settings text file
|
8
|
+
# in the installation package
|
9
|
+
install_dir="/tmp/engineyard-local-installer"
|
10
|
+
|
11
|
+
# TODO take the set and loop over it to run the install for each
|
12
|
+
# logged in user
|
13
|
+
current_user=`users | tail -1`
|
14
|
+
|
15
|
+
# it would be nice to tie the directory to some variable
|
16
|
+
# determined by the installer
|
17
|
+
gems=`ls $install_dir/*.gem | xargs`
|
18
|
+
|
19
|
+
# the name of the base box to be created, again would be nice
|
20
|
+
# to include an installer file with these settings
|
21
|
+
box_name="ey-gentoo-rack"
|
22
|
+
|
23
|
+
# run the current command with a login shell as the current logged in user
|
24
|
+
function as_current_user {
|
25
|
+
su $current_user -l -c "$1"
|
26
|
+
}
|
27
|
+
|
28
|
+
# run the post install scripts as the logged in user
|
29
|
+
# --login is required to make sure that rvm is available when
|
30
|
+
# installed and added to .bash_profile
|
31
|
+
#
|
32
|
+
# If they aren't though RVM starts into an infinite
|
33
|
+
# loop because while the binary is present the scripts
|
34
|
+
# directory isn't available in $HOME which may be /var/root
|
35
|
+
# if run as `sudo -u $current_user`. That is, it thinks
|
36
|
+
# there's no user install and then attempts to find the
|
37
|
+
# root install despite the fact that its running the user install
|
38
|
+
# script. After not finding one it proceeds to
|
39
|
+
# execute the same command again and again.
|
40
|
+
as_current_user "./rvm_install.sh $gems"
|
41
|
+
|
42
|
+
# if rvm_install fails install to the system gems
|
43
|
+
if [[ $? -gt 0 ]]; then
|
44
|
+
log "Installing gems to system ruby ..."
|
45
|
+
sudo gem install $gems
|
46
|
+
fi
|
47
|
+
|
48
|
+
log "Gem install complete"
|
49
|
+
as_current_user "ey-local box list | grep $box_name"
|
50
|
+
|
51
|
+
# install the packaged box for use with ey-local up
|
52
|
+
if [[ $? -gt 0 ]]; then
|
53
|
+
log "Installing default box $box_name ..."
|
54
|
+
as_current_user "ey-local box add $box_name $install_dir/package.box"
|
55
|
+
else
|
56
|
+
log "$box_name already installed ..."
|
57
|
+
fi
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# if rvm is not installed exit with an error to signal
|
2
|
+
# parent script that it needs to take action accordingly
|
3
|
+
if [[ ! `which rvm` ]]; then
|
4
|
+
exit 1;
|
5
|
+
fi
|
6
|
+
|
7
|
+
# pull in our syslog loggerGH
|
8
|
+
source log.sh
|
9
|
+
|
10
|
+
# rvm has a habit of making its output nigh unparsable.
|
11
|
+
# Here we have to strip the possible default ruby notation
|
12
|
+
# of `=>` incase it's used so that our results are consistent
|
13
|
+
# and can be run through awk to pull out the ruby
|
14
|
+
#
|
15
|
+
# possible `rvm list` output handled here:
|
16
|
+
# => ruby-version-patch
|
17
|
+
# ruby-version-patch
|
18
|
+
default_ruby=`rvm list default | sed 's/=>/ /' | grep '^ ' | awk '{print \$1}'`
|
19
|
+
current_ruby=`rvm current`
|
20
|
+
|
21
|
+
# if the user has a default or current ruby install to one or the other
|
22
|
+
# otherwise we can't know where it should be installed for rvm
|
23
|
+
if [[ $default_ruby ]]; then
|
24
|
+
log "Installing gems to the default ruby: $default_ruby@global ..."
|
25
|
+
rvm use $default_ruby@global
|
26
|
+
gem install $@ --no-ri --no-rdoc
|
27
|
+
elif [[ $current_ruby ]]; then
|
28
|
+
log "Installing gems to the current ruby: $current_ruby@global ..."
|
29
|
+
rvm use $current_ruby@global
|
30
|
+
gem install $@ --no-ri --no-rdoc
|
31
|
+
else
|
32
|
+
log "No rvm default or current ruby detected ..."
|
33
|
+
exit 1
|
34
|
+
fi
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "vagrant"
|
2
|
+
require "pathname"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
# TODO settings object/management will be needed shortly
|
6
|
+
module Engineyard
|
7
|
+
module Local
|
8
|
+
def self.project_root
|
9
|
+
@project_root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.project_file(path)
|
13
|
+
self.project_root + path
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.config
|
17
|
+
@config ||= load_config_yaml("settings.yml")
|
18
|
+
end
|
19
|
+
|
20
|
+
# default to en until something more inteligent is required
|
21
|
+
# NOTE all locale information is contained in a single yaml
|
22
|
+
# file in anticipation of relatively minimal use
|
23
|
+
def self.locales
|
24
|
+
@locales ||= load_config_yaml("locales/en.yml")
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.load_config_yaml(config_rel_path)
|
28
|
+
yaml_file = File.expand_path("config/#{config_rel_path}", self.project_root)
|
29
|
+
YAML.load_file(yaml_file)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require "engineyard-local/virtualbox"
|
35
|
+
require "engineyard-local/middleware/helpers"
|
36
|
+
require "engineyard-local/middleware"
|
37
|
+
require "engineyard-local/ui"
|
38
|
+
require "engineyard-local/version"
|
39
|
+
require "engineyard-local/command"
|
40
|
+
require "engineyard-local/errors"
|
41
|
+
|
42
|
+
I18n.load_path << Engineyard::Local.project_file("config/locales/en.yml")
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Engineyard
|
2
|
+
module Local
|
3
|
+
module Command
|
4
|
+
def self.all
|
5
|
+
Engineyard::Local.locales[:commands].keys.map { |cmd| cmd.to_s }
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.passthrough
|
9
|
+
Engineyard::Local.config[:commands][:passthrough]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.dispatch(args)
|
13
|
+
Group.env = env = vagrant_env(args)
|
14
|
+
|
15
|
+
# if the flags need to be sent through on the command, avoid Thor
|
16
|
+
# otherwise start up Thor command line handling. Otherwise notify wrapper
|
17
|
+
# that nothing was dispatched.
|
18
|
+
if args.include?("-v") || args.include?("--version")
|
19
|
+
env.ui.info Engineyard::Local::VERSION, :prefix => false
|
20
|
+
elsif passthrough.include?(args.first)
|
21
|
+
cmd = Group.new(args, [], {})
|
22
|
+
cmd.send(args.first.to_sym, *args[1, args.length])
|
23
|
+
elsif all.include?(args.first) || args.length == 0
|
24
|
+
Group.start(args)
|
25
|
+
else
|
26
|
+
vagrant_env(args).cli(args)
|
27
|
+
end
|
28
|
+
rescue Vagrant::Errors::VagrantError => e
|
29
|
+
# TODO move to Vagrant Environment ui error
|
30
|
+
env.ui.error e.message if e.message
|
31
|
+
exit e.status_code if e.respond_to?(:status_code)
|
32
|
+
exit 999
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.vagrant_env(args)
|
36
|
+
opts = {}
|
37
|
+
|
38
|
+
# setup the vagrant env properly for the commands to run
|
39
|
+
if args.include?("--no-color") || !$stdout.tty? || !Vagrant::Util::Platform.terminal_supports_colors?
|
40
|
+
# Delete the argument from the list so that it doesn't cause any
|
41
|
+
# invalid arguments down the road.
|
42
|
+
args.delete("--no-color")
|
43
|
+
opts[:ui_class] = UI::Basic
|
44
|
+
else
|
45
|
+
opts[:ui_class] = UI::Colored
|
46
|
+
end
|
47
|
+
|
48
|
+
new_env = Vagrant::Environment.new(opts)
|
49
|
+
new_env.load!
|
50
|
+
new_env
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
require "thor"
|
57
|
+
# TODO autoload
|
58
|
+
require "engineyard-local/command/helpers"
|
59
|
+
require "engineyard-local/command/base"
|
60
|
+
require "engineyard-local/command/group"
|
61
|
+
require "engineyard-local/command/vagrant_action"
|
62
|
+
require "engineyard-local/command/exec"
|
63
|
+
require "engineyard-local/command/list"
|
64
|
+
require "engineyard-local/command/rails"
|
65
|
+
require "engineyard-local/command/up"
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Engineyard
|
2
|
+
module Local
|
3
|
+
module Command
|
4
|
+
# TODO move to purely vagrant command based setup
|
5
|
+
class Group < Thor
|
6
|
+
# TODO this class level env crap will go away once
|
7
|
+
# these commands are moved out of thor to Vagrant commands
|
8
|
+
def self.env=(env)
|
9
|
+
@@env = env
|
10
|
+
end
|
11
|
+
|
12
|
+
no_tasks do
|
13
|
+
def env
|
14
|
+
@@env
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# NOTE this is generally a bad idea as it might break between Vagrant versions
|
19
|
+
# the alternate is to monkey with the output (we're attempting to own the ux)
|
20
|
+
# from Thor where ey-local remains a Vagrant plugin. Either way the library
|
21
|
+
# is reaching into deps and using their internals, Vagrant is preferred here
|
22
|
+
# because the author has more experience with said internals
|
23
|
+
# TODO clean up the vagrant command environment init
|
24
|
+
def initialize(*args)
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.command_info
|
29
|
+
Local.locales[:commands]
|
30
|
+
end
|
31
|
+
|
32
|
+
# register the command group eylocal
|
33
|
+
# register(*command_info[:eylocal])
|
34
|
+
|
35
|
+
# make sure rails is installed, run rails commands in the guest project share
|
36
|
+
method_option "version", :type => :string, :default => nil
|
37
|
+
desc(*command_info[:rails])
|
38
|
+
def rails(*args)
|
39
|
+
Command::Rails.new(env, options).exec(*args)
|
40
|
+
end
|
41
|
+
|
42
|
+
desc(*command_info[:exec])
|
43
|
+
def exec(*args)
|
44
|
+
Command::Exec.new(env, options).exec(args)
|
45
|
+
end
|
46
|
+
|
47
|
+
# streamlining of Vagrant up
|
48
|
+
method_option "no-bundle", :type => :boolean, :default => nil
|
49
|
+
method_option "no-db-setup", :type => :boolean, :default => nil
|
50
|
+
method_option "silent", :type => :boolean, :default => nil
|
51
|
+
desc(*command_info[:up])
|
52
|
+
def up(*args)
|
53
|
+
Command::Up.new(env, options).exec(*args)
|
54
|
+
end
|
55
|
+
|
56
|
+
method_option "environment", :type => :string, :default => "development"
|
57
|
+
method_option "lines", :type => :numeric, :default => 100
|
58
|
+
desc(*command_info[:log])
|
59
|
+
def log(*args)
|
60
|
+
cmd_args = ["tail -#{options["lines"]} log/#{options["environment"]}.log"]
|
61
|
+
Command::Exec.new(env, options).exec(cmd_args)
|
62
|
+
end
|
63
|
+
|
64
|
+
method_option "format", :type => :string, :default => "short"
|
65
|
+
desc(*command_info[:list])
|
66
|
+
def list
|
67
|
+
if options["format"] && !["short", "full"].include?(options["format"])
|
68
|
+
help("list")
|
69
|
+
else
|
70
|
+
Command::List.new(env, options).exec(options)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
desc(*command_info[:start])
|
75
|
+
def start
|
76
|
+
Command::VagrantAction.new(env, options).exec(:resume)
|
77
|
+
end
|
78
|
+
|
79
|
+
desc(*command_info[:stop])
|
80
|
+
def stop
|
81
|
+
Command::VagrantAction.new(env, options).exec(:suspend)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Engineyard
|
2
|
+
module Local
|
3
|
+
module Command
|
4
|
+
module Helpers
|
5
|
+
def run(middleware, opts={}, &block)
|
6
|
+
with_target_vms do |vm|
|
7
|
+
opts = merge_run_options(vm, opts)
|
8
|
+
vm.env.action_runner.run(middleware, opts)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# TODO borrowed entirely from vagrant, running outside it's command
|
13
|
+
# structure is causing issues that need remedy
|
14
|
+
def merge_run_options(vm, opts={})
|
15
|
+
{
|
16
|
+
:vm => vm,
|
17
|
+
:ui => vm.env.ui.dup
|
18
|
+
}.merge(opts || {})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Engineyard
|
2
|
+
module Local
|
3
|
+
module Command
|
4
|
+
class List < Base
|
5
|
+
def exec(options)
|
6
|
+
Virtualbox.uuid_map.each do |name, uuid|
|
7
|
+
project_root = Virtualbox.extra_data(uuid, Local.config[:managed_vm_key])
|
8
|
+
|
9
|
+
if project_root
|
10
|
+
# move the uuid and project root to the front of the output
|
11
|
+
# for easier cutting since it's less likely to have spaces
|
12
|
+
env.ui.info format(uuid, project_root, name), :prefix => false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def format(uuid, project_root, name)
|
18
|
+
result = "#{uuid} #{project_root}"
|
19
|
+
|
20
|
+
if @options[:format] == "full"
|
21
|
+
"#{result} #{name}"
|
22
|
+
else
|
23
|
+
result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Engineyard
|
2
|
+
module Local
|
3
|
+
module Command
|
4
|
+
class Rails < Base
|
5
|
+
def exec(*command_args)
|
6
|
+
scoped_options = options
|
7
|
+
|
8
|
+
stack = Vagrant::Action::Builder.new do
|
9
|
+
use Middleware::Rails::Install, "eylocal.rails.version" => scoped_options["version"]
|
10
|
+
use Middleware::Rails::Command, "eylocal.rails.command_args" => command_args
|
11
|
+
end
|
12
|
+
|
13
|
+
run stack
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Engineyard
|
2
|
+
module Local
|
3
|
+
module Command
|
4
|
+
class Up < Base
|
5
|
+
def box_defaults
|
6
|
+
Local.config[:box_defaults]
|
7
|
+
end
|
8
|
+
|
9
|
+
def box_exists?(name)
|
10
|
+
env.boxes.map { |box| box.name }.include?(name)
|
11
|
+
end
|
12
|
+
|
13
|
+
# convention based streamlining of Vagrant's up
|
14
|
+
def exec(name=box_defaults[:name], uri=box_uri)
|
15
|
+
if box_exists?(name)
|
16
|
+
env.ui.warn(I18n.t("eylocal.up.box_exists", :name => name))
|
17
|
+
else
|
18
|
+
env.cli("box", "add", name, uri)
|
19
|
+
end
|
20
|
+
|
21
|
+
# if a Vagrant file does NOT exist create one
|
22
|
+
if env.root_path.nil?
|
23
|
+
env.cli("init", name)
|
24
|
+
end
|
25
|
+
|
26
|
+
# resets vagrant root path so that it can detect the
|
27
|
+
# newly initialized Vagrantfile, and the newly added box
|
28
|
+
# TODO submit alternate reset of root path to Vagrant
|
29
|
+
env.send(:remove_instance_variable, :@root_path)
|
30
|
+
env.load_config!
|
31
|
+
env.boxes.reload!
|
32
|
+
|
33
|
+
env.ui.info(I18n.t("eylocal.up.root_path", :root_path => env.root_path))
|
34
|
+
if File.expand_path(env.root_path) != File.expand_path(Dir.pwd)
|
35
|
+
env.ui.info(I18n.t("eylocal.up.root_path_instructions", :root_path => env.root_path, :pwd => Dir.pwd))
|
36
|
+
end
|
37
|
+
|
38
|
+
# don't build a box if its already built
|
39
|
+
with_target_vms do |vm|
|
40
|
+
if vm.created?
|
41
|
+
env.ui.info I18n.t("vagrant.commands.up.vm_created")
|
42
|
+
else
|
43
|
+
up = Vagrant.actions.get(:up)
|
44
|
+
|
45
|
+
# insert the tag before the box is in a state where it can't be saved eg running
|
46
|
+
up.insert_before(Vagrant::Action::VM::CheckGuestAdditions, Middleware::Tag)
|
47
|
+
up.insert_before(Vagrant::Action::VM::CheckGuestAdditions, Middleware::Network, @options)
|
48
|
+
|
49
|
+
opts = merge_run_options(vm)
|
50
|
+
vm.env.action_runner.run(up, opts)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# finish the box setup
|
55
|
+
run setup_stack(options)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# prefer the the base box included with the installer if it exists
|
61
|
+
# otherwise use the default downloadable box
|
62
|
+
def box_uri
|
63
|
+
default_path = Engineyard::Local.project_root + "default.box"
|
64
|
+
|
65
|
+
if File.exists?(default_path)
|
66
|
+
# to_s required here as the path will be scanned for http
|
67
|
+
# by Vagrant
|
68
|
+
default_path.to_s
|
69
|
+
else
|
70
|
+
box_defaults[:uri]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# install the application bundle and create/migrate the database
|
75
|
+
# TODO check for the database.yml and fail gracefully
|
76
|
+
def setup_stack(options)
|
77
|
+
Vagrant::Action::Builder.new do
|
78
|
+
use Middleware::DNA unless options["no-dna"]
|
79
|
+
use Middleware::Chef unless options["no-chef"]
|
80
|
+
use Middleware::Bundle unless options["no-bundle"]
|
81
|
+
use Middleware::Rails::DB unless options["no-db-setup"]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|