dply 0.2.19 → 0.3.0
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.
- checksums.yaml +5 -5
- data/.rspec +4 -0
- data/Rakefile +0 -14
- data/TODO +0 -1
- data/code_dump/old_remote_task.rb +2 -0
- data/{dev_bin → dev_exe}/dplyr +0 -0
- data/{dev_bin → dev_exe}/drake +1 -1
- data/dply.gemspec +2 -2
- data/{bin → exe}/dplyr +0 -0
- data/{bin → exe}/drake +12 -14
- data/lib/dply/TEST_TODO +50 -0
- data/lib/dply/app_config.rb +108 -0
- data/lib/dply/base_config.rb +110 -0
- data/lib/dply/build.rb +17 -11
- data/lib/dply/build_config.rb +28 -96
- data/lib/dply/bundle.rb +7 -30
- data/lib/dply/cli/build.rb +5 -12
- data/lib/dply/cli/ctl.rb +7 -8
- data/lib/dply/cli/deploy.rb +6 -10
- data/lib/dply/cli/devbuild.rb +6 -10
- data/lib/dply/cli/install_pkgs.rb +2 -3
- data/lib/dply/cli/run.rb +27 -0
- data/lib/dply/cli/status.rb +1 -2
- data/lib/dply/cli/task.rb +6 -12
- data/lib/dply/code_archive.rb +123 -0
- data/lib/dply/command.rb +57 -0
- data/lib/dply/config_downloader.rb +3 -2
- data/lib/dply/curl.rb +1 -5
- data/lib/dply/custom_logger.rb +18 -1
- data/lib/dply/deplist.rb +16 -48
- data/lib/dply/deploy_config.rb +34 -0
- data/lib/dply/elf.rb +60 -0
- data/lib/dply/env.rb +9 -0
- data/lib/dply/git.rb +15 -8
- data/lib/dply/helper.rb +21 -33
- data/lib/dply/linker.rb +27 -27
- data/lib/dply/lock.rb +2 -9
- data/lib/dply/logger.rb +1 -1
- data/lib/dply/pkgs.rb +9 -11
- data/lib/dply/release.rb +2 -2
- data/lib/dply/{archive.rb → remote_archive.rb} +1 -1
- data/lib/dply/repo.rb +3 -3
- data/lib/dply/rpm.rb +12 -20
- data/lib/dply/scripts/depcheck.rb +4 -0
- data/lib/dply/shared_dirs.rb +1 -1
- data/lib/dply/strategy/archive.rb +15 -22
- data/lib/dply/strategy/base.rb +82 -0
- data/lib/dply/strategy/git.rb +18 -19
- data/lib/dply/task_dsl.rb +101 -0
- data/lib/dply/util.rb +75 -0
- data/lib/dply/venv.rb +53 -0
- data/lib/dply/version.rb +1 -1
- data/lib/dply/yum.rb +21 -31
- data/lib/dplyr/consul.rb +1 -1
- data/spec/dply/base_config_spec.rb +178 -0
- data/spec/dply/bundle_spec.rb +100 -0
- data/spec/dply/command_spec.rb +190 -0
- data/spec/dply/curl_spec.rb +41 -0
- data/spec/dply/deplist_spec.rb +48 -0
- data/spec/dply/elf_spec.rb +64 -0
- data/spec/dply/env_spec.rb +57 -0
- data/spec/dply/git_spec.rb +136 -0
- data/spec/dply/helper_spec.rb +168 -0
- data/spec/dply/linker_spec.rb +81 -0
- data/spec/dply/lock_spec.rb +24 -0
- data/spec/dply/pkgs_spec.rb +105 -0
- data/spec/dply/repo_spec.rb +58 -0
- data/spec/dply/rpm_spec.rb +32 -0
- data/spec/dply/yum_spec.rb +29 -0
- data/spec/integration/archive_flow_spec.rb +87 -0
- data/spec/integration/git_flow_spec.rb +63 -0
- data/spec/repo.rb +27 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/test_data/build.tar.gz +0 -0
- data/spec/test_data/build.tar.gz.md5 +1 -0
- data/spec/test_data/bundle/gems_installed/Gemfile +1 -0
- data/spec/test_data/bundle/gems_not_installed/Gemfile +2 -0
- data/spec/test_data/bundle/no_gemfile/.gitkeep +0 -0
- data/spec/test_data/command/test.rb +7 -0
- data/spec/test_data/elf/elf +0 -0
- data/spec/test_data/elf/libpgtypes.so.3 +0 -0
- data/spec/test_data/elf/not_elf +1 -0
- data/spec/test_data/sample_repo/.dply.lock +0 -0
- data/spec/test_data/sample_repo/Gemfile +2 -0
- data/spec/test_data/sample_repo/Rakefile +3 -0
- data/spec/test_data/sample_repo/app.rb +1 -0
- data/spec/test_data/sample_repo/dply/app.rb +33 -0
- data/spec/test_data/sample_repo/lib/libacl.so.1 +0 -0
- data/spec/test_data/sample_repo/pkgs.yml +2 -0
- data/spec/webserver.rb +21 -0
- metadata +96 -28
- data/lib/dply/cli/app_task.rb +0 -38
- data/lib/dply/config.rb +0 -120
- data/lib/dply/config_struct.rb +0 -52
- data/lib/dply/rakelib/drake.rake +0 -33
- data/lib/dply/tasks.rb +0 -136
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require_relative 'helper'
|
|
3
|
+
|
|
4
|
+
module Dply
|
|
5
|
+
class CodeArchive
|
|
6
|
+
|
|
7
|
+
include Helper
|
|
8
|
+
|
|
9
|
+
attr_reader :name, :branch
|
|
10
|
+
attr_writer :skip_depcheck
|
|
11
|
+
|
|
12
|
+
def initialize(name, revision:)
|
|
13
|
+
@name = name
|
|
14
|
+
@branch = get_branch
|
|
15
|
+
@revision = revision
|
|
16
|
+
@dir = "tmp/build_artifacts"
|
|
17
|
+
validate
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def build(git: true, gnu_tar: false, &block)
|
|
21
|
+
make_dir
|
|
22
|
+
create_tar git, gnu_tar
|
|
23
|
+
instance_eval &block if block
|
|
24
|
+
add_git_commit_id
|
|
25
|
+
add_revision
|
|
26
|
+
add_archive_name
|
|
27
|
+
depcheck
|
|
28
|
+
compress
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def get_branch
|
|
34
|
+
out = cmd "git rev-parse --abbrev-ref HEAD", return_output: true
|
|
35
|
+
out.chomp.tr("/", "_")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def tar
|
|
39
|
+
@tar ||= "#{@dir}/#{@name}-#{@revision}-#{@branch}.tar"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def make_dir
|
|
43
|
+
FileUtils.mkdir @dir if not File.directory? @dir
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def create_tar(git, gnu_tar)
|
|
47
|
+
tmp_dir = "tmp/app_code"
|
|
48
|
+
if git
|
|
49
|
+
if gnu_tar
|
|
50
|
+
FileUtils.rm_rf tmp_dir if File.exists? tmp_dir
|
|
51
|
+
FileUtils.mkdir tmp_dir
|
|
52
|
+
sh "git archive HEAD | tar xf - -C #{tmp_dir}"
|
|
53
|
+
cmd "tar cf #{tar} -C #{tmp_dir} ."
|
|
54
|
+
else
|
|
55
|
+
cmd "git archive -o #{tar} HEAD"
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
cmd "tar -cf #{tar} -T /dev/null"
|
|
59
|
+
end
|
|
60
|
+
ensure
|
|
61
|
+
FileUtils.rm_rf tmp_dir if File.exists? tmp_dir
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def add(file, chdir: nil)
|
|
65
|
+
if chdir
|
|
66
|
+
cmd %(tar -h -C #{chdir} --append -f "#{tar}" "#{file}")
|
|
67
|
+
else
|
|
68
|
+
cmd %(tar -h --append -f "#{tar}" "#{file}")
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def remove(file)
|
|
73
|
+
cmd %(tar --delete -f "#{tar}" "#{file}")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def add_git_commit_id
|
|
77
|
+
commit_id = `git rev-parse HEAD`.chomp!
|
|
78
|
+
file = "GIT_COMMIT_ID"
|
|
79
|
+
File.write(file, commit_id)
|
|
80
|
+
add file
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def add_revision
|
|
84
|
+
file = "REVISION"
|
|
85
|
+
File.write(file, @revision)
|
|
86
|
+
add file
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def add_archive_name
|
|
90
|
+
file = "ARCHIVE_NAME"
|
|
91
|
+
File.write(file, @name)
|
|
92
|
+
add file
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def add_bundle
|
|
96
|
+
add ".bundle"
|
|
97
|
+
add "vendor/bundle"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def depcheck
|
|
101
|
+
return if @skip_depcheck
|
|
102
|
+
command = %(ruby -W0 "#{__dir__}/scripts/depcheck.rb" #{tar})
|
|
103
|
+
logger.bullet "depcheck #{tar}"
|
|
104
|
+
cmd command, display: false
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def compress
|
|
108
|
+
cmd %(#{gzip} -f -9 "#{tar}")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def gzip
|
|
112
|
+
File.exists?("/usr/bin/pigz") ? "pigz" : "gzip"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def validate
|
|
116
|
+
[:name, :branch, :revision, :dir].each do |i|
|
|
117
|
+
ivar = "@#{i}"
|
|
118
|
+
v = instance_variable_get(ivar)
|
|
119
|
+
raise Error, "archive param :#{i} is empty" if (!v || v.strip.empty?)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
data/lib/dply/command.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require_relative 'error'
|
|
2
|
+
require 'shellwords'
|
|
3
|
+
|
|
4
|
+
module Dply
|
|
5
|
+
class Command
|
|
6
|
+
|
|
7
|
+
def initialize(command, env: {}, shell: false)
|
|
8
|
+
@command = command
|
|
9
|
+
@env = env
|
|
10
|
+
@shell = shell
|
|
11
|
+
validate!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run
|
|
15
|
+
assert_success { system(@env, *command, unsetenv_others: true, 2 => 1) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def capture
|
|
19
|
+
assert_success { IO.popen(@env, command, unsetenv_others: true) { |f| f.read } }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def assert_success(&block)
|
|
25
|
+
ret = yield
|
|
26
|
+
exitstatus = $?.exitstatus
|
|
27
|
+
if exitstatus != 0
|
|
28
|
+
raise Error, "non zero exit for \"#{command_str}\""
|
|
29
|
+
end
|
|
30
|
+
ret
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def command
|
|
34
|
+
@shell ? command_str : command_arr
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def command_arr
|
|
38
|
+
@command_arr ||= begin
|
|
39
|
+
command_arr = @command.is_a?(Array) ? @command : @command.shellsplit
|
|
40
|
+
raise Error, "empty command \"#{@command}\"" if command_arr.empty?
|
|
41
|
+
command_arr[0] = command_arr[0].shellescape if command_arr.size == 1
|
|
42
|
+
command_arr
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def command_str
|
|
47
|
+
@command_str ||= @command.is_a?(String) ? @command : @command.join(" ")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def validate!
|
|
51
|
+
if @shell && @command.is_a?(Array)
|
|
52
|
+
raise Error, "command cannot be an array when shell: true"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -8,9 +8,10 @@ module Dply
|
|
|
8
8
|
include Helper
|
|
9
9
|
attr_writer :skip_download
|
|
10
10
|
|
|
11
|
-
def initialize(config_files , base_url)
|
|
11
|
+
def initialize(config_files , base_url, dir: "config")
|
|
12
12
|
@config_files = config_files
|
|
13
13
|
@base_url = base_url
|
|
14
|
+
@dir = dir
|
|
14
15
|
@skip_download = []
|
|
15
16
|
end
|
|
16
17
|
|
|
@@ -20,7 +21,7 @@ module Dply
|
|
|
20
21
|
logger.debug "skipping to download file #{f}"
|
|
21
22
|
next
|
|
22
23
|
end
|
|
23
|
-
curl.download "#{@base_url}/#{f}", "
|
|
24
|
+
curl.download "#{@base_url}/#{f}", "#{@dir}/#{f}"
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
27
|
|
data/lib/dply/curl.rb
CHANGED
data/lib/dply/custom_logger.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'logger'
|
|
2
|
-
|
|
2
|
+
require_relative 'ext/string'
|
|
3
|
+
|
|
3
4
|
module Dply
|
|
4
5
|
class CustomLogger < ::Logger
|
|
5
6
|
|
|
@@ -8,6 +9,7 @@ module Dply
|
|
|
8
9
|
def initialize(file)
|
|
9
10
|
super(file)
|
|
10
11
|
@level = ::Logger::INFO
|
|
12
|
+
# @trace_mode = false
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def format_message(severity, timestamp, progname, msg)
|
|
@@ -23,6 +25,21 @@ module Dply
|
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
|
|
28
|
+
def command(command, mode:)
|
|
29
|
+
case mode
|
|
30
|
+
when :arrow
|
|
31
|
+
arrow command
|
|
32
|
+
when :bullet
|
|
33
|
+
bullet command
|
|
34
|
+
else
|
|
35
|
+
debug command
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def arrow(msg)
|
|
40
|
+
info "#{"\u2023".green.bold} #{msg}"
|
|
41
|
+
end
|
|
42
|
+
|
|
26
43
|
def bullet(msg)
|
|
27
44
|
info "#{"\u2219".bold.blue} #{msg}"
|
|
28
45
|
end
|
data/lib/dply/deplist.rb
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
|
-
require 'filemagic'
|
|
2
|
-
require 'elf'
|
|
3
|
-
require 'dply/helper'
|
|
4
|
-
require 'dply/rpm'
|
|
5
|
-
require 'dply/pkgs'
|
|
6
1
|
require 'tmpdir'
|
|
2
|
+
require 'set'
|
|
3
|
+
require_relative 'helper'
|
|
4
|
+
require_relative 'rpm'
|
|
5
|
+
require_relative 'pkgs'
|
|
6
|
+
require_relative 'elf'
|
|
7
7
|
|
|
8
8
|
module Dply
|
|
9
9
|
class Deplist
|
|
10
10
|
|
|
11
11
|
include Helper
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@path = path
|
|
18
|
-
end
|
|
13
|
+
BASE_PACKAGES = Set["glibc", "libgcc", "libstdc++", "openssl", "ruby-alt", "jemalloc"]
|
|
14
|
+
|
|
15
|
+
def initialize(tar_path)
|
|
16
|
+
@tar_path = Pathname.new(tar_path).realpath
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
def verify!
|
|
22
|
-
error "#{@
|
|
20
|
+
error "#{@tar_path} not readable" if not File.readable? @tar_path
|
|
23
21
|
tmp_dir do
|
|
24
22
|
logger.info "(in #{Dir.pwd})"
|
|
25
|
-
cmd "tar xf #{@
|
|
26
|
-
pkgs_list = Pkgs.new.runtime
|
|
23
|
+
cmd "tar xf #{@tar_path}"
|
|
24
|
+
pkgs_list = Pkgs.new("pkgs.yml").runtime
|
|
27
25
|
|
|
28
26
|
@libs_files_map = libs_files_map
|
|
29
27
|
libs = @libs_files_map.keys
|
|
@@ -33,7 +31,7 @@ module Dply
|
|
|
33
31
|
pp @libs_files_map
|
|
34
32
|
end
|
|
35
33
|
|
|
36
|
-
deps =
|
|
34
|
+
deps = Rpm.libs_pkgs_map libs
|
|
37
35
|
verify_deps(deps, pkgs_list)
|
|
38
36
|
end
|
|
39
37
|
end
|
|
@@ -42,6 +40,7 @@ module Dply
|
|
|
42
40
|
|
|
43
41
|
def verify_deps(deps, pkgs_list)
|
|
44
42
|
deps.each do |lib, pkgs|
|
|
43
|
+
next if pkgs.find { |pkg| BASE_PACKAGES.include? pkg }
|
|
45
44
|
if not pkgs.any? { |pkg| pkgs_list.include? pkg }
|
|
46
45
|
logger.error "missing from pkgs.yml : any of #{pkgs} (lib: #{lib}, files: #{@libs_files_map[lib]})"
|
|
47
46
|
@error = true
|
|
@@ -51,17 +50,6 @@ module Dply
|
|
|
51
50
|
puts "all dependencies satisfied".green
|
|
52
51
|
end
|
|
53
52
|
|
|
54
|
-
def magic
|
|
55
|
-
@magic ||= begin
|
|
56
|
-
flags = FileMagic::FLAGS_BY_SYM.select { |k,v| k.to_s =~ /no_check_/ }.keys
|
|
57
|
-
not_required_flags = [:no_check_soft, :no_check_elf, :no_check_builtin]
|
|
58
|
-
not_required_flags.each {|x| flags.delete(x) }
|
|
59
|
-
fm = FileMagic.new
|
|
60
|
-
fm.flags = flags
|
|
61
|
-
fm
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
53
|
def tmp_dir(&block)
|
|
66
54
|
dir = File.exist?("tmp") ? "tmp" : "/tmp"
|
|
67
55
|
Dir.mktmpdir(nil, dir) do |d|
|
|
@@ -72,8 +60,7 @@ module Dply
|
|
|
72
60
|
def libs_files_map
|
|
73
61
|
libs = {}
|
|
74
62
|
Dir["./**/*"].each do |f|
|
|
75
|
-
|
|
76
|
-
next if not type =~ /ELF/
|
|
63
|
+
next if not Elf.elf? f
|
|
77
64
|
dynamic_libs(f).each do |l|
|
|
78
65
|
libs[l] ||= []
|
|
79
66
|
libs[l] << f
|
|
@@ -83,26 +70,7 @@ module Dply
|
|
|
83
70
|
end
|
|
84
71
|
|
|
85
72
|
def dynamic_libs(file)
|
|
86
|
-
|
|
87
|
-
Elf::File.open(file) do |ef|
|
|
88
|
-
return [] if not ef.has_section? ".dynamic"
|
|
89
|
-
lib_type = ef.elf_class.desc == "64-bit" ? "()(64bit)" : ""
|
|
90
|
-
dynamic = ef[".dynamic"].needed_libraries.keys
|
|
91
|
-
rpath = ef[".dynamic"].rpath.map { |i| i.sub("$ORIGIN", "#{path.dirname}") }
|
|
92
|
-
external = dynamic.reject { |l| lib_in_rpath? l, rpath }.map { |l| "#{l}#{lib_type}" }
|
|
93
|
-
logger.debug { "[#{file}]: dynamic:#{dynamic.size} rpath:#{dynamic.size - external.size} ext:#{external.size}" } if logger.debug?
|
|
94
|
-
external
|
|
95
|
-
end
|
|
96
|
-
rescue Exception
|
|
97
|
-
return []
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def lib_in_rpath?(lib, rpath)
|
|
101
|
-
rpath.any? { |i| File.exist? "#{i}/#{lib}" }
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def rpm
|
|
105
|
-
@rpm ||= Rpm.new
|
|
73
|
+
Elf.new(file).external_libs
|
|
106
74
|
end
|
|
107
75
|
|
|
108
76
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'dply/base_config'
|
|
2
|
+
|
|
3
|
+
module Dply
|
|
4
|
+
class DeployConfig < BaseConfig
|
|
5
|
+
define_opts do
|
|
6
|
+
opt :name
|
|
7
|
+
opt :repo
|
|
8
|
+
opt :mirror
|
|
9
|
+
opt :branch
|
|
10
|
+
opt :strategy, type: Symbol
|
|
11
|
+
opt :target
|
|
12
|
+
opt :build_url
|
|
13
|
+
opt :shared_dirs, type: Array
|
|
14
|
+
opt :config_map, type: Hash
|
|
15
|
+
opt :dir_map, type: Hash
|
|
16
|
+
opt :config_download_url
|
|
17
|
+
opt :config_skip_download, type: Array
|
|
18
|
+
opt :verify_checksum
|
|
19
|
+
opt :revision
|
|
20
|
+
opt :dir
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def default_config
|
|
24
|
+
dir Dir.pwd
|
|
25
|
+
branch "master"
|
|
26
|
+
shared_dirs []
|
|
27
|
+
dir_map({
|
|
28
|
+
"tmp" => "tmp",
|
|
29
|
+
"log" => "log"
|
|
30
|
+
})
|
|
31
|
+
verify_checksum true
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/dply/elf.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'elf'
|
|
2
|
+
require_relative 'helper'
|
|
3
|
+
|
|
4
|
+
module Dply
|
|
5
|
+
class Elf
|
|
6
|
+
|
|
7
|
+
include Helper
|
|
8
|
+
|
|
9
|
+
MAGIC_STRING = "\177ELF"
|
|
10
|
+
|
|
11
|
+
def self.elf?(path)
|
|
12
|
+
return false if not File.file? path
|
|
13
|
+
IO.binread(path, 4) == MAGIC_STRING
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :path
|
|
17
|
+
|
|
18
|
+
def initialize(path)
|
|
19
|
+
@path = Pathname.new(path)
|
|
20
|
+
@elf = ::Elf::File.new(path)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def external_libs
|
|
24
|
+
return [] if not @elf.has_section? ".dynamic"
|
|
25
|
+
dynamic = dynamic_libs()
|
|
26
|
+
external = dynamic.reject { |i| lib_in_relative_rpath? i }.map { |l| "#{l}#{lib_type}" }
|
|
27
|
+
logger.debug { "[#{@path}]: dynamic:#{dynamic.size} rpath:#{dynamic.size - external.size} ext:#{external.size}" } if logger.debug?
|
|
28
|
+
external
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def dynamic_libs
|
|
34
|
+
@elf[".dynamic"].needed_libraries.keys
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def lib_type
|
|
38
|
+
@lib_type ||= @elf.elf_class.desc == "64-bit" ? "()(64bit)" : ""
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def relative_rpath
|
|
42
|
+
@relative_rpath ||= begin
|
|
43
|
+
# include both rpath and runpaths
|
|
44
|
+
rpaths = @elf[".dynamic"].rpath + @elf[".dynamic"].runpath
|
|
45
|
+
# expand $ORIGIN
|
|
46
|
+
rpaths = rpaths.map { |i| i.sub("$ORIGIN", "#{@path.dirname}") }
|
|
47
|
+
# convert all paths to realpath
|
|
48
|
+
rpaths = rpaths.map { |i| Pathname.new(i).realpath }
|
|
49
|
+
# select paths which start with cwd or are subpaths to cwd
|
|
50
|
+
cwd = Dir.pwd
|
|
51
|
+
rpaths.select { |i| i.to_s.start_with? cwd }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def lib_in_relative_rpath?(lib)
|
|
56
|
+
relative_rpath.any? { |i| File.exist? "#{i}/#{lib}" }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
end
|