dploy 0.0.2

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in dploy.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/config/dploy.yml ADDED
@@ -0,0 +1,11 @@
1
+ development:
2
+
3
+ ec2_access_key_id:
4
+ ec2_access_key:
5
+ ec2_endpoint:
6
+ ec2_ssh_key_path:
7
+
8
+ chef_api_url:
9
+ chef_api_user:
10
+ chef_api_key:
11
+
data/dploy.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dploy/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "dploy"
7
+ s.version = Dploy::VERSION
8
+ s.authors = ["DuckDO"]
9
+ s.email = ["james@stylesaint.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{deployment module for chef and aws}
12
+ s.description = %q{deploymoent module for chef and aws}
13
+
14
+ s.rubyforge_project = "dploy"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ s.add_runtime_dependency('aws-sdk')
25
+ s.add_runtime_dependency('chef')
26
+ end
data/lib/dploy.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "dploy/version"
2
+ require 'dploy/chef_client'
3
+ require 'dploy/ec2_client'
4
+ require 'dploy/deployer'
5
+ require 'dploy/logger'
6
+
7
+ module Dploy
8
+
9
+ end
10
+
@@ -0,0 +1,52 @@
1
+ require 'chef'
2
+ require 'json'
3
+
4
+ module Dploy
5
+
6
+ class ChefClient
7
+
8
+ def initialize(server_url, user, key_path = nil)
9
+ key_path ||= "#{user}.pem"
10
+ @rest_client = Chef::REST.new(server_url, user, key_path)
11
+ end
12
+
13
+ def update_node_attributes(node_name,attributes)
14
+ node = get_node(node_name)
15
+ node[:normal] = node[:normal].merge(attributes)
16
+ symbolize(@rest_client.put_rest("nodes/#{node_name}",node))
17
+ end
18
+
19
+ def get_nodes
20
+ @rest_client.get_rest("nodes")
21
+ end
22
+
23
+ def get_node(name)
24
+ symbolize(@rest_client.get_rest("nodes/#{name}"))
25
+ end
26
+
27
+ def put_node(node)
28
+ symbolize(@rest_client.put_rest("nodes/#{node[:name]}",node))
29
+ end
30
+
31
+ def create_node(node)
32
+ symbolize(@rest_client.post_rest("nodes",node.to_json))
33
+ end
34
+
35
+ def delete_node(node_name)
36
+ symbolize(@rest_client.delete_rest("nodes/#{node_name}"))
37
+ end
38
+
39
+ def symbolize(hash)
40
+ json_parse_opts = {:symbolize_names => true}
41
+ JSON.parse(hash.to_json, json_parse_opts)
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
48
+
49
+
50
+
51
+
52
+
@@ -0,0 +1,27 @@
1
+ require 'json'
2
+ require 'rest_client'
3
+
4
+ module Dploy
5
+
6
+ module Client
7
+
8
+ def self.deploy(server, project, environment, version)
9
+ deploy_data = JSON.parse((RestClient.post "http://#{server}/deploy", { :project => project, :environment => environment, :version => version }.to_json, :content_type => :json, :accept => :json))
10
+ self.get_deploy_logs(server, deploy_data['id'])
11
+ end
12
+
13
+ def self.get_deploy_logs(server, deploy_id)
14
+ start_id = "000000000000000000000000"
15
+ while true
16
+ logs = JSON.parse(RestClient.get( "http://#{server}/logs/#{deploy_id}/?start_id=#{start_id}", :accept => :json))
17
+ logs.each do |row|
18
+ puts row
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ Dploy::Client.deploy("dploy.internal.stylesaint.com:3000", "community", "test", ENV['VERSION'])
@@ -0,0 +1,68 @@
1
+ require "dploy/version"
2
+ require 'dploy/chef_client'
3
+ require 'dploy/ec2_client'
4
+ require 'dploy/logger'
5
+ require 'dploy/shell_command'
6
+
7
+ module Dploy
8
+
9
+ class Deployer
10
+
11
+ attr_accessor :deploy_data
12
+
13
+ def initialize(deploy_data)
14
+
15
+ @deploy_data = deploy_data
16
+
17
+ @ec2 = EC2Client.new(
18
+ DPLOY_CONFIG['ec2_access_key_id'],
19
+ DPLOY_CONFIG['ec2_access_key'],
20
+ DPLOY_CONFIG['ec2_endpoint'])
21
+
22
+ @chef = ChefClient.new(
23
+ DPLOY_CONFIG['chef_api_url'],
24
+ DPLOY_CONFIG['chef_api_user'],
25
+ DPLOY_CONFIG['chef_api_key'])
26
+
27
+
28
+ #TODO validate deploy data
29
+
30
+ @deploy_data[:id] = "#{@deploy_data[:project]}-#{@deploy_data[:environment]}-#{@deploy_data[:version].gsub('.','-')}-#{Time.now.to_i}"
31
+ @log = Dploy::Logger.new(DPLOY_CONFIG['mongo_server'], @deploy_data[:id])
32
+ end
33
+
34
+ def deploy()
35
+ begin
36
+ #Get Instances
37
+ search_tags = { 'project' => @deploy_data[:project], 'environment' => @deploy_data[:environment] }
38
+ @log.debug("Searching For EC2 Instances")
39
+ @log.debug("Search tags: #{search_tags}")
40
+ instances = @ec2.get_instances_by_tags(search_tags)
41
+ @log.debug("#{instances.count} matching instances found")
42
+
43
+ instances.each do |instance|
44
+
45
+ @log.debug("Starting deploy for instance: #{instance.id}")
46
+ #TODO Remove from LB
47
+
48
+ #update chef node
49
+ node_name = "#{@deploy_data[:environment]}-#{@deploy_data[:project]}-#{instance.id}"
50
+ @log.debug("Updating chef node: #{node_name}")
51
+ attributes = { :dploy => { :target_version => @deploy_data[:version], :status => 'deploying' } }
52
+ @chef.update_node_attributes(node_name, attributes)
53
+
54
+ #Run Chef client
55
+ @log.debug("Running Chef Client for #{node_name} (#{instance.dns_name})")
56
+ ShellCmd.run("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i #{DPLOY_CONFIG['ec2_ssh_key_path']} ubuntu@#{instance.dns_name} sudo chef-client", @deploy_data[:id])
57
+
58
+ #TODO Test
59
+ rescue Exception
60
+ @log.error($!)
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
@@ -0,0 +1,26 @@
1
+ require 'aws-sdk'
2
+
3
+ module Dploy
4
+
5
+ class EC2Client
6
+
7
+ def initialize(access_key_id, access_key, ec2_endpoint)
8
+ @ec2 = AWS::EC2.new(
9
+ :access_key_id => access_key_id,
10
+ :secret_access_key => access_key,
11
+ :ec2_endpoint => ec2_endpoint
12
+ )
13
+ end
14
+
15
+ def get_instances_by_tags(search_tags = {})
16
+ search_tags.map{|k,v| {k => v}}.reduce(@ec2.instances){|filtered_result,search_tag | filtered_result.tagged(search_tag.keys).tagged_values(search_tag.values)}
17
+ end
18
+
19
+ protected
20
+ def get_resource_attributes(resource, attributes)
21
+ attributes.map { |attribute| {attribute => resource.send(attribute)} if resource.respond_to?(attribute) }.reduce {|sum, att| sum.merge(att) }
22
+ end
23
+
24
+ end
25
+
26
+ end
File without changes
@@ -0,0 +1,38 @@
1
+ require 'mongo'
2
+
3
+ module Dploy
4
+
5
+ class Logger
6
+
7
+ def initialize(mongo_host, deploy_id)
8
+ @log = Mongo::Connection.new(mongo_host).db('log')[deploy_id]
9
+ end
10
+
11
+ private :log
12
+ def log(message, meta_data )
13
+ @log.insert({:meta_data => meta_data, :message => message})
14
+ end
15
+
16
+ def debug(message, meta_data = {})
17
+ meta_data.merge({:log_type => 'debug' })
18
+ log(message, metadata)
19
+ end
20
+
21
+ def error(message, meta_data = {})
22
+ meta_data.merge({:log_type => 'debug' })
23
+ log(message, metadata)
24
+ end
25
+
26
+ def completion(message, meta_data = {})
27
+ meta_data.merge({:log_type => 'debug' })
28
+ log(message, metadata)
29
+ end
30
+
31
+ def get_messages(collection, start_id = "000000000000000000000000")
32
+ @@db[collection].find(:_id => {"$gt" => BSON::ObjectId(start_id)}).map {|row| row}
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,28 @@
1
+ require 'pty'
2
+
3
+ module Dploy
4
+
5
+ class ShellCmd
6
+
7
+ def self.run(command, log)
8
+ PTY.spawn(command) do |output, input, pid|
9
+ begin
10
+ while !PTY.check(pid)
11
+ if log != nil
12
+ line = output.gets
13
+ if line.upcase.include? "ERROR"
14
+ log.error(line)
15
+ else
16
+ log.debug(line)
17
+ end
18
+ end
19
+ end
20
+ rescue Errno::EIO
21
+ puts "end"
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,3 @@
1
+ module Dploy
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dploy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - DuckDO
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-04 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aws-sdk
16
+ requirement: &24476420 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *24476420
25
+ - !ruby/object:Gem::Dependency
26
+ name: chef
27
+ requirement: &24475920 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *24475920
36
+ description: deploymoent module for chef and aws
37
+ email:
38
+ - james@stylesaint.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - Rakefile
46
+ - config/dploy.yml
47
+ - dploy.gemspec
48
+ - lib/dploy.rb
49
+ - lib/dploy/chef_client.rb
50
+ - lib/dploy/client.rb
51
+ - lib/dploy/deployer.rb
52
+ - lib/dploy/ec2_client.rb
53
+ - lib/dploy/load_config.rb
54
+ - lib/dploy/logger.rb
55
+ - lib/dploy/shell_command.rb
56
+ - lib/dploy/version.rb
57
+ homepage: ''
58
+ licenses: []
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project: dploy
77
+ rubygems_version: 1.8.11
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: deployment module for chef and aws
81
+ test_files: []