autodeploy 0.0.3 → 0.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46751e33ef5ccb5333b1ab00092f52995bef8ce4
4
- data.tar.gz: 1736806359124af7e527e285bcab54debe988659
3
+ metadata.gz: 2f7a38b2c1acdf70874ef655a05c22ddf38a68e7
4
+ data.tar.gz: df182975d1f94091d312a71688c5516d069aa66b
5
5
  SHA512:
6
- metadata.gz: a4f29c848c3f485032978d13f5207e5bfcac0da1a76bd898324adc52ca5b6a1cf1b337bf956e7e2bd97390f85994d9538c48724183a1ef6604bf5b33559a312a
7
- data.tar.gz: 05e059b3c6be8f10ceab82bcf1b675f60b28c38e6ed6b39fe3a5b89cbbc9bed569beed68fa378230ec1d21db4a34254d3e6bacae13aaf322e758fe18256dc20b
6
+ metadata.gz: 0113541e0b016ebd29936fab70a25636d75a7bd56c4e5b56c7d0b84e4bbb90cd6dd69c9fb221a51c7661edee0168f87ed578a45545b7ceaae0e2787fcce73df3
7
+ data.tar.gz: 2a30e625e887bd4f4b09da12cbe3bb24d78ddab9e169adb1d0e049ce3ce43f10a61a00d0b45426360f30647db6ea127ddc1c8bc0b7993f5cdd7f3049ee68cbca
data/.gitignore CHANGED
@@ -17,3 +17,4 @@ test/version_tmp
17
17
  tmp
18
18
  config.yml
19
19
  downloads/
20
+ .idea/
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+
3
4
  # Specify your gem's dependencies in autodeploy.gemspec
4
5
  gemspec
data/Rakefile CHANGED
@@ -1 +1,40 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ require 'rspec/core/rake_task'
5
+
6
+ require 'active_record'
7
+ require 'yaml'
8
+ require 'mysql2'
9
+
10
+
11
+ RSpec::Core::RakeTask.new('spec')
12
+ task :default => :spec
13
+
14
+ namespace :db do
15
+
16
+ desc "Migrate the db"
17
+ task :migrate do
18
+ connection_details = YAML::load(File.open('config/database.yml'))
19
+ ActiveRecord::Base.establish_connection(connection_details)
20
+ ActiveRecord::Migrator.migrate("lib/db/migrate/")
21
+ end
22
+
23
+ desc "Create the db"
24
+ task :create do
25
+ connection_details = YAML::load(File.open('config/database.yml'))
26
+ admin_connection = connection_details.merge({'database'=> 'mysql',
27
+ 'schema_search_path'=> 'public'})
28
+ ActiveRecord::Base.establish_connection(admin_connection)
29
+ ActiveRecord::Base.connection.create_database(connection_details.fetch('database'))
30
+ end
31
+
32
+ desc "drop the db"
33
+ task :drop do
34
+ connection_details = YAML::load(File.open('config/database.yml'))
35
+ admin_connection = connection_details.merge({'database'=> 'mysql',
36
+ 'schema_search_path'=> 'public'})
37
+ ActiveRecord::Base.establish_connection(admin_connection)
38
+ ActiveRecord::Base.connection.drop_database(connection_details.fetch('database'))
39
+ end
40
+ end
@@ -20,7 +20,10 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
23
24
 
24
25
  spec.add_dependency 'jenkins_api_client'
25
26
  spec.add_dependency 'dante'
27
+ spec.add_dependency 'activerecord'
28
+ spec.add_dependency 'mysql2'
26
29
  end
@@ -5,21 +5,32 @@ require 'jenkins_api_client'
5
5
  require 'date'
6
6
 
7
7
  require "autodeploy/version"
8
+ require 'active_record'
9
+ require File.expand_path('../autodeploy/models/deploy_build', __FILE__)
10
+ require File.expand_path('../autodeploy/models/deploy_lock', __FILE__)
11
+ require File.expand_path('../autodeploy/models/deploy_audit', __FILE__)
12
+ require File.expand_path('../autodeploy/deployer', __FILE__)
13
+
14
+
8
15
 
9
16
  module Autodeploy
17
+ def self.log(message)
18
+ puts "[#{DateTime.now.strftime}] #{message}"
19
+ end
20
+
10
21
  class Job
11
- def log(message)
12
- puts "[#{DateTime.now.strftime}] #{message}"
13
- end
14
22
 
15
23
  def initialize(configfile)
16
- @config = YAML.load_file(configfile)
17
- @client = JenkinsApi::Client.new(@config)
24
+ @config = YAML.load_file(configfile)
25
+ @client = JenkinsApi::Client.new(@config)
18
26
 
19
- unless Dir.exist? @config['download_dir']
20
- log "Creating #{@config['download_dir']} in #{Dir.pwd}"
21
- Dir.mkdir @config['download_dir']
22
- end
27
+ unless Dir.exist? @config['download_dir']
28
+ Autodeploy.log "Creating #{@config['download_dir']} in #{Dir.pwd}"
29
+ Dir.mkdir @config['download_dir']
30
+ end
31
+
32
+ puts @config
33
+ ActiveRecord::Base.establish_connection(@config['database'])
23
34
  end
