dply 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/dply/git.rb CHANGED
@@ -23,6 +23,11 @@ module Dply
23
23
  cmd "git clone #{repo} #{dir}"
24
24
  end
25
25
 
26
+ def self.clean
27
+ cmd "git reset --hard HEAD"
28
+ cmd "git clean -dxf "
29
+ end
30
+
26
31
  def self.get_tracking_branch(branch)
27
32
  command = "git for-each-ref --format='%(upstream:short)' refs/heads/#{branch} --count=1"
28
33
  tracking_branch = `#{command}`
data/lib/dply/helper.rb CHANGED
@@ -2,7 +2,6 @@ require 'dply/tasks'
2
2
  require 'dply/shell'
3
3
  require 'dply/git'
4
4
  require 'dply/error'
5
- require 'dply/logger'
6
5
 
7
6
 
8
7
  module Dply
@@ -12,23 +11,14 @@ module Dply
12
11
  Git
13
12
  end
14
13
 
15
- def self.tasks
16
- @tasks ||= Tasks.new
17
- end
18
-
19
14
  include Shell
20
- include Logger
21
15
 
22
16
  def git
23
17
  ::Dply::Helper.git
24
18
  end
25
19
 
26
- def tasks
27
- ::Dply::Helper.tasks
28
- end
29
-
30
20
  def error(msg)
31
- ::Dply::Error.new(msg)
21
+ raise ::Dply::Error, msg
32
22
  end
33
23
 
34
24
  end
@@ -0,0 +1,32 @@
1
+ require 'open-uri'
2
+ require 'json'
3
+ require 'dply/helper'
4
+
5
+ module Dply
6
+ class Jenkins
7
+
8
+ include Helper
9
+
10
+ def initialize(url, project)
11
+ @url = URI.parse(url)
12
+ @project = project
13
+ validate
14
+ end
15
+
16
+ def latest_successful_revision
17
+ api_url = "#{@url}/job/#{@project}/api/json"
18
+ logger.debug "using jenkins api \"#{api_url}\""
19
+ open(api_url) do |f|
20
+ json = JSON.parse(f.read)
21
+ revision = json["lastSuccessfulBuild"]["number"]
22
+ logger.debug "got revision #{revision}"
23
+ revision
24
+ end
25
+ end
26
+
27
+ def validate
28
+ raise "invalid uri " if not ["http", "https"].include? @url.scheme
29
+ raise "project name not defined" if not @project
30
+ end
31
+ end
32
+ end
data/lib/dply/lock.rb CHANGED
@@ -1,23 +1,27 @@
1
- require 'dply/helper'
1
+ require 'dply/logger'
2
2
  module Dply
3
3
  class Lock
4
4
 
5
- include Helper
6
- attr_accessor :deploy_dir
5
+ include Logger
7
6
 
8
- def initialize(deploy_dir)
9
- @deploy_dir = deploy_dir
7
+ def initialize(dir = nil)
8
+ @dir = dir
9
+ end
10
+
11
+ def acquire
12
+ logger.debug "acquiring lock"
13
+ lock_acquired = lock_file.flock(File::LOCK_NB | File::LOCK_EX)
14
+ raise "exclusive lock not available" if not lock_acquired
10
15
  end
11
16
 
12
17
  def lock_file
13
- @lock_file ||= Dir.chdir(deploy_dir) do
14
- File.open(".dply.lock", "w+")
15
- end
18
+ @lock_file ||= File.open("#{dir}/.dply.lock", "a+")
16
19
  end
17
20
 
18
- def acquire
19
- logger.debug "acquiring exclusive lock"
20
- lock_file.flock(File::LOCK_EX)
21
+ private
22
+
23
+ def dir
24
+ @dir ||= Dir.pwd
21
25
  end
22
26
 
23
27
  end
data/lib/dply/release.rb CHANGED
@@ -1,33 +1,75 @@
1
+ require 'dply/archive'
2
+ require 'dply/helper'
3
+ require 'tmpdir'
4
+
1
5
  module Dply
2
6
  class Release
3
7
 
