dply 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9a3b5ef3facbc1566ddb34fa8a038d263be1b32
4
- data.tar.gz: e06ca61d6ab3e7470accc884fa10f660f3652b2d
3
+ metadata.gz: a62731f9b97dd1e39aa3ecbc0462fdfb2896c606
4
+ data.tar.gz: 29f29b503deaa08c163c03d06e78ded0bf379e11
5
5
  SHA512:
6
- metadata.gz: 677ce56f5aa22733fb85146fa73b5aed0ab6debce7c7f92e57dbf28287479cfc27a62973a98a9f6d6480b60ea32d5440f6bb61bbc937b16caf7c87c87a591c27
7
- data.tar.gz: 3f4fff81dd674aade3902cb88b75c7a9c75b47f47189bde721e435c95e6c9fc38bfba29408f4b30a0071497d720f81b97879e9bfde999eb6786c503f6146cf48
6
+ metadata.gz: af99d1e9832912032f753924ba390a1c82e16999b99d25456581eb910e630b15d325006c524538839455e584e81942243ba45aa3dc0a3ef2b02ecb8e11c0e658
7
+ data.tar.gz: 0c3028c8e066bab4777a4695eb0e034db9c2de17c7250bb8431f762a01fb63c2f8a611b30626f41d610eec47a45afbf7c0616de84c3a721677a8f51f45af2b9c
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ # t.libs << 'lib'
6
+ t.libs << 'test'
7
+ t.pattern = "test/unit/*_test.rb"
8
+ end
2
9
 
@@ -1,82 +1,67 @@
1
1
  require 'dply/helper'
2
+ require 'dply/curl'
2
3
  require 'uri'
4
+ require 'tmpdir'
5
+
3
6
  module Dply
4
7
  class Archive
5
8
 
6
9
  include Helper
7
10
 
11
+ attr_reader :name, :path, :checksum_path, :uri
12
+
8
13
  def initialize(url, verify_checksum: true)
9
- @url = url
14
+ @uri = URI.parse url
10
15
  @verify_checksum = verify_checksum
16
+ @name = File.basename(uri.path)
17
+ @path = "tmp/archive/#{name}"
18
+ @checksum_path = "tmp/archive/#{name}.md5"
11
19
  end
12
20
 
13
- def extract_to(extraction_path)
14
- download_file if not @downloaded
15
- FileUtils.rm_rf extraction_path if File.exists? extraction_path
16
- FileUtils.mkdir_p extraction_path
17
- cmd "tar xf #{path} -C #{extraction_path}", display: true
21
+ def extract(&block)
22
+ download_file
23
+ Dir.mktmpdir "tmp", "./" do |d|
24
+ extracted = "#{d}/extracted"
25
+ FileUtils.mkdir extracted
26
+ cmd "tar xf #{path} -C #{extracted}", display: true
27
+ yield extracted
28
+ end
29
+ cleanup
18
30
  end
19
31
 
20
- def clean
21
- logger.trace "cleaning cache"
22
- files = [ "tmp/cache/#{name}", "tmp/cache/#{name}.md5" ]
32
+ private
33
+
34
+ def cleanup
35
+ logger.trace "cleaning tmp/archive"
36
+ files = [ path, checksum_path ]
23
37
  files.each { |f| FileUtils.rm f if File.exists? f }
24
38
  end
25
- private
26
39
 
27
40
  def download_file
28
- if File.exists? path
29
- download(uri, path) if not verify_checksum
30
- else
31
- download(uri, path)
41
+ curl.download(uri, path)
42
+ if @verify_checksum
43
+ download_checksum
44
+ error "checksum doesn't match for archive" if not checksum_matches?
32
45
  end
33
- raise if not verify_checksum
34
- @downloaded = true
35
- end
36
-
37
- def uri
38
- @uri ||= URI.parse(@url)
39
46
  end
40
47
 
41
- def name
42
- @name ||= File.basename(uri.path)
43
- end
44
-
45
- def path
46
- @path = "tmp/cache/#{name}"
48
+ def download_checksum
49
+ curl.download("#{uri}.md5", checksum_path)
47
50
  end
48
51
 
49
52
  def checksum
50
- @checksum ||= load_checksum
53
+ File.read(checksum_path).chomp
51
54
  end
52
55
 
53
- def load_checksum
54
- file = "tmp/cache/#{name}.md5"
55
- if File.exists? file
56
- checksum = File.read(file).chomp
57
- return checksum if checksum.size == 32
58
- end
59
- download("#{uri}.md5", file)
60
- checksum = File.read(file).chomp
61
- raise if checksum.size != 32
62
- return checksum
63
- end
64
-
65
- def verify_checksum
66
- return true if not @verify_checksum
56
+ def checksum_matches?
67
57
  require 'digest'
68
58
  computed_checksum = Digest::MD5.file path
69
59
  computed_checksum == checksum
70
60
  end
71
61
 
72
- def download(url, outfile)
73
- logger.bullet "downloading #{url} to #{outfile}"
74
- http_status = `curl -w "%{http_code}" -f -s -o '#{outfile}' '#{url}' `
75
- exit_status = $?.exitstatus
76
- if (http_status != "200" || exit_status != 0)
77
- error "failed to download #{outfile}, http status #{http_status}, exit_status #{exit_status}"
78
- end
62
+ def curl
63
+ @curl ||= Curl.new
79
64
  end
