1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
module CookbookHelper
require 'aws/s3'
def put_in_couchdb_and_s3(cookbook_name, file, revision)
# TODO: set inital state of cookbook to something like 'pre-upload'
cookbook = Cookbook.on(database_from_orgname(params[:organization_id])).new(:display_name => cookbook_name, :revision => revision)
save cookbook
id = cookbook['_id']
Merb.logger.debug "Creating cookbook with id = #{id}"
stream_to_s3(params[:file][:tempfile], id)
# TODO: if upload successful, set cookbook state to something like 'active'
end
def validate_tarball(filepath, cookbook_name)
raise "(try creating with 'tar czf cookbook.tgz cookbook/')" unless system("tar", "tzf", filepath)
# TODO: modify/implement tests and uncomment the next lines
# required_entry_roots = [cookbook_name]
# allowed_entry_roots = [cookbook_name, "ignore"]
# entry_roots = `tar tzf #{filepath}`.split("\n").map{|e|e.split('/').first}.uniq
# illegal_roots = entry_roots - allowed_entry_roots
# raise "tarball root may only contain #{allowed_entry_roots.join(', ')}" unless illegal_roots.empty?
# missing_required_roots = required_entry_roots - entry_roots
# raise "tarball root must contain #{required_entry_roots.join(', ')}" unless missing_required_roots.empty?
end
def get_all_cookbook_entries(cookbook_name)
rows = Cookbook.on(database_from_orgname(params[:organization_id])).by_display_name(:key => cookbook_name, :include_docs => true)
Merb.logger.debug "Cookbook has the following entries: #{rows.inspect}"
rows
end
def cookbook_id(cookbook_name)
rows = get_all_cookbook_entries(cookbook_name)
return nil if rows.empty?
most_recent_record = rows.sort_by{|row| row['revision'].to_i}.last
Merb.logger.debug "Selected #{most_recent_record.inspect}"
[most_recent_record['_id'], most_recent_record['revision']]
end
# TODO: should we do this once at start-up and test the connection before establishing it?
def establish_connection
AWS::S3::Base.establish_connection!(
:access_key_id => Merb::Config[:aws_secret_access_key_id],
:secret_access_key => Merb::Config[:aws_secret_access_key]
)
end
def stream_to_s3(path, object_id)
establish_connection
AWS::S3::S3Object.store("#{object_id}.tgz", open(path), Merb::Config[:aws_cookbook_tarball_s3_bucket])
end
def stream_from_s3(cookbook_name, id)
establish_connection
# TODO: if the cookbook is large and the user has a slow connection, will this cause the process's memory to bloat or will it just read from S3 slowly?
stream_file do |response|
AWS::S3::S3Object.stream("#{id}.tgz", Merb::Config[:aws_cookbook_tarball_s3_bucket]) do |chunk|
response.write chunk
end
end
end
# TODO: the following methods were heisted from opscode-account. if this is how we want to do it, then do some hoisting
def save(object)
if object.valid?
object.save
else
raise BadRequest, object.errors.full_messages
end
end
def orgname_to_dbname(orgname)
"chef_#{orgname}"
end
def database_from_orgname(orgname)
CouchRest::Database.new(CouchRest::Server.new,orgname_to_dbname(orgname))
end
end
|