chef-vpc-toolkit 2.0.0
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 +2 -0
- data/COPYING +26 -0
- data/README.rdoc +75 -0
- data/Rakefile +34 -0
- data/VERSION +1 -0
- data/bin/chef-vpc-toolkit +80 -0
- data/config/chef_installer.yml +20 -0
- data/config/databags.json.example +24 -0
- data/config/nodes.json +10 -0
- data/config/server_group.json +16 -0
- data/contrib/doc/ChefVPCToolkit.odt +0 -0
- data/contrib/doc/ChefVPCToolkit.pdf +0 -0
- data/contrib/etc/chef_vpc_toolkit.conf +10 -0
- data/contrib/rake/Rakefile +23 -0
- data/cookbook-repos/local/README +5 -0
- data/cookbook-repos/local/Rakefile +66 -0
- data/cookbook-repos/local/certificates/README +1 -0
- data/cookbook-repos/local/config/client.rb.example +21 -0
- data/cookbook-repos/local/config/knife.rb.example +10 -0
- data/cookbook-repos/local/config/rake.rb +60 -0
- data/cookbook-repos/local/config/server.rb.example +42 -0
- data/cookbook-repos/local/config/solo.rb.example +13 -0
- data/cookbook-repos/local/cookbooks/README +4 -0
- data/cookbook-repos/local/cookbooks/motd/README.rdoc +15 -0
- data/cookbook-repos/local/cookbooks/motd/attributes/motd.rb +1 -0
- data/cookbook-repos/local/cookbooks/motd/metadata.rb +6 -0
- data/cookbook-repos/local/cookbooks/motd/recipes/default.rb +13 -0
- data/cookbook-repos/local/cookbooks/motd/templates/default/motd.erb +1 -0
- data/cookbook-repos/local/roles/README +4 -0
- data/lib/chef-vpc-toolkit.rb +6 -0
- data/lib/chef-vpc-toolkit/chef-0.9.bash +232 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/centos.bash +47 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/fedora.bash +41 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/rhel.bash +38 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/ubuntu.bash +32 -0
- data/lib/chef-vpc-toolkit/chef_installer.rb +276 -0
- data/lib/chef-vpc-toolkit/cloud_files.bash +67 -0
- data/lib/chef-vpc-toolkit/cloud_servers_vpc.rb +285 -0
- data/lib/chef-vpc-toolkit/http_util.rb +117 -0
- data/lib/chef-vpc-toolkit/ssh_util.rb +22 -0
- data/lib/chef-vpc-toolkit/util.rb +56 -0
- data/lib/chef-vpc-toolkit/version.rb +8 -0
- data/rake/chef_vpc_toolkit.rake +284 -0
- data/test/cloud_servers_vpc_test.rb +174 -0
- data/test/test_helper.rb +25 -0
- metadata +153 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
function install_chef {
|
2
|
+
|
3
|
+
local INSTALL_TYPE=${1:-"CLIENT"} # CLIENT/SERVER
|
4
|
+
|
5
|
+
[[ "$INSTALL_TYPE" == "CLIENT" ]] || { echo "Chef server installations are not yet supported on Fedora."; exit 1; }
|
6
|
+
|
7
|
+
yum install -q -y ruby ruby-devel gcc gcc-c++ automake autoconf rubygems make &> /dev/null || { echo "Failed to install ruby, ruby-devel, etc."; exit 1; }
|
8
|
+
gem update --system
|
9
|
+
gem update
|
10
|
+
gem install json -v 1.1.4 --no-rdoc --no-ri &> /dev/null || \
|
11
|
+
{ echo "Failed to install JSON gem on $HOSTNAME."; exit 1; }
|
12
|
+
gem install ohai -v 0.5.6 --no-rdoc --no-ri &> /dev/null || \
|
13
|
+
{ echo "Failed to install ohai gem on $HOSTNAME."; exit 1; }
|
14
|
+
gem install chef -v 0.9.8 --no-rdoc --no-ri &> /dev/null || \
|
15
|
+
{ echo "Failed to install chef gem on $HOSTNAME."; exit 1; }
|
16
|
+
|
17
|
+
for DIR in /etc/chef /var/log/chef /var/cache/chef /var/lib/chef /var/run/chef; do
|
18
|
+
mkdir -p $DIR
|
19
|
+
done
|
20
|
+
|
21
|
+
cat > /etc/chef/client.rb <<-"EOF_CAT"
|
22
|
+
log_level :info
|
23
|
+
log_location STDOUT
|
24
|
+
ssl_verify_mode :verify_none
|
25
|
+
chef_server_url "http://localhost:4000"
|
26
|
+
file_cache_path "/var/cache/chef"
|
27
|
+
file_backup_path "/var/lib/chef/backup"
|
28
|
+
pid_file "/var/run/chef/client.pid"
|
29
|
+
cache_options({ :path => "/var/cache/chef/checksums", :skip_expires => true})
|
30
|
+
signing_ca_user "chef"
|
31
|
+
Mixlib::Log::Formatter.show_time = true
|
32
|
+
validation_client_name "chef-validator"
|
33
|
+
validation_key "/etc/chef/validation.pem"
|
34
|
+
client_key "/etc/chef/client.pem"
|
35
|
+
EOF_CAT
|
36
|
+
|
37
|
+
cp /usr/lib/ruby/gems/1.8/gems/chef-0.9.8/distro/redhat/etc/init.d/chef-client /etc/init.d/
|
38
|
+
cp /usr/lib/ruby/gems/1.8/gems/chef-0.9.8/distro/redhat/etc/logrotate.d/chef-client /etc/logrotate.d/
|
39
|
+
chmod 755 /etc/init.d/chef-client
|
40
|
+
|
41
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
function install_chef {
|
2
|
+
|
3
|
+
local INSTALL_TYPE=${1:-"CLIENT"} # CLIENT/SERVER
|
4
|
+
|
5
|
+
# cached RPMs from ELFF
|
6
|
+
local CDN_BASE="http://c2521002.cdn.cloudfiles.rackspacecloud.com"
|
7
|
+
|
8
|
+
local TARBALL="chef-client-0.9.8-rhel5-x86_64.tar.gz"
|
9
|
+
if [[ "$INSTALL_TYPE" == "SERVER" ]]; then
|
10
|
+
TARBALL="chef-server-0.9.8-rhel5-x86_64.tar.gz"
|
11
|
+
fi
|
12
|
+
|
13
|
+
rpm -q rsync &> /dev/null || yum install -y -q rsync
|
14
|
+
rpm -q wget &> /dev/null || yum install -y -q wget
|
15
|
+
|
16
|
+
if ! rpm -q rubygem-chef &> /dev/null; then
|
17
|
+
|
18
|
+
local CHEF_RPM_DIR=$(mktemp -d)
|
19
|
+
|
20
|
+
wget "$CDN_BASE/$TARBALL" -O "$CHEF_RPM_DIR/chef.tar.gz" &> /dev/null \
|
21
|
+
|| { echo "Failed to download Chef RPM tarball."; exit 1; }
|
22
|
+
cd $CHEF_RPM_DIR
|
23
|
+
|
24
|
+
tar xzf chef.tar.gz || { echo "Failed to extract Chef tarball."; exit 1; }
|
25
|
+
rm chef.tar.gz
|
26
|
+
cd chef*
|
27
|
+
yum install -q -y --nogpgcheck */*.rpm
|
28
|
+
if [[ "$INSTALL_TYPE" == "SERVER" ]]; then
|
29
|
+
rpm -q rubygem-chef-server &> /dev/null || { echo "Failed to install chef."; exit 1; }
|
30
|
+
else
|
31
|
+
rpm -q rubygem-chef &> /dev/null || { echo "Failed to install chef."; exit 1; }
|
32
|
+
fi
|
33
|
+
cd /tmp
|
34
|
+
rm -Rf "$CHEF_RPM_DIR"
|
35
|
+
|
36
|
+
fi
|
37
|
+
|
38
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
function install_chef {
|
2
|
+
|
3
|
+
CODENAME=$(cat /etc/*release | grep CODENAME | sed -e "s|^.*=\([^$]*\)$|\1|")
|
4
|
+
local INSTALL_TYPE=${1:-"CLIENT"} # CLIENT/SERVER
|
5
|
+
|
6
|
+
[ -f /etc/apt/sources.list.d/opscode.list ] || echo "deb http://apt.opscode.com $CODENAME main" > /etc/apt/sources.list.d/opscode.list
|
7
|
+
wget -q -O- http://apt.opscode.com/packages@opscode.com.gpg.key | apt-key add - &> /dev/null || { echo "Failed to configure Apt repo."; exit 1; }
|
8
|
+
|
9
|
+
dpkg -L rsync &> /dev/null || apt-get install -y rsync &> /dev/null
|
10
|
+
|
11
|
+
if ! dpkg -L chef &> /dev/null; then
|
12
|
+
|
13
|
+
if [[ "$INSTALL_TYPE" == "SERVER" ]]; then
|
14
|
+
|
15
|
+
[[ "$CODENAME" == "lucid" ]] || { echo "Ubuntu 10.0.4 lucid is required for Chef server installations."; exit 1; }
|
16
|
+
apt-get update &> /dev/null || { echo "Failed to apt-get update."; exit 1; }
|
17
|
+
echo "chef-solr chef-solr/amqp_password password YA1B2C301234Z" | debconf-set-selections &> /dev/null || { echo "Failed to set debconf selections for chef-solr."; exit 1; }
|
18
|
+
echo "chef chef/chef_server_url string http://localhost:4000" | debconf-set-selections &> /dev/null || { echo "Failed to set debconf selections for chef."; exit 1; }
|
19
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y chef-server chef &> /dev/null || { echo "Failed to install the Chef Server via apt-get on $HOSTNAME."; exit 1; }
|
20
|
+
else
|
21
|
+
apt-get update &> /dev/null || { echo "Failed to apt-get update."; exit 1; }
|
22
|
+
echo "chef chef/chef_server_url string http://localhost:4000" | debconf-set-selections &> /dev/null || { echo "Failed to set debconf selections for chef."; exit 1; }
|
23
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y chef &> /dev/null || { echo "Failed to install Chef via apt-get on $HOSTNAME."; exit 1; }
|
24
|
+
fi
|
25
|
+
|
26
|
+
/etc/init.d/chef-client stop &> /dev/null
|
27
|
+
sleep 2
|
28
|
+
rm /var/log/chef/client.log
|
29
|
+
|
30
|
+
fi
|
31
|
+
|
32
|
+
}
|
@@ -0,0 +1,276 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'json'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module ChefVPCToolkit
|
6
|
+
|
7
|
+
module ChefInstaller
|
8
|
+
CHEF_INSTALL_FUNCTIONS=File.dirname(__FILE__) + "/chef-0.9.bash"
|
9
|
+
|
10
|
+
def self.load_configs
|
11
|
+
|
12
|
+
config_file=CHEF_VPC_PROJECT + File::SEPARATOR + "config" + File::SEPARATOR + "chef_installer.yml"
|
13
|
+
|
14
|
+
if File.exists?(config_file) then
|
15
|
+
return YAML.load_file(config_file)
|
16
|
+
else
|
17
|
+
raise "The config/chef_installer.conf file is missing."
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
# validate the chef.json config file by parsing it
|
23
|
+
def self.validate_json(options)
|
24
|
+
|
25
|
+
Util.raise_if_nil_or_empty(options, "chef_json_file")
|
26
|
+
begin
|
27
|
+
JSON.parse(IO.read(options["chef_json_file"]))
|
28
|
+
rescue Exception => e
|
29
|
+
puts "Failed to parse Chef JSON config file:"
|
30
|
+
puts ""
|
31
|
+
raise
|
32
|
+
end
|
33
|
+
|
34
|
+
if not options["databags_json_file"].nil? and not options["databags_json_file"].empty?
|
35
|
+
begin
|
36
|
+
JSON.parse(IO.read(options["databags_json_file"]))
|
37
|
+
rescue Exception => e
|
38
|
+
puts "Failed to parse Databag JSON config file:"
|
39
|
+
puts ""
|
40
|
+
raise
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.install_chef_server(options, machine_os_types)
|
47
|
+
|
48
|
+
Util.raise_if_nil_or_empty(options, "ssh_gateway_ip")
|
49
|
+
Util.raise_if_nil_or_empty(options, "chef_json_file")
|
50
|
+
Util.raise_if_nil_or_empty(options, "chef_server_name")
|
51
|
+
|
52
|
+
# should we install a Chef client on the server?
|
53
|
+
json=JSON.parse(IO.read(options["chef_json_file"]))
|
54
|
+
configure_client_script=""
|
55
|
+
start_client_script=""
|
56
|
+
if json.has_key?(options["chef_server_name"]) then
|
57
|
+
configure_client_script="configure_chef_client '#{options['chef_server_name']}' ''"
|
58
|
+
start_client_script="start_chef_client"
|
59
|
+
end
|
60
|
+
knife_add_nodes_script=""
|
61
|
+
json.each_pair do |node_name, node_json|
|
62
|
+
run_list=node_json['run_list'].inspect
|
63
|
+
node_json.delete("run_list")
|
64
|
+
attributes=node_json.to_json.to_s
|
65
|
+
knife_add_nodes_script+="knife_add_node '#{node_name}' '#{run_list}' '#{attributes}'\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
cookbook_urls=""
|
69
|
+
if options["chef_cookbook_repos"] then
|
70
|
+
cookbook_urls=options["chef_cookbook_repos"].inject { |sum, c| sum + " " + c }
|
71
|
+
end
|
72
|
+
os_type=machine_os_types[options['chef_server_name']]
|
73
|
+
|
74
|
+
data=%x{
|
75
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
76
|
+
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
77
|
+
echo "Installing Chef server on: $HOSTNAME"
|
78
|
+
EOF_BASH
|
79
|
+
EOF_GATEWAY
|
80
|
+
}
|
81
|
+
puts data
|
82
|
+
|
83
|
+
data=%x{
|
84
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
85
|
+
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
86
|
+
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
87
|
+
#{IO.read(File.dirname(__FILE__) + "/chef_bootstrap/#{os_type}.bash")}
|
88
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
89
|
+
install_chef "SERVER"
|
90
|
+
|
91
|
+
mkdir -p /root/cookbook-repos
|
92
|
+
|
93
|
+
configure_chef_server
|
94
|
+
start_chef_server
|
95
|
+
|
96
|
+
#{configure_client_script}
|
97
|
+
|
98
|
+
configure_knife "#{options["knife_editor"]}"
|
99
|
+
|
100
|
+
knife_upload_cookbooks_and_roles
|
101
|
+
|
102
|
+
#{knife_add_nodes_script}
|
103
|
+
|
104
|
+
#{start_client_script}
|
105
|
+
|
106
|
+
EOF_BASH
|
107
|
+
EOF_GATEWAY
|
108
|
+
}
|
109
|
+
puts data
|
110
|
+
|
111
|
+
return client_validation_key(options)
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.client_validation_key(options)
|
116
|
+
|
117
|
+
client_validation_key=%x{
|
118
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
119
|
+
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
120
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
121
|
+
print_client_validation_key
|
122
|
+
EOF_BASH
|
123
|
+
EOF_GATEWAY
|
124
|
+
}
|
125
|
+
|
126
|
+
raise "Client validation key is blank." if client_validation_key.nil? or client_validation_key.empty?
|
127
|
+
|
128
|
+
return client_validation_key
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.install_chef_clients(options, client_validation_key, os_types)
|
133
|
+
|
134
|
+
# configure Chef clients on each node
|
135
|
+
json=JSON.parse(IO.read(options['chef_json_file']))
|
136
|
+
json.each_pair do |hostname, json_hash|
|
137
|
+
if hostname != options['chef_server_name']
|
138
|
+
install_chef_client(options, hostname, client_validation_key, os_types[hostname])
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.install_chef_client(options, client_name, client_validation_key, os_type)
|
145
|
+
|
146
|
+
puts "Installing Chef client on: #{client_name}"
|
147
|
+
|
148
|
+
data=%x{
|
149
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
150
|
+
ssh #{client_name} bash <<-"EOF_BASH"
|
151
|
+
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
152
|
+
#{IO.read(File.dirname(__FILE__) + "/chef_bootstrap/#{os_type}.bash")}
|
153
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
154
|
+
install_chef "CLIENT"
|
155
|
+
configure_chef_client '#{options['chef_server_name']}' '#{client_validation_key}'
|
156
|
+
start_chef_client
|
157
|
+
EOF_BASH
|
158
|
+
EOF_GATEWAY
|
159
|
+
}
|
160
|
+
puts data
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.create_databags(options)
|
165
|
+
|
166
|
+
Util.raise_if_nil_or_empty(options, "ssh_gateway_ip")
|
167
|
+
|
168
|
+
if options["databags_json_file"].nil? or options["databags_json_file"].empty?
|
169
|
+
puts "No databag config file specified."
|
170
|
+
return
|
171
|
+
end
|
172
|
+
printf "Creating databags..."
|
173
|
+
STDOUT.flush
|
174
|
+
|
175
|
+
if not File.exists?(options["databags_json_file"]) then
|
176
|
+
raise "Databags json file is missing: #{options["databags_json_file"]}."
|
177
|
+
end
|
178
|
+
|
179
|
+
json=JSON.parse(IO.read(options["databags_json_file"]))
|
180
|
+
|
181
|
+
databag_cmds=""
|
182
|
+
|
183
|
+
json.each_pair do |bag_name, items_json|
|
184
|
+
databag_cmds+="knife data bag delete '#{bag_name}' -y &> /dev/null \n"
|
185
|
+
databag_cmds+="knife data bag create '#{bag_name}' -y \n"
|
186
|
+
|
187
|
+
items_json.each do |item_json|
|
188
|
+
|
189
|
+
item_id=item_json["id"]
|
190
|
+
raise "Databags json missing item ID." if item_id.nil? or item_id.empty?
|
191
|
+
databag_cmds+="knife_create_databag '#{bag_name}' '#{item_id}' '#{item_json.to_json.to_s}'\n"
|
192
|
+
end
|
193
|
+
|
194
|
+
data=%x{
|
195
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
196
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
197
|
+
#{databag_cmds}
|
198
|
+
EOF_GATEWAY
|
199
|
+
}
|
200
|
+
puts "OK."
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.knife_readd_node(options, client_name)
|
207
|
+
|
208
|
+
Util.raise_if_nil_or_empty(options, "ssh_gateway_ip")
|
209
|
+
Util.raise_if_nil_or_empty(options, "chef_json_file")
|
210
|
+
|
211
|
+
json=JSON.parse(IO.read(options["chef_json_file"]))
|
212
|
+
node_json=json[client_name]
|
213
|
+
run_list=node_json['run_list'].inspect
|
214
|
+
node_json.delete("run_list")
|
215
|
+
attributes=node_json.to_json.to_s
|
216
|
+
data=%x{
|
217
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
218
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
219
|
+
knife_delete_node '#{client_name}'
|
220
|
+
knife_add_node '#{client_name}' '#{run_list}' '#{attributes}'
|
221
|
+
EOF_GATEWAY
|
222
|
+
}
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.tail_log(gateway_ip, server_name, log_file="/var/log/chef/client.log", num_lines="100")
|
227
|
+
%x{ssh root@#{gateway_ip} ssh #{server_name} tail -n #{num_lines} #{log_file}}
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.rsync_cookbook_repos(options, local_dir="#{CHEF_VPC_PROJECT}/cookbook-repos/", remote_directory="/root/cookbook-repos")
|
231
|
+
|
232
|
+
if File.exists?(local_dir) then
|
233
|
+
$stdout.printf "Syncing local Chef cookbook repositories..."
|
234
|
+
configs=Util.load_configs
|
235
|
+
%x{ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
236
|
+
mkdir -p #{remote_directory}
|
237
|
+
if [ -f /usr/bin/yum ]; then
|
238
|
+
rpm -q rsync &> /dev/null || yum install -y -q rsync
|
239
|
+
else
|
240
|
+
dpkg -L rsync > /dev/null 2>&1 || apt-get install -y --quiet rsync > /dev/null 2>&1
|
241
|
+
fi
|
242
|
+
EOF_SSH
|
243
|
+
}
|
244
|
+
system("rsync -azL '#{local_dir}' root@#{options['ssh_gateway_ip']}:#{remote_directory}")
|
245
|
+
puts "OK"
|
246
|
+
end
|
247
|
+
|
248
|
+
cookbook_urls=""
|
249
|
+
if options["chef_cookbook_repos"] then
|
250
|
+
cookbook_urls=options["chef_cookbook_repos"].inject { |sum, c| sum + " " + c }
|
251
|
+
end
|
252
|
+
|
253
|
+
data=%x{
|
254
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
255
|
+
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
256
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
257
|
+
|
258
|
+
if [ -n "#{cookbook_urls}" ]; then
|
259
|
+
download_cookbook_repos "#{cookbook_urls}"
|
260
|
+
fi
|
261
|
+
|
262
|
+
if [ -f /root/.chef/knife.rb ]; then
|
263
|
+
echo -n "Uploading cookbooks and roles..."
|
264
|
+
knife_upload_cookbooks_and_roles
|
265
|
+
echo "OK"
|
266
|
+
fi
|
267
|
+
|
268
|
+
EOF_SSH
|
269
|
+
}
|
270
|
+
puts data
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Load the username and password into variables that are used by this
|
2
|
+
# bash API.
|
3
|
+
function install_curl {
|
4
|
+
|
5
|
+
if [ -f /usr/bin/yum ]; then
|
6
|
+
rpm -q curl &> /dev/null || yum install -y -q curl
|
7
|
+
elif [ -f /usr/bin/dpkg ]; then
|
8
|
+
dpkg -L curl > /dev/null 2>&1 || apt-get install -y --quiet curl > /dev/null 2>&1
|
9
|
+
else
|
10
|
+
echo "Failed to install curl. Unsupported platform."
|
11
|
+
exit 1
|
12
|
+
fi
|
13
|
+
|
14
|
+
}
|
15
|
+
|
16
|
+
function load_cloud_configs {
|
17
|
+
|
18
|
+
if [ -z "$RACKSPACE_CLOUD_API_USERNAME" ] || [ -z "$RACKSPACE_CLOUD_API_KEY" ]; then
|
19
|
+
|
20
|
+
if [ ! -f ~/.rackspace_cloud ]; then
|
21
|
+
echo "Missing .rackspace_cloud config file."
|
22
|
+
exit 1
|
23
|
+
fi
|
24
|
+
|
25
|
+
export RACKSPACE_CLOUD_API_USERNAME=$(cat ~/.rackspace_cloud | grep "userid" | sed -e "s|.*: \([^ \n\r]*\).*|\1|")
|
26
|
+
export RACKSPACE_CLOUD_API_KEY=$(cat ~/.rackspace_cloud | grep "api_key" | sed -e "s|.*: \([^ \n\r]*\).*|\1|")
|
27
|
+
|
28
|
+
if [ -z "$RACKSPACE_CLOUD_API_USERNAME" ] || [ -z "$RACKSPACE_CLOUD_API_KEY" ]; then
|
29
|
+
echo "Please define a 'userid' and 'api_key' in ~/.rackspace_cloud"
|
30
|
+
exit 1
|
31
|
+
fi
|
32
|
+
|
33
|
+
fi
|
34
|
+
|
35
|
+
}
|
36
|
+
|
37
|
+
# Download a private file from Rackspace Cloud Files using the secure
|
38
|
+
# X-Storage-Url.
|
39
|
+
function download_cloud_file {
|
40
|
+
|
41
|
+
if (( $# != 2 )); then
|
42
|
+
echo "Failed to download cloud file."
|
43
|
+
echo "usage: download_cloud_file <container_url> <output_file>"
|
44
|
+
exit 1
|
45
|
+
fi
|
46
|
+
|
47
|
+
load_cloud_configs
|
48
|
+
install_curl
|
49
|
+
|
50
|
+
local CONTAINER_URL=$1
|
51
|
+
local OUTPUT_FILE=$2
|
52
|
+
|
53
|
+
local AUTH_RESPONSE=$(curl -D - \
|
54
|
+
-H "X-Auth-Key: $RACKSPACE_CLOUD_API_KEY" \
|
55
|
+
-H "X-Auth-User: $RACKSPACE_CLOUD_API_USERNAME" \
|
56
|
+
"https://auth.api.rackspacecloud.com/v1.0" 2> /dev/null)
|
57
|
+
|
58
|
+
[[ $? == 0 ]] || { echo "Failed to authenticate."; exit 1; }
|
59
|
+
|
60
|
+
local AUTH_TOKEN=$(echo $AUTH_RESPONSE | \
|
61
|
+
sed -e "s|.* X-Auth-Token: \([^ \n\r]*\).*|\1|g")
|
62
|
+
local STORAGE_URL=$(echo $AUTH_RESPONSE | \
|
63
|
+
sed -e "s|.* X-Storage-Url: \([^ \n\r]*\).*|\1|g")
|
64
|
+
|
65
|
+
curl -s -X GET -H "X-Auth-Token: $AUTH_TOKEN" "$STORAGE_URL/$CONTAINER_URL" -o "$OUTPUT_FILE"
|
66
|
+
|
67
|
+
}
|