80
-
65
+
81
66
  end
82
67
  end
@@ -1,20 +1,15 @@
1
- require 'dply/shell'
1
+ require 'dply/helper'
2
2
  module Dply
3
3
  class Bundle
4
4
 
5
- include Shell
5
+ include Helper
6
6
 
7
- def initialize(deployment: true)
8
- @deployment = deployment
7
+ def install_deployment
8
+ install(without: ["test", "development"])
9
9
  end
10
10
 
11
- def install
12
- return if not gemfile_exists?
13
- if @deployment
14
- install_deployment
15
- else
16
- install_global
17
- end
11
+ def install_test
12
+ install(without: ["development"])
18
13
  end
19
14
 
20
15
  def rake(task, **args)
@@ -26,42 +21,38 @@ module Dply
26
21
  end
27
22
 
28
23
  def clean
24
+ bundle_without(without: ["development"])
29
25
  cmd "bundle clean"
30
26
  end
31
27
 
32
28
  private
33
29
 
34
- def install_global
35
- exitstatus = system "bundle check > /dev/null"
36
- return if exitstatus
37
- cmd "bundle install -j5"
30
+ def check
31
+ system "bundle check > /dev/null"
38
32
  end
39
33
 
40
- def install_deployment
41
- if deployment_config_present?
42
- exitstatus = system "bundle check > /dev/null"
43
- return if exitstatus
44
- end
34
+ def install(without:[])
35
+ #persists BUNDLE_WITHOUT config
36
+ bundle_without(without: without)
37
+ return if check
45
38
  cmd "bundle install -j5 --deployment"
46
39
  end
47
40
 
48
- def deployment_config_present?
49
- file = ".bundle/config"
50
- if not File.readable? file
51
- return false
52
- end
53
- config = YAML.load_file file
54
- config["BUNDLE_FROZEN"] == "1" && config["BUNDLE_PATH"] == "vendor/bundle"
55
- rescue
56
- return false
41
+ def bundle_without(without: [])
42
+ value = without.join(":")
43
+ cmd "bundle config --local without #{value}", return_output: true
57
44
  end
58
45
 
59
46
  def env
60
- @env ||= env_from_yml
47
+ @env ||= begin
48
+ env = {}
49
+ env.merge! env_from_yml(".env.yml")
50
+ env.merge! env_from_yml("config/env.yml")
51
+ env
52
+ end
61
53
  end
62
54
 
63
- def env_from_yml
64
- path = "config/env.yml"
55
+ def env_from_yml(path)
65
56
  if not File.readable? path
66
57
  logger.debug "skipped loading env from #{path}"
67
58
  return {}
@@ -15,10 +15,8 @@ module Dply
15
15
  def run
16
16
  tar_path = @argv.shift
17
17
  error "tar path not specified" if not tar_path
18
- tar_path = "#{Dir.pwd}/#{tar_path}"
19
- pkgs = PkgsConfig.new.pkgs
20
18
  deplist = Deplist.new(tar_path)
21
- deplist.verify! pkgs
19
+ deplist.verify!
22
20
  end
23
21
 
24
22
  end
@@ -1,5 +1,4 @@
1
- require 'dply/pkgs_config'
2
- require 'dply/yum'
1
+ require 'dply/pkgs'
3
2
  require 'dply/helper'
4
3
 
5
4
  module Dply
@@ -16,8 +15,9 @@ module Dply
16
15
  def run
17
16
  opts.parse!(@argv)
18
17
  error "pkgs.yml cannot be a symlink" if File.symlink? "pkgs.yml"
19
- pkgs = PkgsConfig.new(build_mode: @options[:build_mode]).pkgs
20
- Yum.new(pkgs).install
18
+ pkgs = Pkgs.new
19
+ pkgs.install(build_mode: @options[:build_mode])
20
+ puts "installed"
21
21
  end
22
22
 
23
23
  def opts
@@ -1,5 +1,7 @@
1
1
  require 'dply/helper'
2
2
  require 'fileutils'
3
+ require 'dply/curl'
4
+
3
5
  module Dply
4
6
  class ConfigDownloader
5
7
 
@@ -19,32 +21,14 @@ module Dply
19
21
  logger.debug "skipping to download file #{f}"
20
22
  next
21
23
  end
22
- download f
23
- FileUtils.mv "#{tmpdir}/#{f}", "config/#{f}"
24
+ curl.download f, "config/#{f}"
24
25
  end
25
26
  end
26
27
 
27
28
  private
28
29
 
29
- def download(file)
30
- url = "#{@base_url}/#{file}"
31
- logger.bullet "downloading #{file}"
32
- http_status = `curl -w "%{http_code}" -f -s -o '#{tmpdir}/#{file}' '#{url}' `
33
- exitstatus = $?.exitstatus
34
- if (http_status != "200" || exitstatus != 0 )
35
- error "failed to download #{file}, http status #{http_status}, exitstatus #{exitstatus}"
36
- end
37
- end
38
-
39
- def tmpdir
40
- @tmpdir ||= "tmp/config_dl"
41
- end
42
-
43
- def init_tmpdir
44
- if File.exists? tmpdir
45
- FileUtils.rm_rf tmpdir
46
- end
47
- FileUtils.mkdir_p tmpdir
30
+ def curl
31
+ @curl ||= Curl.new
48
32
  end