24
35
 
25
36
  def job_number
@@ -31,19 +42,25 @@ module Autodeploy
31
42
  end
32
43
 
33
44
  def run
45
+ @deployer = Autodeploy::Deployer.new(@config, job)
46
+ @deployer.run()
47
+
34
48
  return unless job['result'] == 'SUCCESS'
35
49
 
36
- filename = "#{job_number}-#{job['artifacts'][0]['fileName']}"
50
+ build_action = job['actions'].detect{|action| action.include?('lastBuiltRevision')}
51
+ sha = build_action.nil? ? nil : build_action['lastBuiltRevision']['SHA1']
52
+
53
+ filename = [job_number, sha, job['artifacts'][0]['fileName']].compact.join('-')
37
54
  filepath = File.join(@config['download_dir'], filename)
38
55
 
39
56
  if File.exists?(filepath)
40
- log "#{filepath} already exists"
57
+ Autodeploy.log "#{filepath} already exists"
41
58
  return
42
59
  end
43
60
 
44
61
  uri = URI("#{job['url']}artifact/#{job['artifacts'][0]['relativePath']}")
45
62
 
46
- log "Starting download: #{uri.path}"
63
+ Autodeploy.log "Starting download: #{uri.path}"
47
64
 
48
65
  Net::HTTP.start(uri.host, uri.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
49
66
  request = Net::HTTP::Get.new uri.request_uri
@@ -52,20 +69,20 @@ module Autodeploy
52
69
  resp = http.request(request)
53
70
 
54
71
  if resp.code != "200"
55
- log "Error downloading artifact: #{resp.code} - #{resp.message}"
72
+ Autodeploy.log "Error downloading artifact: #{resp.code} - #{resp.message}"
56
73
  return
57
74
  end
58
75
 
59
- log "Saving #{filename}"
76
+ Autodeploy.log "Saving #{filename}"
60
77
 
61
78
  open("downloads/#{filename}", "wb") do |file|
62
79
  file.write(resp.body)
63
- log "Completed download - #{filename}"
80
+ Autodeploy.log "Completed download - #{filename}"
64
81
  end
65
82
  end
66
83
  end
67
84
 
68
- def daemonize(time=30)
85
+ def daemonize(time=10)
69
86
  loop do
70
87
  run
71
88
  sleep time
@@ -0,0 +1,99 @@
1
+ require 'socket'
2
+
3
+ module Autodeploy
4
+ class Deployer
5
+ def initialize(yaml_config, jenkins_job)
6
+ @config = yaml_config
7
+ @job = jenkins_job
8
+ end
9
+
10
+ def run()
11
+ deploy_build = get_build_to_deploy(@config['job'])
12
+ build_full_file_path(deploy_build)
13
+
14
+ file_downloaded = has_file_been_downloaded
15
+ return unless file_downloaded
16
+
17
+ file_deployed = has_file_been_deployed
18
+ return if file_deployed
19
+
20
+ lock_and_deploy
21
+ end
22
+
23
+ def lock_and_deploy
24
+ locked = acquire_lock_from_mysql
25
+ if locked
26
+ deploy
27
+ else
28
+ Autodeploy.log "Waiting for lock..."
29
+ end
30
+ end
31
+
32
+ def deploy
33
+ Autodeploy.log "Lock acquired"
34
+
35
+ begin
36
+ move_artifact_to_deploy_dir
37
+
38
+ record_successful_deployment
39
+ ensure
40
+ release_lock_from_mysql
41
+ end
42
+ end
43
+
44
+ def build_full_file_path(deploy_build)
45
+ artifact_file_name = @job['artifacts'][0]['fileName']
46
+
47
+ Autodeploy.log "DeployBuild: #{deploy_build}"
48
+
49
+ filename = [deploy_build.build_number, deploy_build.git_sha, artifact_file_name].compact.join('-')
50
+ @filepath = File.join(@config['download_dir'], filename)
51
+ end
52
+
53
+ def get_build_to_deploy(job_name)
54
+ Models::DeployBuild.where(job_name: job_name).order("created_at DESC").first
55
+ end
56
+
57
+ def has_file_been_downloaded()
58
+ File.exists?(@filepath)
59
+ end
60
+
61
+ def record_successful_deployment()
62
+ Models::DeployAudit.create(host: Socket.gethostname,
63
+ build_number: @job['number'],
64
+ jenkins_build_timestamp: @job['timestamp'],
65
+ created_at: Time.now.to_i * 1000)
66
+ end
67
+
68
+ def has_file_been_deployed()
69
+ Models::DeployAudit.where(host: Socket.gethostname,
70
+ build_number: @job['number'],
71
+ jenkins_build_timestamp: @job['timestamp']).exists?
72
+ end
73
+
74
+ def acquire_lock_from_mysql
75
+ Autodeploy.log "Attempting to acquire lock..."
76
+
77
+ begin
78
+ Models::DeployLock.create(job_name: @config['job'],
79
+ host: Socket.gethostname,
80
+ created_at: Time.now.to_i * 1000)
81
+ rescue ActiveRecord::RecordNotUnique
82
+ nil
83
+ end
84
+ end
85
+
86
+ def release_lock_from_mysql
87
+ Autodeploy.log "Releasing lock..."
88
+ lock = Models::DeployLock.where(job_name: @config['job'], host: Socket.gethostname).first
89
+ lock.delete
90
+ end
91
+
92
+ def move_artifact_to_deploy_dir
93
+ Autodeploy.log "Moving aritifact to deploy dir"
94
+
95
+ cmd = "mv #{@filepath} #{@config['deploy_dir']}/#{@config['deploy_artifact_name']}"
96
+ success = system(cmd)
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,9 @@
1
+ module Autodeploy
2
+ module Models
3
+
4
+ class DeployAudit < ActiveRecord::Base
5
+
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Autodeploy
2
+ module Models
3
+
4
+ class DeployBuild < ActiveRecord::Base
5
+
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Autodeploy
2
+ module Models
3
+
4
+ class DeployLock < ActiveRecord::Base
5
+
6
+
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module Autodeploy
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -0,0 +1,14 @@
1
+ class SetupDeployBuildTable < ActiveRecord::Migration
2
+ def up
3
+ create_table :deploy_builds do |t|
4
+ t.string :job_name
5
+ t.string :git_sha
6
+ t.integer :build_number
7
+ t.integer :created_at, :limit => 8
8
+ end
9
+ end
10
+
11
+ def down
12
+ drop_table :deploy_builds
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ class SetupLockTable < ActiveRecord::Migration
2
+ def up
3
+ create_table :deploy_locks do |t|
4
+ t.string :host
5
+ t.string :job_name
6
+ t.integer :created_at, :limit => 8
7
+ end
8
+
9
+ add_index :deploy_locks, [:job_name], unique: true
10
+ end
11
+
12
+ def down
13
+ drop_table :deploy_locks
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ class SetupDeployAuditTable < ActiveRecord::Migration
2
+ def up
3
+ create_table :deploy_audits do |t|
4
+ t.string :host
5
+ t.integer :jenkins_build_timestamp, :limit => 8
6
+ t.integer :build_number
7
+ t.integer :created_at, :limit => 8
8
+ end
9
+
10
+ add_index :deploy_audits, [:host, :jenkins_build_timestamp, :build_number], unique: true, name: 'host_deploy_idx'
11
+ end
12
+
13
+ def down
14
+ drop_table :deploy_audits
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Autodeploy::Deployer do
4
+
5
+ it "should test" do
6
+ puts "hi"
7
+
8
+ deployer = Autodeploy::Deployer.new
9
+ deployer.should_receive(:get_build_to_deploy).with("contacts").and_return(1)
10
+
11
+ mock_deployer.run
12
+ end
13
+
14
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'autodeploy'
5
+
6
+ RSpec.configure do |config|
7
+
8
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autodeploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Breznak
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-21 00:00:00.000000000 Z
12
+ date: 2013-08-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -39,6 +39,20 @@ dependencies:
39
39
  - - '>='
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: jenkins_api_client
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -67,6 +81,34 @@ dependencies:
67
81
  - - '>='
68
82
  - !ruby/object:Gem::Version
69
83
  version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: activerecord
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: mysql2
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
70
112
  description: A simple daemon that checks and downloads assets from Jenkins
71
113
  email:
72
114
  - bob@evertrue.com
@@ -84,7 +126,16 @@ files:
84
126
  - autodeploy.gemspec
85
127
  - bin/autodeploy
86
128
  - lib/autodeploy.rb
129
+ - lib/autodeploy/deployer.rb
130
+ - lib/autodeploy/models/deploy_audit.rb
131
+ - lib/autodeploy/models/deploy_build.rb
132
+ - lib/autodeploy/models/deploy_lock.rb
87
133
  - lib/autodeploy/version.rb
134
+ - lib/db/migrate/001_setup_deploy_build_table.rb
135
+ - lib/db/migrate/002_setup_lock_table.rb
136
+ - lib/db/migrate/003_setup_deploy_audit_table.rb
137
+ - spec/deployer_spec.rb
138
+ - spec/spec_helper.rb
88
139
  homepage: https://github.com/evertrue/autodeploy
89
140
  licenses:
90
141
  - MIT
@@ -109,5 +160,6 @@ rubygems_version: 2.0.0
109
160
  signing_key:
110
161
  specification_version: 4
111
162
  summary: A simple daemon that checks and downloads assets from Jenkins
112
- test_files: []
113
- has_rdoc:
163
+ test_files:
164
+ - spec/deployer_spec.rb
165
+ - spec/spec_helper.rb