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 +4 -4
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/Rakefile +40 -1
- data/autodeploy.gemspec +3 -0
- data/lib/autodeploy.rb +33 -16
- data/lib/autodeploy/deployer.rb +99 -0
- data/lib/autodeploy/models/deploy_audit.rb +9 -0
- data/lib/autodeploy/models/deploy_build.rb +9 -0
- data/lib/autodeploy/models/deploy_lock.rb +9 -0
- data/lib/autodeploy/version.rb +1 -1
- data/lib/db/migrate/001_setup_deploy_build_table.rb +14 -0
- data/lib/db/migrate/002_setup_lock_table.rb +15 -0
- data/lib/db/migrate/003_setup_deploy_audit_table.rb +16 -0
- data/spec/deployer_spec.rb +14 -0
- data/spec/spec_helper.rb +8 -0
- metadata +56 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f7a38b2c1acdf70874ef655a05c22ddf38a68e7
|
4
|
+
data.tar.gz: df182975d1f94091d312a71688c5516d069aa66b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0113541e0b016ebd29936fab70a25636d75a7bd56c4e5b56c7d0b84e4bbb90cd6dd69c9fb221a51c7661edee0168f87ed578a45545b7ceaae0e2787fcce73df3
|
7
|
+
data.tar.gz: 2a30e625e887bd4f4b09da12cbe3bb24d78ddab9e169adb1d0e049ce3ce43f10a61a00d0b45426360f30647db6ea127ddc1c8bc0b7993f5cdd7f3049ee68cbca
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1 +1,40 @@
|
|
1
|
-
require
|
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
|
data/autodeploy.gemspec
CHANGED
@@ -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
|
data/lib/autodeploy.rb
CHANGED
@@ -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
|
-
|
17
|
-
|
24
|
+
@config = YAML.load_file(configfile)
|
25
|
+
@client = JenkinsApi::Client.new(@config)
|
18
26
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
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=
|
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
|
data/lib/autodeploy/version.rb
CHANGED
@@ -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
|
data/spec/spec_helper.rb
ADDED
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.
|
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-
|
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
|
-
|
163
|
+
test_files:
|
164
|
+
- spec/deployer_spec.rb
|
165
|
+
- spec/spec_helper.rb
|