4
- attr_reader release_dir
8
+ include Helper
9
+
10
+ attr_accessor :url, :verify_checksum
11
+ attr_reader :name
12
+
13
+ def initialize(revision, app_name: nil, branch: nil, url: nil)
14
+ @revision = revision
15
+ @branch = branch
16
+ @app_name = app_name
17
+ @url = url
18
+ end
19
+
20
+ def make_current
21
+ raise "cannot make not installed release current" if not installed?
22
+ raise "release path #{path} doesn't exist" if not File.directory? path
23
+ symlink path, "current"
24
+ end
25
+
26
+ def install
27
+ return if installed?
28
+ @name = name_without_ts + timestamp
29
+ Dir.mktmpdir "tmp" do |d|
30
+ path = "#{d}/#{name}"
31
+ archive.extract_to path
32
+ FileUtils.mv path, "releases"
33
+ end
34
+ @installed = true
35
+ archive.clean
36
+ end
37
+
38
+ def path
39
+ @path ||= "releases/#{@name}"
40
+ end
41
+
42
+ private
5
43
 
6
- def initialize(release_dir)
7
- @release_dir = release_dir
44
+ def replace_dashes(str)
45
+ str.to_s.gsub(/-/, "_")
8
46
  end
9
47
 
10
- def create(repo_cache, branch)
11
- return if exists?
12
- FileUtils.mkdir uncommited_release_dir
13
- copy_source_code(repo_cache, branch)
48
+ def archive
49
+ @archive ||= Archive.new(url, verify_checksum: @verify_checksum)
14
50
  end
15
51
 
16
- def copy_source_code(repo_cache, branch)
17
- cmd "git archive #{branch} | tar -x -f - -C #{uncommited_release_dir}"
52
+ def timestamp
53
+ Time.now.strftime "%Y%m%d%H%M%S"
18
54
  end
19
55
 
20
- def exists?
21
- File.exists? (release_dir) || File.exists? (uncommited_release_dir)
56
+ def load_status
57
+ name = name_without_ts
58
+ latest = Dir["releases/#{name}*"].sort_by { |x, y| File.mtime(x) }.first
59
+ if latest
60
+ @installed = true
61
+ @name = File.basename latest
62
+ end
63
+ @status_loaded = true
22
64
  end
23
65
 
24
- def uncommited_release_dir
25
- "#{release_dir}.uncommited"
66
+ def installed?
67
+ load_status if not @status_loaded
68
+ @installed
26
69
  end
27
70
 
28
- def commit
29
- return if File.exists? (release_dir)
30
- FileUtils.mv uncommited_release_dir, release_dir
71
+ def name_without_ts
72
+ @name_without_ts ||= "#{@revision}-#{replace_dashes(@app_name)}-#{replace_dashes(@branch)}-"
31
73
  end
32
74
 
33
75
  end
data/lib/dply/setup.rb CHANGED
@@ -1,11 +1,52 @@
1
+ require 'fileutils'
2
+ require 'dply/helper'
3
+ require 'dply/repo'
4
+ require 'dply/shared_dirs'
5
+
1
6
  module Dply
2
- module Setup
7
+ class Setup
8
+
9
+ include Helper
10
+
11
+ def initialize(config)
12
+ @config = config
13
+ end
14
+
15
+ def build
16
+ dirs = ["config", "shared", "build"]
17
+ create_repo if @config.git
18
+ create_dirs dirs
19
+ create_shared_dirs
20
+ end
21
+
22
+ def git
23
+ dirs = ["config", "shared"]
24
+ create_repo
25
+ symlink "repo", "current"
26
+ create_dirs dirs
27
+ create_shared_dirs
28
+ end
29
+
30
+ def archive
31
+ dirs = ["config", "shared", "releases", "tmp/cache"]
32
+ create_dirs dirs
33
+ create_shared_dirs
34
+ end
35
+
36
+ private
37
+
38
+ def create_repo
39
+ repo = ::Dply::Repo.new("repo", @config.repo)
40
+ repo.create
41
+ end
42
+
43
+ def create_dirs(dirs)
44
+ FileUtils.mkdir_p dirs
45
+ end
3
46
 
4
- def self.load(strategy, config)
5
- require_relative "setup/#{strategy}"
6
- const = "::Dply::Setup::#{strategy.capitalize}"
7
- const = Module.const_get(const)
8
- return const.new(config)
47
+ def create_shared_dirs
48
+ shared_dirs = SharedDirs.new(@config.shared_dirs)
49
+ shared_dirs.create_in "shared"
9
50
  end
10
51
 
11
52
  end
data/lib/dply/shell.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'dply/error'
2
+ require 'dply/logger'
2
3
 
3
4
  module Dply
4
5
  module Shell
@@ -12,11 +13,13 @@ module Dply
12
13
  else
13
14
  logger.debug command
14
15
  end
16
+ command_arr = command.split
17
+
15
18
  if return_output
16
- output = `#{env_str(env)} #{command}`
19
+ output = IO.popen(env, command_arr) { |f| f.read }
17
20
  else
