heirloom 0.0.7 → 0.0.8
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/lib/heirloom/acl/s3.rb +64 -0
- data/lib/heirloom/acl.rb +1 -0
- data/lib/heirloom/artifact/artifact_authorizer.rb +31 -0
- data/lib/heirloom/artifact/artifact_builder.rb +57 -0
- data/lib/heirloom/artifact/artifact_destroyer.rb +40 -0
- data/lib/heirloom/artifact/artifact_lister.rb +25 -0
- data/lib/heirloom/artifact/artifact_reader.rb +26 -0
- data/lib/heirloom/artifact/artifact_uploader.rb +58 -0
- data/lib/heirloom/artifact.rb +88 -0
- data/lib/heirloom/aws/s3.rb +35 -0
- data/lib/heirloom/aws/simpledb.rb +37 -0
- data/lib/heirloom/aws.rb +2 -35
- data/lib/heirloom/cli.rb +25 -32
- data/lib/heirloom/config.rb +11 -5
- data/lib/heirloom/destroyer/s3.rb +27 -0
- data/lib/heirloom/destroyer.rb +1 -0
- data/lib/heirloom/directory/git_directory.rb +35 -0
- data/lib/heirloom/directory.rb +1 -0
- data/lib/heirloom/uploader/s3.rb +33 -0
- data/lib/heirloom/uploader.rb +1 -0
- data/lib/heirloom/version.rb +1 -1
- data/lib/heirloom.rb +5 -227
- data/script/ci_setup +14 -0
- data/spec/config_spec.rb +11 -0
- data/spec/spec_helper.rb +8 -0
- metadata +39 -17
@@ -0,0 +1,64 @@
|
|
1
|
+
module Heirloom
|
2
|
+
module ACL
|
3
|
+
class S3
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@config = args[:config]
|
7
|
+
@region = args[:region]
|
8
|
+
@logger = args[:logger]
|
9
|
+
@accounts = @config.authorized_aws_accounts
|
10
|
+
end
|
11
|
+
|
12
|
+
def allow_read_acccess_from_accounts(args)
|
13
|
+
bucket = args[:bucket]
|
14
|
+
key_name = args[:key_name]
|
15
|
+
key_folder = args[:key_folder]
|
16
|
+
|
17
|
+
key = "#{key_folder}/#{key_name}.tar.gz"
|
18
|
+
|
19
|
+
current_acls = s3.get_bucket_acl(bucket)
|
20
|
+
|
21
|
+
name = current_acls['Owner']['Name']
|
22
|
+
id = current_acls['Owner']['ID']
|
23
|
+
grants = build_bucket_grants :id => id,
|
24
|
+
:name => name,
|
25
|
+
:accounts => @accounts
|
26
|
+
|
27
|
+
@accounts.each do |a|
|
28
|
+
@logger.info "Authorizing #{a} to s3://#{bucket}/#{key}"
|
29
|
+
end
|
30
|
+
s3.put_object_acl bucket, key, grants
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def build_bucket_grants(args)
|
36
|
+
id = args[:id]
|
37
|
+
name = args[:name]
|
38
|
+
|
39
|
+
a = Array.new
|
40
|
+
|
41
|
+
@accounts.each do |g|
|
42
|
+
a << {
|
43
|
+
'Grantee' => { 'EmailAddress' => g } ,
|
44
|
+
'Permission' => 'READ'
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
{
|
49
|
+
'Owner' => {
|
50
|
+
'DisplayName' => name,
|
51
|
+
'ID' => id
|
52
|
+
},
|
53
|
+
'AccessControlList' => a
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def s3
|
58
|
+
@s3 ||= AWS::S3.new :config => @config,
|
59
|
+
:region => @region
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/heirloom/acl.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'heirloom/acl/s3'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Heirloom
|
2
|
+
|
3
|
+
class ArtifactAuthorizer
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@config = args[:config]
|
7
|
+
@logger = args[:logger]
|
8
|
+
end
|
9
|
+
|
10
|
+
def authorize(args)
|
11
|
+
id = args[:id]
|
12
|
+
name = args[:name]
|
13
|
+
public_readable = args[:public_readable]
|
14
|
+
|
15
|
+
unless @public_readable
|
16
|
+
@config.regions.each do |region|
|
17
|
+
bucket = "#{@config.bucket_prefix}-#{region}"
|
18
|
+
|
19
|
+
s3_acl = ACL::S3.new :config => @config,
|
20
|
+
:logger => @logger,
|
21
|
+
:region => region
|
22
|
+
|
23
|
+
s3_acl.allow_read_acccess_from_accounts :key_name => id,
|
24
|
+
:key_folder => name,
|
25
|
+
:bucket => bucket
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Heirloom
|
5
|
+
|
6
|
+
class ArtifactBuilder
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
@config = args[:config]
|
10
|
+
@logger = args[:logger]
|
11
|
+
end
|
12
|
+
|
13
|
+
def build(args)
|
14
|
+
@name = args[:name]
|
15
|
+
@id = args[:id]
|
16
|
+
@public = args[:public]
|
17
|
+
@git_directory = GitDirectory.new :directory => args[:directory],
|
18
|
+
:logger => @logger
|
19
|
+
|
20
|
+
@commit = @git_directory.commit @id
|
21
|
+
|
22
|
+
create_artifact_record
|
23
|
+
@git_directory.build_artifact_from_directory
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def create_artifact_domain
|
29
|
+
@logger.info "Verifying artifact domain #{@name} exists."
|
30
|
+
sdb.create_domain @name
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_artifact_record
|
34
|
+
create_artifact_domain
|
35
|
+
attributes = { 'built_by' => "#{user}@#{hostname}",
|
36
|
+
'built_at' => Time.now.utc.iso8601,
|
37
|
+
'sha' => @id,
|
38
|
+
'abbreviated_sha' => @commit.id_abbrev,
|
39
|
+
'message' => @commit.message,
|
40
|
+
'author' => @commit.author.name }
|
41
|
+
sdb.put_attributes @name, @id, attributes
|
42
|
+
end
|
43
|
+
|
44
|
+
def sdb
|
45
|
+
@sdb ||= AWS::SimpleDB.new :config => @config
|
46
|
+
end
|
47
|
+
|
48
|
+
def user
|
49
|
+
ENV['USER']
|
50
|
+
end
|
51
|
+
|
52
|
+
def hostname
|
53
|
+
Socket.gethostname
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Heirloom
|
2
|
+
|
3
|
+
class ArtifactDestroyer
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@config = args[:config]
|
7
|
+
@logger = args[:logger]
|
8
|
+
end
|
9
|
+
|
10
|
+
def destroy(args)
|
11
|
+
id = args[:id]
|
12
|
+
name = args[:name]
|
13
|
+
|
14
|
+
@logger.info "Destroying #{args[:name]} - #{args[:id]}"
|
15
|
+
|
16
|
+
@config.regions.each do |region|
|
17
|
+
bucket = "#{@config.bucket_prefix}-#{region}"
|
18
|
+
key = "#{id}.tar.gz"
|
19
|
+
|
20
|
+
@logger.info "Deleting s3://#{bucket}/#{name}/#{key}"
|
21
|
+
|
22
|
+
s3_destroyer = Destroyer::S3.new :config => @config,
|
23
|
+
:region => region
|
24
|
+
|
25
|
+
s3_destroyer.destroy_file :key_name => key,
|
26
|
+
:key_folder => name,
|
27
|
+
:bucket => bucket
|
28
|
+
|
29
|
+
sdb.delete name, id
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def sdb
|
36
|
+
@sdb ||= AWS::SimpleDB.new :config => @config
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Heirloom
|
2
|
+
|
3
|
+
class ArtifactLister
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@config = Config.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def versions(args)
|
10
|
+
domain = args[:name]
|
11
|
+
sdb.select("select * from #{domain}").keys.reverse
|
12
|
+
end
|
13
|
+
|
14
|
+
def list
|
15
|
+
sdb.domains
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def sdb
|
21
|
+
@sdb ||= AWS::SimpleDB.new :config => @config
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Heirloom
|
2
|
+
|
3
|
+
class ArtifactReader
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@config = Config.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def show(args)
|
10
|
+
domain = args[:name]
|
11
|
+
id = args[:id]
|
12
|
+
sdb.select "select * from #{domain} where itemName() = '#{id}'"
|
13
|
+
end
|
14
|
+
|
15
|
+
def exists?(args)
|
16
|
+
show(args).any?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def sdb
|
22
|
+
@sdb ||= AWS::SimpleDB.new :config => @config
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Heirloom
|
2
|
+
|
3
|
+
class ArtifactUploader
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@config = args[:config]
|
7
|
+
@logger = args[:logger]
|
8
|
+
end
|
9
|
+
|
10
|
+
def upload(args)
|
11
|
+
id = args[:id]
|
12
|
+
name = args[:name]
|
13
|
+
file = args[:file]
|
14
|
+
key = "#{id}.tar.gz"
|
15
|
+
public_readable = args[:public_readable]
|
16
|
+
|
17
|
+
@config.regions.each do |region|
|
18
|
+
bucket = "#{@config.bucket_prefix}-#{region}"
|
19
|
+
|
20
|
+
s3_uploader = Uploader::S3.new :config => @config,
|
21
|
+
:region => region
|
22
|
+
|
23
|
+
s3_uploader.upload_file :file => file,
|
24
|
+
:bucket => bucket,
|
25
|
+
:key_name => key,
|
26
|
+
:key_folder => name,
|
27
|
+
:public_readable => public_readable
|
28
|
+
sdb.put_attributes name, id, { "#{region}-s3-url" =>
|
29
|
+
"s3://#{bucket}/#{name}/#{key}" }
|
30
|
+
|
31
|
+
@logger.info "Uploading s3://#{bucket}/#{name}/#{key}"
|
32
|
+
|
33
|
+
sdb.put_attributes name, id, { "#{region}-http-url" =>
|
34
|
+
"http://#{s3_endpoints[region]}/#{bucket}/#{name}/#{key}" }
|
35
|
+
@logger.info "Uploading http://#{s3_endpoints[region]}/#{bucket}/#{name}/#{key}"
|
36
|
+
|
37
|
+
sdb.put_attributes name, id, { "#{region}-https-url" =>
|
38
|
+
"https://#{s3_endpoints[region]}/#{bucket}/#{name}/#{key}" }
|
39
|
+
@logger.info "Uploading https://#{s3_endpoints[region]}/#{bucket}/#{name}/#{key}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def s3_endpoints
|
46
|
+
{
|
47
|
+
'us-east-1' => 's3.amazonaws.com',
|
48
|
+
'us-west-1' => 's3-us-west-1.amazonaws.com',
|
49
|
+
'us-west-2' => 's3-us-west-2.amazonaws.com'
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def sdb
|
54
|
+
@sdb ||= AWS::SimpleDB.new :config => @config
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'heirloom/artifact/artifact_lister.rb'
|
2
|
+
require 'heirloom/artifact/artifact_reader.rb'
|
3
|
+
require 'heirloom/artifact/artifact_builder.rb'
|
4
|
+
require 'heirloom/artifact/artifact_uploader.rb'
|
5
|
+
require 'heirloom/artifact/artifact_authorizer.rb'
|
6
|
+
require 'heirloom/artifact/artifact_destroyer.rb'
|
7
|
+
|
8
|
+
module Heirloom
|
9
|
+
|
10
|
+
class Artifact
|
11
|
+
def initialize(args)
|
12
|
+
@config = Config.new :config => args[:config]
|
13
|
+
@logger = args[:logger] ||= Logger.new(STDOUT)
|
14
|
+
|
15
|
+
@logger.datetime_format = "%Y-%m-%d %H:%M:%S"
|
16
|
+
@logger.formatter = proc do |severity, datetime, progname, msg|
|
17
|
+
"#{datetime}: #{msg}\n"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def build(args)
|
22
|
+
if artifact_reader.exists?(args)
|
23
|
+
@logger.info "Destroying existing artifact."
|
24
|
+
destroy(args)
|
25
|
+
end
|
26
|
+
|
27
|
+
file = artifact_builder.build(args)
|
28
|
+
|
29
|
+
artifact_uploader.upload :id => args[:id],
|
30
|
+
:name => args[:name],
|
31
|
+
:file => file,
|
32
|
+
:public_readable => args[:public]
|
33
|
+
|
34
|
+
unless args[:public]
|
35
|
+
artifact_authorizer.authorize :id => args[:id],
|
36
|
+
:name => args[:name],
|
37
|
+
:public_readable => args[:public_readable]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def destroy(args)
|
42
|
+
artifact_destroyer.destroy(args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def show(args)
|
46
|
+
artifact_reader.show(args)
|
47
|
+
end
|
48
|
+
|
49
|
+
def versions(args)
|
50
|
+
artifact_lister.versions(args)
|
51
|
+
end
|
52
|
+
|
53
|
+
def list
|
54
|
+
artifact_lister.list
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def artifact_lister
|
60
|
+
@artifact_lister ||= ArtifactLister.new :config => @config
|
61
|
+
end
|
62
|
+
|
63
|
+
def artifact_reader
|
64
|
+
@artifact_reader ||= ArtifactReader.new :config => @config
|
65
|
+
end
|
66
|
+
|
67
|
+
def artifact_builder
|
68
|
+
@artifact_builder ||= ArtifactBuilder.new :config => @config,
|
69
|
+
:logger => @logger
|
70
|
+
end
|
71
|
+
|
72
|
+
def artifact_uploader
|
73
|
+
@artifact_uploader ||= ArtifactUploader.new :config => @config,
|
74
|
+
:logger => @logger
|
75
|
+
end
|
76
|
+
|
77
|
+
def artifact_authorizer
|
78
|
+
@artifact_authorizer ||= ArtifactAuthorizer.new :config => @config,
|
79
|
+
:logger => @logger
|
80
|
+
end
|
81
|
+
|
82
|
+
def artifact_destroyer
|
83
|
+
@artifact_destroyer ||= ArtifactDestroyer.new :config => @config,
|
84
|
+
:logger => @logger
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
module Heirloom
|
4
|
+
module AWS
|
5
|
+
class S3
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@config = args[:config]
|
9
|
+
@region = args[:region]
|
10
|
+
|
11
|
+
@s3 = Fog::Storage.new :provider => 'AWS',
|
12
|
+
:aws_access_key_id => @config.access_key,
|
13
|
+
:aws_secret_access_key => @config.secret_key,
|
14
|
+
:region => @region
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete_object(bucket_name, object_name, options = {})
|
18
|
+
@s3.delete_object(bucket_name, object_name, options = {})
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_bucket(bucket)
|
22
|
+
@s3.directories.get bucket
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_bucket_acl(bucket)
|
26
|
+
@s3.get_bucket_acl(bucket).body
|
27
|
+
end
|
28
|
+
|
29
|
+
def put_object_acl(bucket, key, grants)
|
30
|
+
@s3.put_object_acl(bucket, key, grants)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
module Heirloom
|
4
|
+
module AWS
|
5
|
+
class SimpleDB
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@config = args[:config]
|
9
|
+
@sdb = Fog::AWS::SimpleDB.new :aws_access_key_id => @config.access_key,
|
10
|
+
:aws_secret_access_key => @config.secret_key,
|
11
|
+
:region => @config.primary_region
|
12
|
+
end
|
13
|
+
|
14
|
+
def domains
|
15
|
+
@sdb.list_domains.body['Domains']
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_domain(domain)
|
19
|
+
@sdb.create_domain(domain) unless domains.include? domain
|
20
|
+
end
|
21
|
+
|
22
|
+
def put_attributes(domain, key, args)
|
23
|
+
@sdb.put_attributes domain, key, args
|
24
|
+
end
|
25
|
+
|
26
|
+
def select(query)
|
27
|
+
@sdb.select(query).body['Items']
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete(domain, key)
|
31
|
+
@sdb.delete_attributes domain, key
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/lib/heirloom/aws.rb
CHANGED
@@ -1,35 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class AWS
|
4
|
-
class SimpleDb
|
5
|
-
|
6
|
-
def initialize(access_key, secret_key)
|
7
|
-
@sdb = Fog::AWS::SimpleDB.new :aws_access_key_id => access_key,
|
8
|
-
:aws_secret_access_key => secret_key,
|
9
|
-
:region => 'us-west-1'
|
10
|
-
end
|
11
|
-
|
12
|
-
def domains
|
13
|
-
@sdb.list_domains.body['Domains']
|
14
|
-
end
|
15
|
-
|
16
|
-
def create_domain(domain)
|
17
|
-
@sdb.create_domain(domain) unless domains.include? domain
|
18
|
-
end
|
19
|
-
|
20
|
-
def put_attributes(domain, key, args)
|
21
|
-
@sdb.put_attributes domain, key, args
|
22
|
-
end
|
23
|
-
|
24
|
-
def select(query)
|
25
|
-
@sdb.select(query).body['Items']
|
26
|
-
end
|
27
|
-
|
28
|
-
def delete(domain, key)
|
29
|
-
@sdb.delete_attributes domain, key
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
1
|
+
require 'heirloom/aws/simpledb'
|
2
|
+
require 'heirloom/aws/s3'
|
data/lib/heirloom/cli.rb
CHANGED
@@ -5,50 +5,43 @@ module Heirloom
|
|
5
5
|
def self.start
|
6
6
|
@opts = Trollop::options do
|
7
7
|
banner <<-EOS
|
8
|
-
build and manage artifacts
|
8
|
+
I build and manage artifacts
|
9
9
|
|
10
10
|
Usage:
|
11
11
|
|
12
12
|
heirloom list
|
13
|
-
heirloom
|
14
|
-
heirloom
|
15
|
-
heirloom
|
13
|
+
heirloom versions -n NAME
|
14
|
+
heirloom show -n NAME -i VERSION
|
15
|
+
heirloom build -n NAME -i VERSION -d DIRECTORY [-p]
|
16
|
+
heirloom destroy -n NAME -i VERSION
|
16
17
|
EOS
|
17
18
|
opt :help, "Display Help"
|
18
|
-
opt :
|
19
|
-
opt :
|
20
|
-
opt :
|
21
|
-
opt :
|
22
|
-
opt :open, "Is this artifact open to public read?"
|
23
|
-
opt :sha, "Git Sha", :type => :string
|
19
|
+
opt :directory, "Source directory of artifact build.", :type => :string
|
20
|
+
opt :id, "Id of artifact.", :type => :string
|
21
|
+
opt :name, "Name of artifact.", :type => :string
|
22
|
+
opt :public, "Is this artifact public?"
|
24
23
|
end
|
25
24
|
|
26
25
|
cmd = ARGV.shift
|
26
|
+
a = Artifact.new :config => nil
|
27
27
|
|
28
28
|
case cmd
|
29
|
-
when 'build'
|
30
|
-
raise 'Missing required args' unless @opts[:sha] && @opts[:class]
|
31
|
-
|
32
|
-
accounts = @opts[:accounts].nil? ? [] : @opts[:accounts].split(',')
|
33
|
-
|
34
|
-
h = Heirloom.new :heirloom_type => @opts[:class],
|
35
|
-
:source_dir => @opts[:dir] ||= ".",
|
36
|
-
:prefix => @opts[:prefix],
|
37
|
-
:open => @opts[:open],
|
38
|
-
:accounts => accounts
|
39
|
-
|
40
|
-
h.build_and_upload_to_s3(:sha => @opts[:sha])
|
41
29
|
when 'list'
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
when '
|
46
|
-
|
47
|
-
|
48
|
-
when '
|
49
|
-
|
50
|
-
|
51
|
-
|
30
|
+
puts a.list
|
31
|
+
when 'versions', 'artifacts'
|
32
|
+
puts a.versions :name => @opts[:name]
|
33
|
+
when 'show'
|
34
|
+
puts a.show(:name => @opts[:name],
|
35
|
+
:id => @opts[:id]).to_yaml
|
36
|
+
when 'build'
|
37
|
+
a.build :name => @opts[:name],
|
38
|
+
:id => @opts[:id],
|
39
|
+
:accounts => @opts[:accounts],
|
40
|
+
:directory => @opts[:directory],
|
41
|
+
:public => @opts[:public]
|
42
|
+
when 'destroy', 'delete'
|
43
|
+
a.destroy :name => @opts[:name],
|
44
|
+
:id => @opts[:id]
|
52
45
|
else
|
53
46
|
puts "Unkown command: '#{cmd}'."
|
54
47
|
end
|
data/lib/heirloom/config.rb
CHANGED
@@ -1,18 +1,24 @@
|
|
1
1
|
module Heirloom
|
2
2
|
class Config
|
3
3
|
|
4
|
-
attr_accessor :access_key, :secret_key
|
4
|
+
attr_accessor :access_key, :secret_key, :regions,
|
5
|
+
:primary_region, :bucket_prefix, :authorized_aws_accounts
|
5
6
|
|
6
|
-
def initialize
|
7
|
+
def initialize(args = {})
|
8
|
+
@config = args[:config]
|
7
9
|
load_config_file
|
8
10
|
end
|
9
11
|
|
10
12
|
def load_config_file
|
11
13
|
config_file = "#{ENV['HOME']}/.heirloom.yml"
|
12
|
-
c = YAML::load( File.open( config_file ) )
|
14
|
+
c = @config ? @config : YAML::load( File.open( config_file ) )
|
13
15
|
|
14
|
-
self.access_key = c['access_key']
|
15
|
-
self.secret_key = c['secret_key']
|
16
|
+
self.access_key = c['aws']['access_key']
|
17
|
+
self.secret_key = c['aws']['secret_key']
|
18
|
+
self.regions = c['aws']['regions']
|
19
|
+
self.primary_region = regions.first
|
20
|
+
self.bucket_prefix = c['aws']['bucket_prefix']
|
21
|
+
self.authorized_aws_accounts = c['aws']['authorized_aws_accounts']
|
16
22
|
end
|
17
23
|
|
18
24
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Heirloom
|
2
|
+
module Destroyer
|
3
|
+
class S3
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@config = args[:config]
|
7
|
+
@region = args[:region]
|
8
|
+
end
|
9
|
+
|
10
|
+
def destroy_file(args)
|
11
|
+
key_name = args[:key_name]
|
12
|
+
key_folder = args[:key_folder]
|
13
|
+
bucket = args[:bucket]
|
14
|
+
|
15
|
+
s3.delete_object bucket, "#{key_folder}/#{key_name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def s3
|
21
|
+
@s3 ||= AWS::S3.new :config => @config,
|
22
|
+
:region => @region
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'heirloom/destroyer/s3'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'archive/tar/minitar'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'grit'
|
5
|
+
|
6
|
+
include Archive::Tar
|
7
|
+
include Grit
|
8
|
+
|
9
|
+
module Heirloom
|
10
|
+
|
11
|
+
class GitDirectory
|
12
|
+
|
13
|
+
def initialize(args)
|
14
|
+
@directory = args[:directory]
|
15
|
+
@logger = args[:logger]
|
16
|
+
end
|
17
|
+
|
18
|
+
def commit(sha = nil)
|
19
|
+
r = Repo.new @directory
|
20
|
+
sha ? r.commits(sha).first : r.commits.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_artifact_from_directory
|
24
|
+
random_text = (0...8).map{65.+(rand(25)).chr}.join
|
25
|
+
temp_file_name = File.join(Dir.tmpdir, random_text + ".tar.gz")
|
26
|
+
|
27
|
+
@logger.info "Building artifact '#{temp_file_name}' from '#{@directory}'."
|
28
|
+
|
29
|
+
tgz = Zlib::GzipWriter.new File.open(temp_file_name, 'wb')
|
30
|
+
Minitar.pack(@directory, tgz)
|
31
|
+
temp_file_name
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'heirloom/directory/git_directory'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Heirloom
|
2
|
+
module Uploader
|
3
|
+
class S3
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@config = args[:config]
|
7
|
+
@region = args[:region]
|
8
|
+
end
|
9
|
+
|
10
|
+
def upload_file(args)
|
11
|
+
file = args[:file]
|
12
|
+
key_name = args[:key_name]
|
13
|
+
key_folder = args[:key_folder]
|
14
|
+
public_readable = args[:public_readable]
|
15
|
+
bucket = args[:bucket]
|
16
|
+
|
17
|
+
s3_bucket = s3.get_bucket bucket
|
18
|
+
|
19
|
+
s3_bucket.files.create :key => "#{key_folder}/#{key_name}",
|
20
|
+
:body => File.open(file),
|
21
|
+
:public => public_readable
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def s3
|
27
|
+
@s3 ||= AWS::S3.new :config => @config,
|
28
|
+
:region => @region
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'heirloom/uploader/s3'
|
data/lib/heirloom/version.rb
CHANGED
data/lib/heirloom.rb
CHANGED
@@ -1,230 +1,8 @@
|
|
1
|
+
require "heirloom/acl"
|
1
2
|
require "heirloom/aws"
|
3
|
+
require "heirloom/artifact"
|
2
4
|
require "heirloom/config"
|
5
|
+
require "heirloom/directory"
|
6
|
+
require "heirloom/uploader"
|
7
|
+
require "heirloom/destroyer"
|
3
8
|
require "heirloom/version"
|
4
|
-
|
5
|
-
require 'socket'
|
6
|
-
require 'fog'
|
7
|
-
require 'grit'
|
8
|
-
require 'logger'
|
9
|
-
require 'time'
|
10
|
-
require 'zlib'
|
11
|
-
require 'archive/tar/minitar'
|
12
|
-
include Archive::Tar
|
13
|
-
include Grit
|
14
|
-
|
15
|
-
module Heirloom
|
16
|
-
|
17
|
-
class Heirloom
|
18
|
-
attr_accessor :heirloom_type, :commit, :source_dir, :prefix
|
19
|
-
|
20
|
-
def self.list
|
21
|
-
sdb = self.connect_to_sdb
|
22
|
-
|
23
|
-
r = {}
|
24
|
-
|
25
|
-
sdb.domains.each do |domain|
|
26
|
-
r[domain] = sdb.select("select * from #{domain}")
|
27
|
-
end
|
28
|
-
|
29
|
-
r
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.info(args)
|
33
|
-
sdb = self.connect_to_sdb
|
34
|
-
|
35
|
-
s = sdb.select("select * from #{args[:class]} where itemName() = '#{args[:sha]}'")
|
36
|
-
|
37
|
-
s[args[:sha]]
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.delete(args)
|
41
|
-
sdb = self.connect_to_sdb
|
42
|
-
|
43
|
-
sdb.delete args[:class], args[:sha]
|
44
|
-
end
|
45
|
-
|
46
|
-
def initialize(args)
|
47
|
-
@sdb = self.class.connect_to_sdb
|
48
|
-
@accounts = args[:accounts]
|
49
|
-
@open = args[:open] ||= false
|
50
|
-
@config = Config.new
|
51
|
-
|
52
|
-
self.heirloom_type = args[:heirloom_type]
|
53
|
-
self.source_dir = args[:source_dir]
|
54
|
-
self.prefix = args[:prefix]
|
55
|
-
end
|
56
|
-
|
57
|
-
def build_and_upload_to_s3(args)
|
58
|
-
get_commit args[:sha]
|
59
|
-
create_sdb_domain
|
60
|
-
raise 'Artifact already uploaded to S3' if already_in_sdb?
|
61
|
-
build_local_artifact
|
62
|
-
create_sdb_record
|
63
|
-
upload_to_s3
|
64
|
-
delete_local_artifact
|
65
|
-
end
|
66
|
-
|
67
|
-
protected
|
68
|
-
|
69
|
-
def get_commit(sha = nil)
|
70
|
-
r = Repo.new source_dir
|
71
|
-
if sha
|
72
|
-
self.commit = r.commits(sha).first
|
73
|
-
else
|
74
|
-
self.commit = r.commits.first
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def build_local_artifact
|
79
|
-
tgz = Zlib::GzipWriter.new File.open(artifact_path, 'wb')
|
80
|
-
Minitar.pack(source_dir, tgz)
|
81
|
-
end
|
82
|
-
|
83
|
-
def delete_local_artifact
|
84
|
-
File.delete(artifact_path)
|
85
|
-
end
|
86
|
-
|
87
|
-
def create_sdb_domain
|
88
|
-
@sdb.create_domain(domain)
|
89
|
-
end
|
90
|
-
|
91
|
-
def create_sdb_record
|
92
|
-
@sdb.put_attributes domain, sha, { 'built_by' => "#{user}@#{hostname}",
|
93
|
-
'built_at' => Time.now.utc.iso8601,
|
94
|
-
'sha' => sha,
|
95
|
-
'abbreviated_sha' => abbreviated_sha,
|
96
|
-
'message' => message,
|
97
|
-
'author' => author }
|
98
|
-
end
|
99
|
-
|
100
|
-
def already_in_sdb?
|
101
|
-
@sdb.select("select * from #{domain} where itemName() = '#{sha}'").count > 0
|
102
|
-
end
|
103
|
-
|
104
|
-
def upload_to_s3
|
105
|
-
target_buckets = buckets
|
106
|
-
|
107
|
-
# Upload the artifact to each bucket
|
108
|
-
target_buckets.each_pair do |bucket, options|
|
109
|
-
|
110
|
-
# Connect to s3 in region of bucket
|
111
|
-
region = options['region']
|
112
|
-
endpoint = options['endpoint']
|
113
|
-
connection = Fog::Storage.new :provider => 'AWS',
|
114
|
-
:aws_access_key_id => @config.access_key,
|
115
|
-
:aws_secret_access_key => @config.secret_key,
|
116
|
-
:region => region
|
117
|
-
|
118
|
-
# Get bucket
|
119
|
-
b = connection.directories.get bucket
|
120
|
-
|
121
|
-
# Upload the artifact
|
122
|
-
b.files.create :key => "#{folder}/#{artifact}",
|
123
|
-
:body => File.open(artifact_path),
|
124
|
-
:public => open?
|
125
|
-
|
126
|
-
# Get the bucket owner name and ID
|
127
|
-
id = connection.get_bucket_acl(bucket).body['Owner']['ID']
|
128
|
-
name = connection.get_bucket_acl(bucket).body['Owner']['Name']
|
129
|
-
|
130
|
-
# Set the objects ACLs
|
131
|
-
# Only set them if ACLs exist
|
132
|
-
if @accounts.any?
|
133
|
-
connection.put_object_acl(bucket, "#{folder}/#{artifact}", build_bucket_grants(id, name))
|
134
|
-
end
|
135
|
-
|
136
|
-
# Add the artifact location
|
137
|
-
@sdb.put_attributes domain, sha, { "#{region}-s3-url" => "s3://#{bucket}/#{folder}/#{artifact}" }
|
138
|
-
|
139
|
-
# Add the http url
|
140
|
-
@sdb.put_attributes domain, sha, { "#{region}-http-url" => "http://#{endpoint}/#{bucket}/#{folder}/#{artifact}" }
|
141
|
-
|
142
|
-
# Add the https url
|
143
|
-
@sdb.put_attributes domain, sha, { "#{region}-https-url" => "https://#{endpoint}/#{bucket}/#{folder}/#{artifact}" }
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
private
|
148
|
-
|
149
|
-
def build_bucket_grants(id, name)
|
150
|
-
# Creat the AccessControlList based on given accounts
|
151
|
-
a = Array.new
|
152
|
-
@accounts.each do |g|
|
153
|
-
a << {
|
154
|
-
'Grantee' => { 'EmailAddress' => g } ,
|
155
|
-
'Permission' => 'READ'
|
156
|
-
}
|
157
|
-
end
|
158
|
-
|
159
|
-
{
|
160
|
-
'Owner' => {
|
161
|
-
'DisplayName' => name,
|
162
|
-
'ID' => id
|
163
|
-
},
|
164
|
-
'AccessControlList' => a
|
165
|
-
}
|
166
|
-
end
|
167
|
-
|
168
|
-
def buckets
|
169
|
-
{
|
170
|
-
"#{prefix}-us-west-1" => {
|
171
|
-
'region' => 'us-west-1',
|
172
|
-
'endpoint' => 's3-us-west-1.amazonaws.com'
|
173
|
-
}
|
174
|
-
}
|
175
|
-
end
|
176
|
-
|
177
|
-
def artifact
|
178
|
-
"#{sha}.tar.gz"
|
179
|
-
end
|
180
|
-
|
181
|
-
def artifact_path
|
182
|
-
"/tmp/#{artifact}"
|
183
|
-
end
|
184
|
-
|
185
|
-
def domain
|
186
|
-
heirloom_type
|
187
|
-
end
|
188
|
-
|
189
|
-
def folder
|
190
|
-
heirloom_type
|
191
|
-
end
|
192
|
-
|
193
|
-
def author
|
194
|
-
commit.author.name
|
195
|
-
end
|
196
|
-
|
197
|
-
def message
|
198
|
-
commit.message
|
199
|
-
end
|
200
|
-
|
201
|
-
def sha
|
202
|
-
commit.id
|
203
|
-
end
|
204
|
-
|
205
|
-
def abbreviated_sha
|
206
|
-
commit.id_abbrev
|
207
|
-
end
|
208
|
-
|
209
|
-
def user
|
210
|
-
ENV['USER']
|
211
|
-
end
|
212
|
-
|
213
|
-
def open?
|
214
|
-
@open
|
215
|
-
end
|
216
|
-
|
217
|
-
def hostname
|
218
|
-
Socket.gethostname
|
219
|
-
end
|
220
|
-
|
221
|
-
def self.connect_to_sdb
|
222
|
-
config = Config.new
|
223
|
-
@access_key = config.access_key
|
224
|
-
@secret_key = config.secret_key
|
225
|
-
|
226
|
-
AWS::SimpleDb.new(@access_key, @secret_key)
|
227
|
-
end
|
228
|
-
|
229
|
-
end
|
230
|
-
end
|
data/script/ci_setup
ADDED
data/spec/config_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heirloom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70181742234000 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70181742234000
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: fog
|
27
|
-
requirement: &
|
27
|
+
requirement: &70181742233320 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70181742233320
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: grit
|
38
|
-
requirement: &
|
38
|
+
requirement: &70181742232900 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70181742232900
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: logger
|
49
|
-
requirement: &
|
49
|
+
requirement: &70181742232480 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70181742232480
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: minitar
|
60
|
-
requirement: &
|
60
|
+
requirement: &70181742231960 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70181742231960
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: trollop
|
71
|
-
requirement: &
|
71
|
+
requirement: &70181742231460 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70181742231460
|
80
80
|
description: I help build and manage artifacts
|
81
81
|
email:
|
82
82
|
- brett@weav.net
|
@@ -92,10 +92,30 @@ files:
|
|
92
92
|
- bin/heirloom
|
93
93
|
- heirloom.gemspec
|
94
94
|
- lib/heirloom.rb
|
95
|
+
- lib/heirloom/acl.rb
|
96
|
+
- lib/heirloom/acl/s3.rb
|
97
|
+
- lib/heirloom/artifact.rb
|
98
|
+
- lib/heirloom/artifact/artifact_authorizer.rb
|
99
|
+
- lib/heirloom/artifact/artifact_builder.rb
|
100
|
+
- lib/heirloom/artifact/artifact_destroyer.rb
|
101
|
+
- lib/heirloom/artifact/artifact_lister.rb
|
102
|
+
- lib/heirloom/artifact/artifact_reader.rb
|
103
|
+
- lib/heirloom/artifact/artifact_uploader.rb
|
95
104
|
- lib/heirloom/aws.rb
|
105
|
+
- lib/heirloom/aws/s3.rb
|
106
|
+
- lib/heirloom/aws/simpledb.rb
|
96
107
|
- lib/heirloom/cli.rb
|
97
108
|
- lib/heirloom/config.rb
|
109
|
+
- lib/heirloom/destroyer.rb
|
110
|
+
- lib/heirloom/destroyer/s3.rb
|
111
|
+
- lib/heirloom/directory.rb
|
112
|
+
- lib/heirloom/directory/git_directory.rb
|
113
|
+
- lib/heirloom/uploader.rb
|
114
|
+
- lib/heirloom/uploader/s3.rb
|
98
115
|
- lib/heirloom/version.rb
|
116
|
+
- script/ci_setup
|
117
|
+
- spec/config_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
99
119
|
homepage: ''
|
100
120
|
licenses: []
|
101
121
|
post_install_message:
|
@@ -110,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
130
|
version: '0'
|
111
131
|
segments:
|
112
132
|
- 0
|
113
|
-
hash:
|
133
|
+
hash: 1523841461293009165
|
114
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
135
|
none: false
|
116
136
|
requirements:
|
@@ -119,11 +139,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
139
|
version: '0'
|
120
140
|
segments:
|
121
141
|
- 0
|
122
|
-
hash:
|
142
|
+
hash: 1523841461293009165
|
123
143
|
requirements: []
|
124
144
|
rubyforge_project: heirloom
|
125
145
|
rubygems_version: 1.8.16
|
126
146
|
signing_key:
|
127
147
|
specification_version: 3
|
128
148
|
summary: I help with artifacts
|
129
|
-
test_files:
|
149
|
+
test_files:
|
150
|
+
- spec/config_spec.rb
|
151
|
+
- spec/spec_helper.rb
|