luban 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +37 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/luban +3 -0
- data/lib/luban/deployment/cli/application/authenticator.rb +106 -0
- data/lib/luban/deployment/cli/application/base.rb +179 -0
- data/lib/luban/deployment/cli/application/builder.rb +67 -0
- data/lib/luban/deployment/cli/application/publisher.rb +215 -0
- data/lib/luban/deployment/cli/application/repository.rb +175 -0
- data/lib/luban/deployment/cli/application/scm/git.rb +49 -0
- data/lib/luban/deployment/cli/application/scm/rsync.rb +47 -0
- data/lib/luban/deployment/cli/application.rb +5 -0
- data/lib/luban/deployment/cli/command.rb +360 -0
- data/lib/luban/deployment/cli/package/binary.rb +241 -0
- data/lib/luban/deployment/cli/package/dependency.rb +49 -0
- data/lib/luban/deployment/cli/package/dependency_set.rb +71 -0
- data/lib/luban/deployment/cli/package/installer/core.rb +98 -0
- data/lib/luban/deployment/cli/package/installer/install.rb +330 -0
- data/lib/luban/deployment/cli/package/installer/paths.rb +81 -0
- data/lib/luban/deployment/cli/package/installer.rb +3 -0
- data/lib/luban/deployment/cli/package/service.rb +17 -0
- data/lib/luban/deployment/cli/package/worker.rb +43 -0
- data/lib/luban/deployment/cli/package.rb +6 -0
- data/lib/luban/deployment/cli/project.rb +94 -0
- data/lib/luban/deployment/cli.rb +4 -0
- data/lib/luban/deployment/configuration/core.rb +67 -0
- data/lib/luban/deployment/configuration/filter.rb +54 -0
- data/lib/luban/deployment/configuration/question.rb +38 -0
- data/lib/luban/deployment/configuration/server.rb +70 -0
- data/lib/luban/deployment/configuration/server_set.rb +86 -0
- data/lib/luban/deployment/configuration.rb +5 -0
- data/lib/luban/deployment/error.rb +5 -0
- data/lib/luban/deployment/helpers/configuration.rb +159 -0
- data/lib/luban/deployment/helpers/utils.rb +180 -0
- data/lib/luban/deployment/helpers.rb +2 -0
- data/lib/luban/deployment/packages/bundler.rb +81 -0
- data/lib/luban/deployment/packages/git.rb +37 -0
- data/lib/luban/deployment/packages/openssl.rb +59 -0
- data/lib/luban/deployment/packages/ruby.rb +125 -0
- data/lib/luban/deployment/packages/rubygems.rb +89 -0
- data/lib/luban/deployment/packages/yaml.rb +33 -0
- data/lib/luban/deployment/parameters.rb +160 -0
- data/lib/luban/deployment/runner.rb +99 -0
- data/lib/luban/deployment/templates/envrc.erb +30 -0
- data/lib/luban/deployment/templates/unset_envrc.erb +28 -0
- data/lib/luban/deployment/version.rb +5 -0
- data/lib/luban/deployment/worker/base.rb +71 -0
- data/lib/luban/deployment/worker/controller.rb +11 -0
- data/lib/luban/deployment/worker/local.rb +19 -0
- data/lib/luban/deployment/worker/remote.rb +55 -0
- data/lib/luban/deployment/worker/task.rb +25 -0
- data/lib/luban/deployment/worker.rb +4 -0
- data/lib/luban/deployment.rb +8 -0
- data/lib/luban.rb +4 -0
- data/luban.gemspec +29 -0
- metadata +174 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
module Luban
|
2
|
+
module Deployment
|
3
|
+
class Configuration
|
4
|
+
class Question
|
5
|
+
attr_reader :prompt, :default
|
6
|
+
|
7
|
+
def initialize(default:, prompt: nil, echo: true)
|
8
|
+
@default = default
|
9
|
+
@echo = echo
|
10
|
+
@prompt = "#{prompt.to_s}: " unless prompt.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def echo?; @echo; end
|
14
|
+
|
15
|
+
def call
|
16
|
+
ask_question
|
17
|
+
get_response
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def ask_question
|
23
|
+
$stdout.print prompt
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_response
|
27
|
+
response = if echo?
|
28
|
+
$stdin.gets.chomp
|
29
|
+
else
|
30
|
+
require 'io/console'
|
31
|
+
$stdin.noecho(&:gets).chomp.tap{ $stdout.print "\n" }
|
32
|
+
end
|
33
|
+
response.empty? ? default : response
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Luban
|
4
|
+
module Deployment
|
5
|
+
class Configuration
|
6
|
+
class Server < SSHKit::Host
|
7
|
+
attr_reader :roles
|
8
|
+
|
9
|
+
def self.create(host, **properties)
|
10
|
+
server = host.is_a?(Server) ? host : Server.new(host)
|
11
|
+
server.add_properties(properties) unless properties.empty?
|
12
|
+
server.ssh_options ||= {}
|
13
|
+
server
|
14
|
+
end
|
15
|
+
|
16
|
+
def roles
|
17
|
+
self[:roles]
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_roles(roles)
|
21
|
+
roles.each { |role| add_role(role) }
|
22
|
+
end
|
23
|
+
alias_method :roles=, :add_roles
|
24
|
+
|
25
|
+
def add_role(role)
|
26
|
+
roles.add(role.to_sym)
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_role?(role)
|
30
|
+
roles.include? role.to_sym
|
31
|
+
end
|
32
|
+
|
33
|
+
def properties
|
34
|
+
@properties ||= { :roles => Set.new }
|
35
|
+
end
|
36
|
+
|
37
|
+
def [](key)
|
38
|
+
properties[key]
|
39
|
+
end
|
40
|
+
alias_method :fetch, :[]
|
41
|
+
|
42
|
+
def []=(key, value)
|
43
|
+
if respond_to?("#{key}=")
|
44
|
+
send("#{key}=", value)
|
45
|
+
else
|
46
|
+
pval = properties[key]
|
47
|
+
if pval.is_a? Hash and value.is_a? Hash
|
48
|
+
pval.merge!(value)
|
49
|
+
elsif pval.is_a? Set and value.is_a? Set
|
50
|
+
pval.merge(value)
|
51
|
+
elsif pval.is_a? Array and value.is_a? Array
|
52
|
+
pval.concat value
|
53
|
+
else
|
54
|
+
properties[key] = value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
alias_method :set, :[]=
|
59
|
+
|
60
|
+
def add_properties(_properties)
|
61
|
+
_properties.each { |k, v| self[k] = v }
|
62
|
+
end
|
63
|
+
|
64
|
+
def primary?
|
65
|
+
self[:primary]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Luban
|
2
|
+
module Deployment
|
3
|
+
class Configuration
|
4
|
+
class ServerSet
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@servers = { :all => [] }
|
9
|
+
end
|
10
|
+
|
11
|
+
def all
|
12
|
+
@servers[:all]
|
13
|
+
end
|
14
|
+
|
15
|
+
def available_roles
|
16
|
+
@servers.keys - [:all]
|
17
|
+
end
|
18
|
+
|
19
|
+
def has_server?(server)
|
20
|
+
all.find do |s|
|
21
|
+
s.user == server.user and
|
22
|
+
s.hostname == server.hostname and
|
23
|
+
s.port == server.port
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_host(host, **properties)
|
28
|
+
new_server = Server.create(host, properties)
|
29
|
+
if server = has_server?(new_server)
|
30
|
+
server.user = new_server.user unless new_server.user.nil?
|
31
|
+
server.port = new_server.port unless new_server.port.nil?
|
32
|
+
server.add_properties(properties)
|
33
|
+
server
|
34
|
+
else
|
35
|
+
all << new_server
|
36
|
+
new_server.roles.each do |role|
|
37
|
+
@servers[role] ||= []
|
38
|
+
@servers[role] << new_server
|
39
|
+
end
|
40
|
+
new_server
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_hosts_for_role(role, hosts, **properties)
|
45
|
+
properties_deepcopy = Marshal.dump(properties.merge(:roles => Array(role)))
|
46
|
+
Array(hosts).each { |host| add_host(host, Marshal.load(properties_deepcopy)) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_by_roles(roles, **opts)
|
50
|
+
roles.inject([]) do |result, role|
|
51
|
+
result.concat(find_by_role(role, opts))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_by_role(role, **opts)
|
56
|
+
if @servers.has_key?(role)
|
57
|
+
opts.inject(@servers[role]) do |_servers, (action, key)|
|
58
|
+
send(action, _servers, key)
|
59
|
+
end
|
60
|
+
else
|
61
|
+
[]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def find_primary(role)
|
66
|
+
_servers = find_by_role(role)
|
67
|
+
_servers.find(&:primary?) || _servers.first
|
68
|
+
end
|
69
|
+
|
70
|
+
def each
|
71
|
+
all.each { |server| yield server }
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
def exclude(_servers, key)
|
77
|
+
_servers.select { |server| !server[key] }
|
78
|
+
end
|
79
|
+
|
80
|
+
def filter(_servers, key)
|
81
|
+
_servers.select { |server| server[key] }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
module Luban
|
2
|
+
module Deployment
|
3
|
+
module Helpers
|
4
|
+
module Configuration
|
5
|
+
attr_accessor :config
|
6
|
+
|
7
|
+
def config
|
8
|
+
@config ||= Luban::Deployment::Configuration.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(key, *args, &blk)
|
12
|
+
config.fetch(key, *args, &blk)
|
13
|
+
end
|
14
|
+
|
15
|
+
def set(key, *args, &blk)
|
16
|
+
config.set(key, *args, &blk)
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_default(key, *args, &blk)
|
20
|
+
config.set_default(key, *args, &blk)
|
21
|
+
end
|
22
|
+
|
23
|
+
def ask(key=nil, default: nil, prompt: nil, echo: true)
|
24
|
+
config.ask(key, default: default, echo: echo, prompt: prompt)
|
25
|
+
end
|
26
|
+
|
27
|
+
def role(name, hosts, **properties)
|
28
|
+
config.role(name, hosts, properties)
|
29
|
+
end
|
30
|
+
|
31
|
+
def server(name, **properties)
|
32
|
+
config.server(name, properties)
|
33
|
+
end
|
34
|
+
|
35
|
+
def roles(*names)
|
36
|
+
config.roles(*names)
|
37
|
+
end
|
38
|
+
|
39
|
+
def release_roles(*names)
|
40
|
+
config.release_roles(*names)
|
41
|
+
end
|
42
|
+
|
43
|
+
def primary(role)
|
44
|
+
config.primary(role)
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_configuration_file(config_file, optional: false)
|
48
|
+
if File.file?(config_file)
|
49
|
+
if error = syntax_error?(config_file)
|
50
|
+
abort "Aborted! Syntax errors in configuration file.\n#{error}"
|
51
|
+
else
|
52
|
+
instance_eval(File.read(config_file))
|
53
|
+
end
|
54
|
+
else
|
55
|
+
unless optional
|
56
|
+
abort "Aborted! Configuration file is NOT found: #{config_file}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def syntax_error?(file)
|
62
|
+
_stderr = $stderr
|
63
|
+
$stderr = StringIO.new('', 'w')
|
64
|
+
# ONLY work for MRI Ruby
|
65
|
+
RubyVM::InstructionSequence.compile_file(file)
|
66
|
+
$stderr.string.chomp.empty? ? false : $stderr.string
|
67
|
+
ensure
|
68
|
+
$stderr = _stderr
|
69
|
+
end
|
70
|
+
|
71
|
+
def find_template_file(file_name)
|
72
|
+
path = find_template_file_by_config_finder(file_name) ||
|
73
|
+
find_default_template_file(file_name)
|
74
|
+
raise RuntimeError, "Template file is NOT found: #{file_name}." if path.nil?
|
75
|
+
path
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
def find_template_file_by_config_finder(file_name)
|
81
|
+
path = config_finder[:application].find_template_file(file_name) ||
|
82
|
+
config_finder[:project].find_template_file(file_name)
|
83
|
+
end
|
84
|
+
|
85
|
+
def find_default_template_file(file_name)
|
86
|
+
path = File.expand_path(File.join(File.dirname(__FILE__), '..',
|
87
|
+
'templates', file_name))
|
88
|
+
return path if File.file?(path)
|
89
|
+
end
|
90
|
+
|
91
|
+
class Finder
|
92
|
+
class Project < Finder
|
93
|
+
def base_path; base_path ||= target.work_dir; end
|
94
|
+
end
|
95
|
+
|
96
|
+
class Application < Finder
|
97
|
+
def base_path; base_path ||= target.apps_path.join(target.application); end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.project(target); Project.new(target); end
|
101
|
+
def self.application(target); Application.new(target); end
|
102
|
+
|
103
|
+
attr_reader :target
|
104
|
+
attr_reader :base_path
|
105
|
+
attr_reader :config_root
|
106
|
+
attr_reader :config_file
|
107
|
+
attr_reader :config_path
|
108
|
+
attr_reader :templates_path
|
109
|
+
attr_reader :stage_config_file
|
110
|
+
attr_reader :stage_config_path
|
111
|
+
attr_reader :stage_templates_path
|
112
|
+
|
113
|
+
def initialize(target)
|
114
|
+
@target = target
|
115
|
+
set_config_paths
|
116
|
+
end
|
117
|
+
|
118
|
+
def deployfile; @deployfile ||= 'deploy.rb'; end
|
119
|
+
def stagefile; @stagefile ||= "#{target.stage}.rb"; end
|
120
|
+
|
121
|
+
def load_configuration
|
122
|
+
load_general_configuration
|
123
|
+
load_stage_configuration
|
124
|
+
end
|
125
|
+
|
126
|
+
def load_general_configuration
|
127
|
+
target.load_configuration_file(config_file)
|
128
|
+
end
|
129
|
+
|
130
|
+
def load_stage_configuration
|
131
|
+
target.load_configuration_file(stage_config_file)
|
132
|
+
if File.directory?(stage_config_path)
|
133
|
+
Dir[stage_config_path.join("{packages}/**/*.rb")].each do |file|
|
134
|
+
target.load_configuration_file(file)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def find_template_file(file_name)
|
140
|
+
return file_path if File.file?(file_path = stage_templates_path.join(file_name))
|
141
|
+
return file_path if File.file?(file_path = templates_path.join(file_name))
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def set_config_paths
|
147
|
+
@config_root = base_path.join('config')
|
148
|
+
@config_file = @config_root.join(deployfile)
|
149
|
+
@config_path = @config_root.join(deployfile.sub('.rb', ''))
|
150
|
+
@templates_path = @config_root.join('templates')
|
151
|
+
@stage_config_file = @config_path.join(stagefile)
|
152
|
+
@stage_config_path = @config_path.join(target.stage)
|
153
|
+
@stage_templates_path = @stage_config_path.join('templates')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require "digest/md5"
|
2
|
+
|
3
|
+
module Luban
|
4
|
+
module Deployment
|
5
|
+
module Helpers
|
6
|
+
module Utils
|
7
|
+
LogLevels = %i(fatal error warn info debug trace)
|
8
|
+
|
9
|
+
attr_reader :backend
|
10
|
+
|
11
|
+
def check_pass?(type, *args)
|
12
|
+
send("#{type}?", *args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def directory?(path)
|
16
|
+
test "[ -d #{path} ]"
|
17
|
+
end
|
18
|
+
|
19
|
+
def file?(path)
|
20
|
+
test "[ -f #{path} ]"
|
21
|
+
end
|
22
|
+
|
23
|
+
def symlink?(path)
|
24
|
+
test "[ -L #{path} ]"
|
25
|
+
end
|
26
|
+
|
27
|
+
def match?(cmd, expect)
|
28
|
+
expect = Regexp.new(Regexp.escape(expect.to_s)) unless expect.is_a?(Regexp)
|
29
|
+
output = capture(cmd)
|
30
|
+
output =~ expect
|
31
|
+
end
|
32
|
+
|
33
|
+
def assure(type, *args)
|
34
|
+
unless check_pass?(type, *args)
|
35
|
+
if block_given?
|
36
|
+
yield
|
37
|
+
else
|
38
|
+
abort "Aborted! #{type} dependency with #{args.inspect} are not met and no block is given to resolve it."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def assure_dirs(*dirs)
|
44
|
+
dirs.each { |dir| assure(:directory, dir) { mkdir(dir) } }
|
45
|
+
end
|
46
|
+
|
47
|
+
def assure_symlink(source_path, target_path)
|
48
|
+
unless symlink?(target_path) and readlink(target_path) == source_path.to_s
|
49
|
+
ln(source_path, target_path)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def mkdir(*opts, path)
|
54
|
+
execute(:mkdir, '-p', *opts, path)
|
55
|
+
end
|
56
|
+
|
57
|
+
def rm(*opts, path)
|
58
|
+
execute(:rm, '-fr', *opts, path)
|
59
|
+
end
|
60
|
+
alias_method :rmdir, :rm
|
61
|
+
|
62
|
+
def chmod(*opts, path)
|
63
|
+
execute(:chmod, '-R', *opts, path)
|
64
|
+
end
|
65
|
+
|
66
|
+
def ln(*opts, source_path, target_path)
|
67
|
+
execute(:ln, '-nfs', *opts, source_path, target_path)
|
68
|
+
end
|
69
|
+
|
70
|
+
def mv(*opts, source_path, target_path)
|
71
|
+
execute(:mv, *opts, source_path, target_path)
|
72
|
+
end
|
73
|
+
|
74
|
+
def cp(*opts, source_path, target_path)
|
75
|
+
execute(*opts, source_path, target_path)
|
76
|
+
end
|
77
|
+
|
78
|
+
def readlink(source_file)
|
79
|
+
capture("$(type -p readlink greadlink|head -1) #{source_file}")
|
80
|
+
end
|
81
|
+
|
82
|
+
def md5_for_file(file)
|
83
|
+
capture(:cat, "#{file} 2>/dev/null | openssl md5")
|
84
|
+
end
|
85
|
+
|
86
|
+
def sudo(*args)
|
87
|
+
execute(:sudo, *args)
|
88
|
+
end
|
89
|
+
|
90
|
+
def os_name
|
91
|
+
@os_name ||= capture("uname -s")
|
92
|
+
end
|
93
|
+
|
94
|
+
def os_release
|
95
|
+
@os_release ||= capture("uname -r")
|
96
|
+
end
|
97
|
+
|
98
|
+
def hardware_name
|
99
|
+
@hardware_name ||= capture("uname -m")
|
100
|
+
end
|
101
|
+
|
102
|
+
def user_home
|
103
|
+
@user_home ||= capture("eval echo ~")
|
104
|
+
end
|
105
|
+
|
106
|
+
def url_exists?(download_url)
|
107
|
+
# Sent HEAD request to avoid downloading the file contents
|
108
|
+
test("curl -s -L -I -o /dev/null -f #{download_url}")
|
109
|
+
|
110
|
+
# Other effective ways to check url existence with curl
|
111
|
+
|
112
|
+
# In case HEAD request is refused,
|
113
|
+
# only the first byte of the file is requested
|
114
|
+
# test("curl -s -L -o /dev/null -f -r 0-0 #{download_url}")
|
115
|
+
|
116
|
+
# Alternatively, http code (200) can be validated
|
117
|
+
# capture("curl -s -L -I -o /dev/null -w '%{http_code}' #{download_url}") == '200'
|
118
|
+
end
|
119
|
+
|
120
|
+
def upload_by_template(file_to_upload:, template_file:, auto_revision: false, **opts)
|
121
|
+
template = File.read(template_file)
|
122
|
+
|
123
|
+
if auto_revision and file?(file_to_upload)
|
124
|
+
revision = Digest::MD5.hexdigest(template)
|
125
|
+
return if revision_match?(file_to_upload, revision)
|
126
|
+
end
|
127
|
+
|
128
|
+
require 'erb'
|
129
|
+
context = opts[:binding] || binding
|
130
|
+
upload!(StringIO.new(ERB.new(template, nil, '<>').result(context)), file_to_upload)
|
131
|
+
yield file_to_upload if block_given?
|
132
|
+
end
|
133
|
+
|
134
|
+
def revision_match?(file_to_upload, revision)
|
135
|
+
match?("grep \"Revision: \" #{file_to_upload}", revision)
|
136
|
+
end
|
137
|
+
|
138
|
+
[:test, :make, :within, :with, :as, :execute,
|
139
|
+
:upload!, :download!].each do |cmd|
|
140
|
+
define_method(cmd) do |*args, &blk|
|
141
|
+
backend.send(__method__, *args, &blk)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def capture(*args, &blk)
|
146
|
+
backend.capture(*args, &blk).chomp
|
147
|
+
end
|
148
|
+
|
149
|
+
def md5_matched?(file_path, md5)
|
150
|
+
file?(file_path) and md5 == md5_for_file(file_path)
|
151
|
+
end
|
152
|
+
|
153
|
+
#def execute(*args, &blk)
|
154
|
+
# if args.last.is_a?(::Hash)
|
155
|
+
# args.last.merge(verbosity: SSHKit::Logger::DEBUG)
|
156
|
+
# else
|
157
|
+
# args.push(verbosity: SSHKit::Logger::DEBUG)
|
158
|
+
# end
|
159
|
+
# backend.execute(*args, &blk)
|
160
|
+
#end
|
161
|
+
|
162
|
+
LogLevels.each do |cmd|
|
163
|
+
define_method(cmd) { |msg| backend.send(__method__, "[#{hostname}] #{msg}") }
|
164
|
+
end
|
165
|
+
|
166
|
+
def host
|
167
|
+
@host ||= backend.host
|
168
|
+
end
|
169
|
+
|
170
|
+
def hostname
|
171
|
+
@hostname ||= host.hostname
|
172
|
+
end
|
173
|
+
|
174
|
+
def method_missing(sym, *args, &blk)
|
175
|
+
backend.respond_to?(sym) ? backend.send(sym, *args, &blk) : super
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Luban
|
2
|
+
module Deployment
|
3
|
+
module Packages
|
4
|
+
class Bundler < Luban::Deployment::Package::Binary
|
5
|
+
protected
|
6
|
+
|
7
|
+
def setup_install_tasks
|
8
|
+
super
|
9
|
+
commands[:install].switch :install_doc, "Install Bundler document"
|
10
|
+
end
|
11
|
+
|
12
|
+
class Installer < Luban::Deployment::Package::Installer
|
13
|
+
def install_doc?
|
14
|
+
task.opts.install_doc
|
15
|
+
end
|
16
|
+
|
17
|
+
def package_version
|
18
|
+
parent.task.opts.bundler || super
|
19
|
+
end
|
20
|
+
|
21
|
+
def package_path
|
22
|
+
parent.package_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def install_path
|
26
|
+
parent.install_path
|
27
|
+
end
|
28
|
+
|
29
|
+
def bundler_executable
|
30
|
+
@bundler_executable ||= bin_path.join('bundle')
|
31
|
+
end
|
32
|
+
|
33
|
+
def gem_executable
|
34
|
+
parent.gem_executable
|
35
|
+
end
|
36
|
+
|
37
|
+
def src_file_extname
|
38
|
+
@src_file_extname ||= 'gem'
|
39
|
+
end
|
40
|
+
|
41
|
+
def source_repo
|
42
|
+
#@source_repo ||= "http://production.cf.rubygems.org"
|
43
|
+
@source_repo ||= "https://rubygems.org"
|
44
|
+
end
|
45
|
+
|
46
|
+
def source_url_root
|
47
|
+
@source_url_root ||= "downloads"
|
48
|
+
end
|
49
|
+
|
50
|
+
def installed?
|
51
|
+
return false unless file?(bundler_executable)
|
52
|
+
match?("#{bundler_executable} -v", package_version)
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def validate
|
58
|
+
if parent.nil?
|
59
|
+
abort "Aborted! Parent package for Bundler MUST be provided."
|
60
|
+
end
|
61
|
+
unless parent.is_a?(Ruby::Installer)
|
62
|
+
abort "Aborted! Parent package for Bundler MUST be an instance of #{Ruby::Installer.name}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def uncompress_package; end
|
67
|
+
def configure_package; end
|
68
|
+
def make_package; end
|
69
|
+
def update_binstubs!; end
|
70
|
+
|
71
|
+
def install_package!
|
72
|
+
install_opts = ['--local']
|
73
|
+
install_opts << "--no-document" unless install_doc?
|
74
|
+
test("#{gem_executable} uninstall bundler -a -x -I >> #{install_log_file_path} 2>&1") and
|
75
|
+
test("#{gem_executable} install #{install_opts.join(' ')} #{src_file_path} >> #{install_log_file_path} 2>&1")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Luban
|
2
|
+
module Deployment
|
3
|
+
module Packages
|
4
|
+
class Git < Luban::Deployment::Package::Binary
|
5
|
+
apply_to :all do
|
6
|
+
before_install do
|
7
|
+
depend_on 'openssl', version: '1.0.2e'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Installer < Luban::Deployment::Package::Installer
|
12
|
+
def git_executable
|
13
|
+
@git_executable ||= bin_path.join('git')
|
14
|
+
end
|
15
|
+
|
16
|
+
def source_repo
|
17
|
+
@source_repo ||= "https://www.kernel.org"
|
18
|
+
end
|
19
|
+
|
20
|
+
def source_url_root
|
21
|
+
@source_url_root ||= "pub/software/scm/git"
|
22
|
+
end
|
23
|
+
|
24
|
+
def installed?
|
25
|
+
return false unless file?(git_executable)
|
26
|
+
pattern = "version #{package_major_version}"
|
27
|
+
match?("#{git_executable} --version", pattern)
|
28
|
+
end
|
29
|
+
|
30
|
+
def with_openssl_dir(dir)
|
31
|
+
@configure_opts << "--with-openssl=#{dir}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|