49
33
 
50
34
  end
@@ -29,18 +29,18 @@ module Dply
29
29
  @build_url ||= instance_eval(&build_url_proc)
30
30
  end
31
31
 
32
- def revision_proc
33
- @revision_proc ||= Proc.new do
34
- jenkins = Jenkins.new(repo, name)
35
- jenkins.latest_successful_revision
36
- end
37
- end
38
-
39
32
  def build_url_proc
40
33
  @build_url_proc ||= Proc.new do
41
- "#{repo.chomp("/")}/job/#{name}/#{revision}/artifact/build/#{name}-#{revision}-#{branch}.tar.gz"
34
+ "#{repo}/artifacts/#{name}/#{revision}/#{name}-#{revision}-#{branch.to_s.tr("/","_")}.tar.gz"
42
35
  end
43
36
  end
44
37
 
38
+ def dir_map
39
+ @dir_map ||= {
40
+ "tmp" => "tmp",
41
+ "log" => "log"
42
+ }
43
+ end
44
+
45
45
  end
46
46
  end
@@ -0,0 +1,38 @@
1
+ require 'dply/helper'
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+
5
+ module Dply
6
+ class Curl
7
+
8
+ include Helper
9
+
10
+ def initialize(quiet = false)
11
+ @quiet = quiet
12
+ end
13
+
14
+ def download(url, outfile)
15
+ Dir.mktmpdir "tmp", "./" do |d|
16
+ tmpfile = "#{d}/f"
17
+ log "downloading #{url}"
18
+ http_status = `curl -w "%{http_code}" -f -s -o '#{tmpfile}' '#{url}' `
19
+ exit_status = $?.exitstatus
20
+ if (http_status != "200" || exit_status != 0)
21
+ error "failed to download #{outfile}, http status #{http_status}, exit_status #{exit_status}"
22
+ end
23
+ FileUtils.mv tmpfile, outfile
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def log(msg)
30
+ if @quiet
31
+ logger.debug msg
32
+ else
33
+ logger.bullet msg
34
+ end
35
+ end
36
+
37
+ end
38
+ end
@@ -24,22 +24,26 @@ module Dply
24
24
  end
25
25
 
26
26
  def bullet(msg)
27
- puts "#{"\u2219".bold.blue} #{msg}"
27
+ info "#{"\u2219".bold.blue} #{msg}"
28
28
  end
29
29
 
30
30
  def trace(msg)
31
31
  return if not @trace_mode
