ober 0.0.2
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.
- data/Gemfile +4 -0
- data/Gemfile.lock +18 -0
- data/LICENSE +23 -0
- data/README +15 -0
- data/bin/ober +6 -0
- data/doc/sample.rb +13 -0
- data/lib/ober/application.rb +21 -0
- data/lib/ober/cli.rb +17 -0
- data/lib/ober/configuration.rb +79 -0
- data/lib/ober/installer.rb +83 -0
- data/lib/ober/runner/rvm.rb +50 -0
- data/lib/ober/runner.rb +38 -0
- data/lib/ober/version.rb +3 -0
- data/lib/ober.rb +1 -0
- metadata +96 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
Copyright (c) 2013 Kaspar Schiess
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to deal in the Software without
|
7
|
+
restriction, including without limitation the rights to use,
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the
|
10
|
+
Software is furnished to do so, subject to the following
|
11
|
+
conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
18
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
20
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
21
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
23
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
ober - a small application installer for Ruby
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
|
6
|
+
...
|
7
|
+
|
8
|
+
STATUS
|
9
|
+
|
10
|
+
This is early alpha. Where applications do what one programmer wants, not
|
11
|
+
what other programmers want.
|
12
|
+
|
13
|
+
LICENSE
|
14
|
+
|
15
|
+
see LICENSE file, (c) 2013 Kaspar Schiess
|
data/bin/ober
ADDED
data/doc/sample.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
require 'ober/configuration'
|
3
|
+
require 'ober/installer'
|
4
|
+
|
5
|
+
module Ober
|
6
|
+
# The main application class, presents all operations as methods and
|
7
|
+
# has no connection to the CLI interface.
|
8
|
+
#
|
9
|
+
class Application
|
10
|
+
def install env
|
11
|
+
config = read_configuration
|
12
|
+
environment = config.environment(env)
|
13
|
+
Installer.new(environment).install
|
14
|
+
end
|
15
|
+
|
16
|
+
def read_configuration
|
17
|
+
source = File.read('ober_menu.rb')
|
18
|
+
Configuration.parse(source, 'ober_menu.rb')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ober/cli.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
require 'clamp'
|
3
|
+
require 'ober/application'
|
4
|
+
|
5
|
+
module Ober
|
6
|
+
class CLI < Clamp::Command
|
7
|
+
subcommand('install',
|
8
|
+
"Installs applications from ENV to this machine.") do
|
9
|
+
|
10
|
+
parameter 'ENV', 'environment to install'
|
11
|
+
|
12
|
+
def execute
|
13
|
+
Application.new.install(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Ober
|
2
|
+
|
3
|
+
# Ober configuration, which is read from a file called 'ober_menu' or
|
4
|
+
# from stdin. The configuration is a Ruby DSL. Check out child classes
|
5
|
+
# of the configuration for understanding the DSL.
|
6
|
+
#
|
7
|
+
class Configuration
|
8
|
+
# Largest context of evaluation. This is mostly going to be the file
|
9
|
+
# scope.
|
10
|
+
#
|
11
|
+
class Source
|
12
|
+
def initialize config
|
13
|
+
@config = config
|
14
|
+
end
|
15
|
+
|
16
|
+
def environment env, &block
|
17
|
+
@config.environment(env).instance_eval(&block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# A server environment.
|
22
|
+
#
|
23
|
+
class Environment
|
24
|
+
def initialize name
|
25
|
+
@applications = Hash.new { |h,k| h[k] = Application.new(k) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def app name, &block
|
29
|
+
@applications[name].instance_eval(&block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def apps
|
33
|
+
@applications.values
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# An application that is installed.
|
38
|
+
#
|
39
|
+
class Application
|
40
|
+
attr_reader :name
|
41
|
+
|
42
|
+
def initialize name
|
43
|
+
@name = name
|
44
|
+
end
|
45
|
+
|
46
|
+
def root path=nil
|
47
|
+
@root ||= path
|
48
|
+
end
|
49
|
+
|
50
|
+
def rvm version=nil
|
51
|
+
@rvm ||= version
|
52
|
+
end
|
53
|
+
|
54
|
+
def git url=nil, opts={}
|
55
|
+
@git ||= [url, opts]
|
56
|
+
end
|
57
|
+
|
58
|
+
def user name=nil
|
59
|
+
@user ||= name
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.parse *args
|
64
|
+
new.tap { |o| o.parse(*args) }
|
65
|
+
end
|
66
|
+
def parse source, file_name
|
67
|
+
context = Source.new(self)
|
68
|
+
context.instance_eval { binding.eval(source, file_name) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def initialize
|
72
|
+
@environments = Hash.new { |h,k| h[k] = Environment.new(k) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def environment env
|
76
|
+
@environments[env.to_sym]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
require 'fileutils'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
require 'ober/runner'
|
6
|
+
require 'ober/runner/rvm'
|
7
|
+
|
8
|
+
module Ober
|
9
|
+
class Installer
|
10
|
+
def initialize environment
|
11
|
+
@environment = environment
|
12
|
+
end
|
13
|
+
|
14
|
+
def install
|
15
|
+
@environment.apps.each do |app|
|
16
|
+
puts "Installing app #{app.name}..."
|
17
|
+
install_app app
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def runner
|
22
|
+
Runner.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def install_app app
|
26
|
+
validate_app app
|
27
|
+
|
28
|
+
# This rather nasty trick ensures that other users can use our
|
29
|
+
# ssh agent forwarding too. Allows for git checkouts but also take
|
30
|
+
# over of all your base.
|
31
|
+
if ENV['SSH_CONNECTION'] && ENV['SSH_AUTH_SOCK']
|
32
|
+
puts "Opening up your ssh connection forwarding to all users on this machine."
|
33
|
+
puts "WARNING: This is a bad thing on multi user machines. Don't use this tool"
|
34
|
+
puts "in such an environment."
|
35
|
+
puts
|
36
|
+
ssh_auth_sock = ENV['SSH_AUTH_SOCK']
|
37
|
+
FileUtils.chmod(0777, File.dirname(ssh_auth_sock))
|
38
|
+
FileUtils.chmod(0666, ssh_auth_sock)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Makes sure the directory exists
|
42
|
+
root = Pathname.new(app.root)
|
43
|
+
unless root.directory?
|
44
|
+
FileUtils.mkdir_p(root)
|
45
|
+
FileUtils.chown(app.user, nil, root) if app.user
|
46
|
+
end
|
47
|
+
|
48
|
+
# Installs the git source code and resets to the given version
|
49
|
+
if app.git
|
50
|
+
url, options = app.git
|
51
|
+
|
52
|
+
git_clone app, url, options[:version] || 'master'
|
53
|
+
end
|
54
|
+
|
55
|
+
# If we need to use RVM, create another object that takes care of
|
56
|
+
# running things for us.
|
57
|
+
r = runner
|
58
|
+
if app.rvm
|
59
|
+
r = Runner::RVM.new(app.rvm)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Makes sure all the gems are installed
|
63
|
+
r.run 'bundle install --deployment', cwd: app.root, user: app.user
|
64
|
+
end
|
65
|
+
|
66
|
+
def git_clone app, source, version
|
67
|
+
opts = { user: app.user, cwd: app.root }
|
68
|
+
runner.run "git clone #{source} .", opts do |ex|
|
69
|
+
raise ex unless ex.to_s.match(%r(fatal: destination path '.' already exists))
|
70
|
+
"Already exists, error ignored."
|
71
|
+
end
|
72
|
+
|
73
|
+
runner.run "git fetch #{source}", opts
|
74
|
+
runner.run "git reset --hard #{version}", opts
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate_app app
|
78
|
+
fail 'Application has no root. Please set one: root "some/path"' unless
|
79
|
+
app.root
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
module Ober
|
3
|
+
class Runner
|
4
|
+
class RVM < Runner
|
5
|
+
def initialize rvm
|
6
|
+
@rvm_source_path = source(rvm)
|
7
|
+
fail "No such RVM version. (#{rvm} not found)" unless @rvm_source_path
|
8
|
+
|
9
|
+
detect_environment_for_rvm
|
10
|
+
end
|
11
|
+
|
12
|
+
def variables
|
13
|
+
%w(PATH rvm_env_string rvm_path rvm_ruby_string rvm_gemset_name
|
14
|
+
RUBY_VERSION GEM_HOME GEM_PATH MY_RUBY_HOME IRBRC MAGLEV_HOME RBXOPT)
|
15
|
+
end
|
16
|
+
def detect_environment_for_rvm
|
17
|
+
echo_string = ''
|
18
|
+
variables.each { |v| echo_string << "echo $#{v}; " }
|
19
|
+
|
20
|
+
output = run_silent(%Q(
|
21
|
+
bash -c 'source #{@rvm_source_path}; #{echo_string}'
|
22
|
+
).strip)
|
23
|
+
|
24
|
+
@env = {}
|
25
|
+
variables.zip(output.lines).each do |var, val|
|
26
|
+
val.chomp!
|
27
|
+
@env[var] = val.size == 0 ? nil : val
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def produce_shellout cmd, opts
|
32
|
+
Mixlib::ShellOut.new(cmd, opts.merge(environment: @env))
|
33
|
+
end
|
34
|
+
|
35
|
+
# You should find version by running
|
36
|
+
#
|
37
|
+
# rvm env --path
|
38
|
+
#
|
39
|
+
# and taking the last part of the path as your version. Unlike what
|
40
|
+
# rvm accepts, we're kind of picky here.
|
41
|
+
#
|
42
|
+
def source version
|
43
|
+
# Locate rvm installation:
|
44
|
+
["#{ENV['HOME']}/.rvm/environments"].
|
45
|
+
map { |path| File.join(path, version) }.
|
46
|
+
find { |path| File.exist?(path) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/ober/runner.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
require 'mixlib/shellout'
|
3
|
+
|
4
|
+
module Ober
|
5
|
+
class Runner
|
6
|
+
def produce_shellout cmd, opts
|
7
|
+
Mixlib::ShellOut.new(cmd, opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def run cmd, opts={}, &block
|
11
|
+
puts " $ #{cmd}"
|
12
|
+
output = run_silent(cmd, opts, &block)
|
13
|
+
|
14
|
+
if output
|
15
|
+
output.lines.each do |line|
|
16
|
+
puts " > #{line.chomp}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
output
|
21
|
+
end
|
22
|
+
|
23
|
+
def run_silent cmd, opts={}
|
24
|
+
shellout = produce_shellout(cmd, opts)
|
25
|
+
shellout.run_command
|
26
|
+
|
27
|
+
shellout.error!
|
28
|
+
|
29
|
+
shellout.stdout
|
30
|
+
rescue Mixlib::ShellOut::ShellCommandFailed => ex
|
31
|
+
if block_given?
|
32
|
+
return yield(ex)
|
33
|
+
else
|
34
|
+
raise ex
|
35
|
+
end
|
36
|
+
end # def run
|
37
|
+
end # class Runner
|
38
|
+
end
|
data/lib/ober/version.rb
ADDED
data/lib/ober.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ober/cli'
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ober
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kaspar Schiess
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: clamp
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>'
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>'
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mixlib-shellout
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>'
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>'
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0.0'
|
46
|
+
description: ! "Provides an alternative to the various remote applications that fulfill
|
47
|
+
the same\npurpose, such as capistrano or even chef. Installs Ruby applications to
|
48
|
+
servers\non defined locations. \n\nVery early alpha. This will eventually deal with
|
49
|
+
all the intricacies of bundler, \nRVM and rbenv, but for now, does really simple
|
50
|
+
installations. \n"
|
51
|
+
email: kaspar.schiess@absurd.li
|
52
|
+
executables:
|
53
|
+
- ober
|
54
|
+
extensions: []
|
55
|
+
extra_rdoc_files: []
|
56
|
+
files:
|
57
|
+
- Gemfile
|
58
|
+
- Gemfile.lock
|
59
|
+
- LICENSE
|
60
|
+
- README
|
61
|
+
- bin/ober
|
62
|
+
- doc/sample.rb
|
63
|
+
- lib/ober.rb
|
64
|
+
- lib/ober/application.rb
|
65
|
+
- lib/ober/cli.rb
|
66
|
+
- lib/ober/configuration.rb
|
67
|
+
- lib/ober/installer.rb
|
68
|
+
- lib/ober/runner.rb
|
69
|
+
- lib/ober/runner/rvm.rb
|
70
|
+
- lib/ober/version.rb
|
71
|
+
homepage: https://bitbucket.org/kschiess/ober
|
72
|
+
licenses: []
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.8.25
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Ober serves applications to servers.
|
95
|
+
test_files: []
|
96
|
+
has_rdoc:
|