18
21
  output = ""
19
- system env, "#{command} 2>&1"
22
+ system(env, *command_arr, 2 => 1)
20
23
  end
21
24
  return_value = $?.exitstatus
22
25
  error_msg ||= "non zero exit for \"#{command}\""
@@ -44,14 +47,6 @@ module Dply
44
47
  symlink src, dst
45
48
  end
46
49
 
47
- def env_str(env)
48
- str = ""
49
- env.each do |k,v|
50
- str << %(#{k}="#{v.to_s}")
51
- end
52
- str
53
- end
54
-
55
50
  def stringify_values(hash)
56
51
  hash.each do |k,v|
57
52
  hash[k] = v.to_s
@@ -90,12 +90,12 @@ module Dply
90
90
 
91
91
  def read_from_file
92
92
  if not File.readable? config_file
93
- raise error "#{config_file} not readable"
93
+ error "#{config_file} not readable"
94
94
  return
95
95
  end
96
96
  instance_eval(File.read(config_file), config_file)
97
97
  rescue NoMethodError => e
98
- raise "invalid option used in config: #{e.name} #{e.message}"
98
+ error "invalid option used in config: #{e.name} #{e.message}"
99
99
  end
100
100
 
101
101
 
@@ -0,0 +1,124 @@
1
+ require 'dply/helper'
2
+ require 'dply/setup'
3
+ require 'dply/linker'
4
+ require 'dply/config_downloader'
5
+ require 'dply/yum'
6
+ require 'dply/release'
7
+ require 'forwardable'
8
+
9
+
10
+ module Dply
11
+ module Strategy
12
+ class Archive
13
+
14
+ extend Forwardable
15
+ include Helper
16
+
17
+ attr_reader :config, :options
18
+ def_delegators :config, :target, :branch, :revision, :name,
19
+ :config_map, :dir_map, :config_skip_download,
20
+ :config_download_url, :build_url
21
+
22
+ def initialize(config, options)
23
+ @config = config
24
+ @options = options || {}
25
+ end
26
+
27
+ def deploy
28
+ setup.archive
29
+ download_configs if config_download_url
30
+ install_release
31
+ release.make_current
32
+ previous_version = get_release
33
+ Dir.chdir current_dir do
34
+ tasks.deploy target
35
+ end
36
+ current_version = get_release
37
+ tasks.report_changes(previous_version, current_version)
38
+ end
39
+
40
+ def reload
41
+ download_configs if config_download_url
42
+ Dir.chdir current_dir do
43
+ link_dirs
44
+ link_config
45
+ tasks.reload target
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def current_dir
52
+ @current_dir ||= "#{config.dir}/current"
53
+ end
54
+
55
+ def get_release
56
+ File.basename (File.readlink current_dir)
57
+ end
58
+
59
+ def download_configs
60
+ files = config_map.values.uniq
61
+ downloader = ConfigDownloader.new(files, config_download_url)
62
+ downloader.skip_download = config_skip_download
63
+ downloader.download_all
64
+ end
65
+
66
+ def release
67
+ @release ||= Release.new(
68
+ revision, branch: branch,
69
+ app_name: config.name,
70
+ url: config.build_url
71
+ )
72
+ end
73
+
74
+ def install_release
75
+ release.verify_checksum = config.verify_checksum
76
+ release.install
77
+ Dir.chdir release.path do
78
+ link_dirs
79
+ link_config
80
+ yum_install
81
+ end
82
+ end
83
+
84
+ def yum_install
85
+ Yum.new("pkgs.yml").install
86
+ end
87
+
88
+ def git_step
89
+ return if options[:skip_git]
90
+ if options[:no_pull]
91
+ git.checkout branch
92
+ else
93
+ git.pull branch
94
+ end
95
+ end
96
+
97
+ def link_dirs
98
+ link "#{config.dir}/shared", dir_map
99
+ end
100
+
101
+ def link_config
102
+ link "#{config.dir}/config", config_map
103
+ end
104
+
105
+ def setup
106
+ @setup ||= Setup.new(@config)
107
+ end
108
+
109
+ def tasks
110
+ @tasks ||= Tasks.new(deployment: true)
111
+ end
112
+
113
+ def link(source, map)
114
+ return if not map
115
+ logger.bullet "symlinking #{source}"
116
+ dest = "#{config.dir}/#{release.path}"
117
+ linker = Linker.new(source, dest, map: map)
118
+ linker.create_symlinks
119
+ end
120
+
121
+
122
+ end
123
+ end
124
+ end