32
- puts %(#{"T".bold.blue} #{msg}\n)
32
+ info %(#{"T".bold.blue} #{msg}\n)
33
33
  end
34
34
 
35
35
  def remote(msg)
36
36
  return if not @remote_mode
37
- puts %{dply_msg|#{msg}}
37
+ info %{dply_msg|#{msg}}
38
38
  end
39
39
 
40
40
  def marker(msg)
41
41
  return if not @enable_markers
42
- puts "dply_marker:#{msg}"
42
+ info "dply_marker:#{msg}"
43
+ end
44
+
45
+ def silence!
46
+ @logdev = nil
43
47
  end
44
48
 
45
49
  end
@@ -2,6 +2,7 @@ require 'filemagic'
2
2
  require 'elf'
3
3
  require 'dply/helper'
4
4
  require 'dply/rpm'
5
+ require 'dply/pkgs'
5
6
  require 'tmpdir'
6
7
 
7
8
  module Dply
@@ -10,17 +11,34 @@ module Dply
10
11
  include Helper
11
12
 
12
13
  def initialize(path)
13
- @path = path
14
+ if Pathname.new(path).relative?
15
+ @path = "#{Dir.pwd}/#{path}"
16
+ else
17
+ @path = path
18
+ end
14
19
  end
15
20
 
16
- def deps
17
- @deps ||= load_deps
21
+ def verify!
22
+ error "#{@path} not readable" if not File.readable? @path
23
+ tmp_dir do
24
+ logger.info "(in #{Dir.pwd})"
25
+ cmd "tar xf #{@path}"
26
+ pkgs_list = Pkgs.new.runtime
27
+
28
+ @libs_files_map = libs_files_map
29
+ libs = @libs_files_map.keys
30
+
31
+ deps = rpm.libs_packages_map libs
32
+ verify_deps(deps, pkgs_list)
33
+ end
18
34
  end
19
35
 
20
- def verify!(pkgs_list)
21
- deps.each do |pkgs|
36
+ private
37
+
38
+ def verify_deps(deps, pkgs_list)
39
+ deps.each do |lib, pkgs|
22
40
  if not pkgs.any? { |pkg| pkgs_list.include? pkg }
23
- logger.error "missing from pkgs.yml : any of #{pkgs}"
41
+ logger.error "missing from pkgs.yml : any of #{pkgs} (lib: #{lib}, files: #{@libs_files_map[lib]})"
24
42
  @error = true
25
43
  end
26
44
  end
@@ -28,8 +46,6 @@ module Dply
28
46
  puts "all dependencies satisfied".green
29
47
  end
30
48
 
31
- private
32
-
33
49
  def magic
34
50
  @magic ||= begin
35
51
  flags = FileMagic::FLAGS_BY_SYM.select { |k,v| k.to_s =~ /no_check_/ }.keys
@@ -41,17 +57,6 @@ module Dply
41
57
  end
42
58
  end
43
59
 
44
- def load_deps
45
- error "#{@path} not readable" if not File.readable? @path
46
- tmp_dir do
47
- logger.info "(in #{Dir.pwd})"
48
- cmd "tar xf #{@path}"
49
- @libs = get_libs
50
- logger.debug @libs.inspect
51
- @deps = rpm.libs_to_packages @libs
52
- end
53
- end
54
-
55
60
  def tmp_dir(&block)
56
61
  dir = File.exist?("tmp") ? "tmp" : "/tmp"
57
62
  Dir.mktmpdir(nil, dir) do |d|
@@ -59,12 +64,14 @@ module Dply
59
64
  end
60
65
  end
61
66
 
62
- def get_libs
63
- libs = Set.new
67
+ def libs_files_map
68
+ libs = {}
64
69
  Dir["./**/*"].each do |f|
65
70
  type = magic.file(f)
66
- if type =~ /ELF/
67
- dynamic_libs(f).each { |k| libs << k }
71
+ next if not type =~ /ELF/
72
+ dynamic_libs(f).each do |l|
73
+ libs[l] ||= []
74
+ libs[l] << f
68
75
  end
69
76
  end
70
77
  return libs
@@ -1,18 +1,58 @@
1
- require 'dply/shell'
2
- require 'dply/git'
3
1
  require 'dply/error'
2
+ require 'dply/logger'
3
+ require 'fileutils'
4
+ require 'tmpdir'
4
5
 
5
6
  module Dply
6
7
  module Helper
7
8
 
8
- def self.git
9
- Git
9
+ def cmd(command, display: true, error_msg: nil, return_output: false, env:{}, shell: false)
10
+ stringify_values!(env)
11
+ if display
12
+ logger.bullet command
13
+ else
14
+ logger.debug command
15
+ end
16
+ command_arr = command.split
17
+ run_command = shell ? command : command_arr
18
+
19
+ output = if return_output
20
+ IO.popen(env, run_command) { |f| f.read }
21
+ else
22
+ system(env, *run_command, 2 => 1)
23
+ end
24
+ return_value = $?.exitstatus
25
+ error_msg ||= "non zero exit for \"#{command}\""
26
+ error error_msg if return_value != 0
27
+ return output
28
+ end
29
+
30
+ def symlink(src, dst)
31
+ if File.symlink? dst
32
+ Dir.mktmpdir("sym-", "./") do |d|
33
+ dst_tmp = "#{d}/#{File.basename dst}"
34
+ FileUtils.ln_s src, dst_tmp
35
+ cmd "mv #{dst_tmp} #{File.dirname dst}", display: false
36
+ end
37
+ elsif File.exist? dst
38
+ error "cannot create symlink #{dst} => #{src}"
39
+ else
40
+ FileUtils.ln_s src, dst
41
+ end
10
42
  end
11
43
 
12
- include Shell
44
+ def stringify_values!(hash)
45
+ hash.each do |k,v|
46
+ hash[k] = v.to_s
47
+ end
48
+ end
49
+
50
+ def logger
51
+ Logger.logger
52
+ end
13
53
 
14
54
  def git
15
- ::Dply::Helper.git
55
+ Git
16
56
  end
17
57
 
18
58
  def error(msg)
@@ -3,6 +3,10 @@ require 'dply/custom_logger'
3
3
  module Dply
4
4
  module Logger
5
5
 
6
+ class << self
7
+ attr_writer :logger
8
+ end
9
+
6
10
  def self.logger
7
11
  @logger ||= ::Dply::CustomLogger.new(STDOUT)
8
12
  end
@@ -0,0 +1,60 @@
1
+ require 'yaml'
2
+ require 'dply/helper'
3
+ require_relative 'yum'
4
+
5
+ module Dply
6
+ class Pkgs
7
+
8
+ include Helper
9
+
10
+ attr_reader :runtime, :build, :all
11
+
12
+ def initialize(pkgs_yml = nil)
13
+ @pkgs_yml = pkgs_yml || "pkgs.yml"
14
+ read_config
15
+ end
16
+
17
+ def install(build_mode: false, sudo: false)
18
+ pkgs = build_mode ? @all : @runtime
19
+ Yum.new(pkgs, sudo: sudo).install
20
+ end
21
+
22
+ def installed?(build_mode: false)
23
+ pkgs = build_mode ? @all : @runtime
24
+ Yum.new(pkgs).installed?
25
+ end
26
+
27
+ private
28
+
29
+ def read_config
30
+ @read ||= begin
31
+ config = load_yml
32
+ @runtime = config["pkgs"] || []
33
+ @build = config["build_pkgs"] || []
34
+ @all = @runtime + @build
35
+ @all.each { |i| validate! i }
36
+ true
37
+ end
38
+ end
39
+
40
+ def load_yml
41
+ if not File.readable? @pkgs_yml
42
+ logger.debug "skipping yum pkgs"
43
+ return {}
44
+ end
45
+ YAML.safe_load(File.read(@pkgs_yml)) || {}
46
+ rescue => e
47
+ error "error loading pkgs list"
48
+ end
49
+
50
+ def validate!(pkg)
51
+ msg = "invalid pkg name #{pkg}"
52
+ error msg if pkg =~ /\.rpm\z/i
53
+ error msg if pkg =~/\A[A-Za-z_0-9\.\-]\z/
54
+ return true
55
+ end
56
+
57
+ end
58
+ end
59
+
60
+
@@ -10,25 +10,27 @@ module Dply
10
10
  attr_accessor :url, :verify_checksum
11
11
  attr_writer :name
12
12
 
13
- def self.find_or_create(revision, **kwargs)
14
- release = new(revision, **kwargs)
15
- name = find_installed_name(revision, **kwargs)
13
+ def self.find_or_create(**kwargs)
14
+ release = new(**kwargs)
15
+ name = find_installed_name(**kwargs)
16
16
  release.name = name if name
17
17
  return release
18
18
  end
19
19
 
20
- def self.find_installed_name(revision, **kwargs)
21
- branch = kwargs.fetch(:branch).to_s.gsub(/-/, "_").sub("/", "_")
22
- app_name = kwargs.fetch(:app_name).to_s.gsub(/-/, "_")
20
+ def self.find_installed_name(**kwargs)
21
+ branch = kwargs.fetch(:branch).to_s.tr('-/', '__')
22
+ app_name = kwargs.fetch(:app_name).to_s.tr('-/', '__')
23
+ revision = kwargs.fetch(:revision)
24
+
23
25
  name_without_ts = "#{revision}-#{app_name}-#{branch}-"
24
26
  latest = Dir["releases/#{name_without_ts}*"].sort_by { |x, y| File.mtime(x) }.first
25
27
  latest ? File.basename(latest) : nil
26
28
  end
27
29
 
28
- def initialize(revision, app_name: nil, branch: nil, url: nil)
30
+ def initialize(revision:, app_name:, branch:, url:)
29
31
  @revision = revision
30
- @branch = branch.to_s.sub("/", "_")
31
- @app_name = app_name
32
+ @branch = branch.to_s.tr('-/', '__')
33
+ @app_name = app_name.to_s.tr('-/', '__')
32
34
  @url = url
33
35
  end
34
36
 
@@ -39,7 +41,7 @@ module Dply
39
41
  end
40
42
 
41
43
  def name
42
- @name ||= "#{@revision}-#{replace_dashes(@app_name)}-#{replace_dashes(@branch)}-#{timestamp}"
44
+ @name ||= "#{@revision}-#{@app_name}-#{@branch}-#{timestamp}"
43
45
  end
44
46
 
45
47
  def install
@@ -47,12 +49,9 @@ module Dply
47
49
  logger.debug "release #{name} already installed"
48
50
  return
49
51
  end
50
- Dir.mktmpdir "tmp" do |d|
51
- path = "#{d}/#{name}"
52
- archive.extract_to path
53
- FileUtils.mv path, "releases/"
52
+ archive.extract do |path|
53
+ FileUtils.mv path, "releases/#{name}"
54
54
  end
55
- archive.clean
56
55
  end
57
56
 
58
57
  def path
@@ -74,10 +73,6 @@ module Dply
74
73
 
75
74
  private
76
75
 
77
- def replace_dashes(str)
78
- str.to_s.gsub(/-/, "_")
79
- end
80
-
81
76
  def archive
82
77
  @archive ||= Archive.new(url, verify_checksum: @verify_checksum)
83
78
  end
@@ -4,15 +4,17 @@ module Dply
4
4
  class Rpm
5
5
  include Helper
6
6
 
7
- def libs_to_packages(libs)
8
- packages = Set.new
9
- libs.each do |l|
10
- list = whatprovides(l)
11
- packages << list if not list.empty?
7
+ def libs_packages_map(libs)
8
+ h = {}
9
+ libs.each do |lib|
10
+ list = whatprovides(lib)
11
+ h[lib] = list if not list.empty?
12
12
  end
13
- return packages
13
+ return h
14
14
  end
15
15
 
16
+ private
17
+
16
18
  def filtered?(pkg)
17
19
  @filtered ||= ["glibc", "libgcc", "libstdc++", "openssl", "ruby-alt", "jemalloc"]
18
20
  @filtered.include? pkg.strip
@@ -21,9 +23,7 @@ module Dply
21
23
  def whatprovides(lib)
22
24
  lib = "#{lib}()(64bit)"
23
25
  command = %(rpm --queryformat "%{NAME} " -q --whatprovides "#{lib}")
24
- logger.debug command
25
- output = `#{command}`
26
- error "running command #{command}" if not $?.exitstatus == 0
26
+ output = cmd command, return_output: true, shell: true
27
27
  list = output.strip.split.select {|pkg| not filtered? pkg }
28
28
  end
29
29
 
@@ -84,7 +84,8 @@ module Dply
84
84
 
85
85
  def release
86
86
  @release ||= Release.find_or_create(
87
- revision, branch: branch,
87
+ revision: revision,
88
+ branch: branch,
88
89
  app_name: config.name,
89
90
  url: config.build_url
90
91
  )
@@ -118,7 +119,7 @@ module Dply
118
119
  end
119
120
 
120
121
  def tasks
121
- @tasks ||= Tasks.new(deployment: true)
122
+ @tasks ||= Tasks.new
122
123
  end
123
124
 
124
125
  def prune_releases
@@ -89,7 +89,7 @@ module Dply
89
89
  end
90
90
 
91
91
  def tasks
92
- @tasks ||= Tasks.new(deployment: true)
92
+ @tasks ||= Tasks.new
93
93
  end
94
94
 
95
95
  end
@@ -1,38 +1,32 @@
1
1
  require 'json'
2
- require 'dply/shell'
2
+ require 'dply/helper'
3
3
  require 'dply/bundle'
4
- require 'dply/yum'
5
4
  require 'dply/linker'
6
- require 'dply/pkgs_config'
7
- require 'dply/error'
5
+ require 'dply/pkgs'
8
6
  require 'etc'
9
7
 
10
8
  module Dply
11
9
  class Tasks
12
10
 
13
- include Shell
14
-
15
- def initialize(deployment: true)
16
- @deployment = deployment
17
- end
11
+ include Helper
18
12
 
19
13
  def deploy(target)
20
- bundle.install
14
+ bundle.install_deployment
21
15
  rake "#{target}:deploy"
22
16
  end
23
17
 
24
18
  def reload(target)
25
- bundle.install
19
+ bundle.install_deployment
26
20
  rake "#{target}:reload"
27
21
  end
28
22
 
29
23
  def task(task)
30
- bundle.install
24
+ bundle.install_deployment
31
25
  rake task
32
26
  end
33
27
 
34
28
  def build(task)
35
- bundle.install
29
+ bundle.install_deployment
36
30
  bundle.clean
37
31
  rake task
38
32
  end
@@ -50,13 +44,12 @@ module Dply
50
44
 
51
45
  def install_pkgs(build_mode: false, use_yum: false)
52
46
  return if not File.exists? "pkgs.yml"
47
+ return if pkgs.installed?(build_mode: build_mode)
53
48
  drake_exists = File.exists? (drake_command)
54
49
 
55
- pkgs = get_pkgs(build_mode)
56
50
  if use_yum || !drake_exists
57
- yum_install pkgs
51
+ pkgs.install(build_mode: build_mode, sudo: true)
58
52
  else
59
- return if Yum.new(pkgs).installed?
60
53
  command_install build_mode
61
54
  end
62
55
  end
@@ -72,15 +65,11 @@ module Dply
72
65
  private
73
66
 
74
67
  def bundle
75
- @bundle ||= Bundle.new(deployment: @deployment)
76
- end
77
-
78
- def get_pkgs(build_mode)
79
- PkgsConfig.new(build_mode: build_mode).pkgs
68
+ @bundle ||= Bundle.new
80
69
  end
81
70
 
82
- def yum_install(pkgs)
83
- Yum.new(pkgs, sudo: true).install
71
+ def pkgs
72
+ @pkgs ||= Pkgs.new
84
73
  end
85
74
 
86
75
  def command_install(build_mode)
@@ -1,3 +1,3 @@
1
1
  module Dply
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
@@ -6,11 +6,7 @@ module Dply
6
6
  include Helper
7
7
 
8
8
  def initialize(pkgs, sudo: false)
9
- if pkgs.is_a? Set
10
- @pkgs = pkgs.to_a
11
- else
12
- @pkgs = pkgs
13
- end
9
+ @pkgs = pkgs
14
10
  @sudo = sudo
15
11
  end
16
12
 
@@ -23,7 +23,14 @@ module Dplyr
23
23
  when 'local'
24
24
  system "drake #{global_switches.join(" ")} #{argv_str}"
25
25
  else
26
- run_remote_task
26
+ command = argv[0]
27
+ case command
28
+ when "list"
29
+ require 'pp'
30
+ pp hosts
31
+ else
32
+ run_remote_task
33
+ end
27
34
  end
28
35
  end
29
36
 
@@ -0,0 +1,28 @@
1
+ require 'open-uri'
2
+ require 'json'
3
+ require 'dply/error'
4
+
5
+ module Dplyr
6
+ class Consul
7
+
8
+ def hosts(app_name, service: "app")
9
+ uri = "http://127.0.0.1:8500/v1/catalog/service/#{service}?tag=#{app_name}"
10
+ response = JSON.parse(open(uri).read)
11
+ hosts = []
12
+ response.each do |i|
13
+ host = {}
14
+ metadata_tag = i["ServiceTags"].find {|t| t =~ /\Ametadata:/}
15
+ metadata = metadata_tag ? JSON.parse(metadata_tag.partition(":")[2]) : {}
16
+ host[:user] = metadata["user"]
17
+ host[:dir] = metadata["dir"]
18
+ host[:addr] = i["Address"]
19
+ host[:id] = i["Node"]
20
+ hosts << host
21
+ end
22
+ hosts
23
+ rescue
24
+ raise ::Dply::Error, "failed to load hosts from consul"
25
+ end
26
+
27
+ end
28
+ end
@@ -1,4 +1,5 @@
1
1
  require 'dply/helper'
2
+ require_relative 'consul'
2
3
 
3
4
  module Dplyr
4
5
  class Stage
@@ -11,6 +12,8 @@ module Dplyr
11
12
  @name = name.to_sym
12
13
  @hosts = []
13
14
  @parallel_runs = 1
15
+ @dir = nil
16
+ @user = nil
14
17
  end
15
18
 
16
19
  def data
@@ -44,18 +47,31 @@ module Dplyr
44
47
  @parallel_runs = parallel_runs
45
48
  end
46
49
 
47
- def fill_hosts
48
- @hosts.each do |host|
49
- host[:user] ||= fetch(:user)
50
- host[:dir] ||= fetch(:dir)
50
+ def consul(app_name, service: "app")
51
+ consul = Consul.new
52
+ consul.hosts(app_name, service: service).each do |i|
53
+ host(i[:addr], user: i[:user], dir: i[:dir], id: i[:id])
51
54
  end
52
55
  end
53
56
 
54
57
  alias_method :deploy_dir, :dir
55
58
 
59
+ private
60
+
61
+ def fill_hosts
62
+ @hosts.each do |host|
63
+ begin
64
+ host[:user] ||= fetch(:user)
65
+ host[:dir] ||= fetch(:dir)
66
+ rescue
67
+ error "user/dir not specified for #{host[:id]}"
68
+ end
69
+ end
70
+ end
71
+
56
72
  def fetch(var)
57
73
  value = instance_variable_get("@#{var}")
58
- raise "error accessing var #{var} for stage #{name}" if not value
74
+ error "error accessing var #{var} for stage #{name}" if not value
59
75
  return value
60
76
  end
61
77
 
@@ -38,9 +38,9 @@ module Dplyr
38
38
 
39
39
  def run_in_parallel
40
40
  if @auto_serialize
41
- execute_serially hosts[0]
42
- execute_in_parallel Range.new(1,hosts.size - 2)
43
- execute_serially hosts[-1]
41
+ t = execute_serially hosts[0]
42
+ return if t.exit_status != 0
43
+ execute_in_parallel Range.new(1,hosts.size - 1)
44
44
  else
45
45
  execute_in_parallel Range.new(0, hosts.size - 1)
46
46
  end
@@ -0,0 +1 @@
1
+ 642071a065e730cdb86fa3b6892ff619
@@ -0,0 +1,23 @@
1
+ require_relative 'webserver'
2
+ require 'minitest/reporters'
3
+ require 'minitest/autorun'
4
+
5
+ class Minitest::Test
6
+
7
+ def self.test(name, &block)
8
+ method_name = "test_: #{name}".to_sym
9
+ define_method method_name, &block
10
+ end
11
+
12
+ end
13
+
14
+
15
+ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
16
+
17
+ require 'fileutils'
18
+ FileUtils.mkdir_p "tmp/archive"
19
+
20
+ if not ENV['DEBUG']
21
+ require 'dply/logger'
22
+ Dply::Logger.logger.silence!
23
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+ require 'dply/archive'
3
+
4
+ module Dply
5
+ class ArchiveTest < Minitest::Test
6
+ def setup
7
+ url = "http://127.0.0.1:8000/build.tar.gz"
8
+ @name = "build.tar.gz"
9
+ @path = "tmp/archive/build.tar.gz"
10
+ @checksum_path = "tmp/archive/build.tar.gz.md5"
11
+ @archive = Archive.new(url, verify_checksum: true)
12
+ end
13
+
14
+ def teardown
15
+ @archive = nil
16
+ end
17
+
18
+ test "#new" do
19
+ assert_equal @archive.name, @name
20
+ assert_equal @archive.path, @path
21
+ assert_equal @archive.checksum_path, @checksum_path
22
+ end
23
+
24
+ test ".extract" do
25
+ @archive.extract do |d|
26
+ assert File.exist? "#{d}/code"
27
+ end
28
+ [@path, @checksum_path].each do |f|
29
+ refute File.exist?(f), msg: "cache file not deleted #{f}"
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+ require 'dply/curl'
3
+ require 'tmpdir'
4
+
5
+ module Dply
6
+ class CurlTest < Minitest::Test
7
+
8
+ def url
9
+ @url ||= "http://127.0.0.1:8000/build.tar.gz"
10
+ end
11
+
12
+ test "#download" do
13
+
14
+ Dir.mktmpdir do |dir|
15
+ f = "#{dir}/f"
16
+ curl = Curl.new
17
+ curl.download(url, f)
18
+ assert File.exist? f
19
+ end
20
+ end
21
+
22
+
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ require 'webrick'
2
+ class ::WEBrick::BasicLog
3
+ def log(level, data)
4
+ # nop
5
+ end
6
+ end
7
+ port = 8000
8
+ webserver = Thread.new do
9
+ WEBrick::HTTPServer.new(
10
+ :Port => port,
11
+ :DocumentRoot => "#{Dir.pwd}/test/sample_data",
12
+ Logger: WEBrick::Log.new("/dev/null"),
13
+ AccessLog: []
14
+ ).start
15
+ end
16
+ puts "staring webserver on port #{port}"
17
+ webserver.run
18
+
19
+ at_exit { Thread.kill webserver }
20
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dply
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neeraj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-10 00:00:00.000000000 Z
11
+ date: 2015-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-elf
@@ -108,6 +108,7 @@ files:
108
108
  - lib/dply/config.rb
109
109
  - lib/dply/config_downloader.rb
110
110
  - lib/dply/config_struct.rb
111
+ - lib/dply/curl.rb
111
112
  - lib/dply/custom_logger.rb
112
113
  - lib/dply/deplist.rb
113
114
  - lib/dply/error.rb
@@ -118,14 +119,13 @@ files:
118
119
  - lib/dply/linker.rb
119
120
  - lib/dply/lock.rb
120
121
  - lib/dply/logger.rb
121
- - lib/dply/pkgs_config.rb
122
+ - lib/dply/pkgs.rb
122
123
  - lib/dply/release.rb
123
124
  - lib/dply/release_helper.rb
124
125
  - lib/dply/repo.rb
125
126
  - lib/dply/rpm.rb
126
127
  - lib/dply/setup.rb
127
128
  - lib/dply/shared_dirs.rb
128
- - lib/dply/shell.rb
129
129
  - lib/dply/strategy.rb
130
130
  - lib/dply/strategy/archive.rb
131
131
  - lib/dply/strategy/git.rb
@@ -136,12 +136,19 @@ files:
136
136
  - lib/dply/version.rb
137
137
  - lib/dply/yum.rb
138
138
  - lib/dplyr/cli.rb
139
+ - lib/dplyr/consul.rb
139
140
  - lib/dplyr/remote_task.rb
140
141
  - lib/dplyr/report.rb
141
142
  - lib/dplyr/stage.rb
142
143
  - lib/dplyr/stages_config.rb
143
144
  - lib/dplyr/task_runner.rb
144
145
  - lib/dplyr/tasks_config.rb
146
+ - test/sample_data/build.tar.gz
147
+ - test/sample_data/build.tar.gz.md5
148
+ - test/test_helper.rb
149
+ - test/unit/archive_test.rb
150
+ - test/unit/curl_test.rb
151
+ - test/webserver.rb
145
152
  homepage: ''
146
153
  licenses:
147
154
  - MIT
@@ -162,8 +169,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
169
  version: '0'
163
170
  requirements: []
164
171
  rubyforge_project:
165
- rubygems_version: 2.4.5
172
+ rubygems_version: 2.4.5.1
166
173
  signing_key:
167
174
  specification_version: 4
168
175
  summary: rake based deploy tool
169
- test_files: []
176
+ test_files:
177
+ - test/sample_data/build.tar.gz
178
+ - test/sample_data/build.tar.gz.md5
179
+ - test/test_helper.rb
180
+ - test/unit/archive_test.rb
181
+ - test/unit/curl_test.rb
182
+ - test/webserver.rb
@@ -1,63 +0,0 @@
1
- require 'set'
2
- require 'yaml'
3
- require 'dply/helper'
4
-
5
- module Dply
6
- class PkgsConfig
7
-
8
- include Helper
9
-
10
- def initialize(pkgs_yml = nil, build_mode: false)
11
- @pkgs_yml = pkgs_yml || "pkgs.yml"
12
- @build_mode = build_mode
13
- @pkgs = Set.new
14
- end
15
-
16
- def pkgs
17
- populate_all if not @populated
18
- @pkgs
19
- end
20
-
21
- private
22
-
23
- def config
24
- @config ||= load_yml
25
- end
26
-
27
- def load_yml
28
- if not File.readable? @pkgs_yml
29
- logger.debug "skipping yum pkgs"
30
- return {}
31
- end
32
- YAML.safe_load(File.read(@pkgs_yml)) || {}
33
- rescue => e
34
- error "error loading pkgs list"
35
- end
36
-
37
- def populate_all
38
- populate :pkgs
39
- populate :build_pkgs if @build_mode
40
- @populated = true
41
- end
42
-
43
- def populate(pkg_set)
44
- list = config[pkg_set.to_s] || []
45
- list.each { |x| add x }
46
- end
47
-
48
- def add(pkg)
49
- pkg = pkg.strip
50
- validate! pkg
51
- @pkgs << pkg
52
- end
53
-
54
- def validate!(pkg)
55
- msg = "invalid pkg name #{pkg}"
56
- error msg if pkg =~ /\.rpm\z/i
57
- error msg if pkg =~/\A[A-Za-z_0-9\.\-]\z/
58
- end
59
-
60
- end
61
- end
62
-
63
-
@@ -1,57 +0,0 @@
1
- require 'dply/error'
2
- require 'dply/logger'
3
-
4
- module Dply
5
- module Shell
6
-
7
- include Logger
8
-
9
- def cmd(command, display: true, error_msg: nil, return_output: false, env:{})
10
- stringify_values(env)
11
- if display
12
- puts "#{"\u2219".bold.blue} #{command}"
13
- else
14
- logger.debug command
15
- end
16
- command_arr = command.split
17
-
18
- if return_output
19
- output = IO.popen(env, command_arr) { |f| f.read }
20
- else
21
- output = ""
22
- system(env, *command_arr, 2 => 1)
23
- end
24
- return_value = $?.exitstatus
25
- error_msg ||= "non zero exit for \"#{command}\""
26
- raise ::Dply::Error, error_msg if return_value !=0
27
- return output
28
- end
29
-
30
- def symlink(src, dst)
31
- if File.symlink? dst
32
- FileUtils.rm dst
33
- FileUtils.ln_s src, dst
34
- elsif File.exist? dst
35
- raise "cannot create symlink #{dst} => #{src}"
36
- else
37
- FileUtils.ln_s src, dst
38
- end
39
- end
40
-
41
- def symlink_in_dir(src,destdir)
42
- if not Dir.exist? destdir
43
- raise "symlink destination not a dir"
44
- end
45
- src_path = Pathname.new(src)
46
- dst = "#{destdir}/#{src_path.basename}"
47
- symlink src, dst
48
- end
49
-
50
- def stringify_values(hash)
51
- hash.each do |k,v|
52
- hash[k] = v.to_s
53
- end
54
- end
55
-
56
- end
57
- end