ec2_amitools 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +54 -0
- data/bin/console +14 -0
- data/bin/ec2-ami-tools-version +6 -0
- data/bin/ec2-bundle-image +6 -0
- data/bin/ec2-bundle-vol +6 -0
- data/bin/ec2-delete-bundle +6 -0
- data/bin/ec2-download-bundle +6 -0
- data/bin/ec2-migrate-bundle +6 -0
- data/bin/ec2-migrate-manifest +6 -0
- data/bin/ec2-unbundle +6 -0
- data/bin/ec2-upload-bundle +6 -0
- data/bin/setup +8 -0
- data/etc/ec2/amitools/cert-ec2-cn-north-1.pem +28 -0
- data/etc/ec2/amitools/cert-ec2-gov.pem +17 -0
- data/etc/ec2/amitools/cert-ec2.pem +23 -0
- data/etc/ec2/amitools/mappings.csv +9 -0
- data/lib/ec2/amitools/bundle.rb +251 -0
- data/lib/ec2/amitools/bundle_base.rb +58 -0
- data/lib/ec2/amitools/bundleimage.rb +94 -0
- data/lib/ec2/amitools/bundleimageparameters.rb +42 -0
- data/lib/ec2/amitools/bundlemachineparameters.rb +60 -0
- data/lib/ec2/amitools/bundleparameters.rb +120 -0
- data/lib/ec2/amitools/bundlevol.rb +240 -0
- data/lib/ec2/amitools/bundlevolparameters.rb +164 -0
- data/lib/ec2/amitools/crypto.rb +379 -0
- data/lib/ec2/amitools/decryptmanifest.rb +20 -0
- data/lib/ec2/amitools/defaults.rb +12 -0
- data/lib/ec2/amitools/deletebundle.rb +212 -0
- data/lib/ec2/amitools/deletebundleparameters.rb +78 -0
- data/lib/ec2/amitools/downloadbundle.rb +161 -0
- data/lib/ec2/amitools/downloadbundleparameters.rb +84 -0
- data/lib/ec2/amitools/exception.rb +86 -0
- data/lib/ec2/amitools/fileutil.rb +219 -0
- data/lib/ec2/amitools/format.rb +127 -0
- data/lib/ec2/amitools/instance-data.rb +97 -0
- data/lib/ec2/amitools/manifest_wrapper.rb +132 -0
- data/lib/ec2/amitools/manifestv20070829.rb +361 -0
- data/lib/ec2/amitools/manifestv20071010.rb +403 -0
- data/lib/ec2/amitools/manifestv3.rb +331 -0
- data/lib/ec2/amitools/mapids.rb +148 -0
- data/lib/ec2/amitools/migratebundle.rb +222 -0
- data/lib/ec2/amitools/migratebundleparameters.rb +173 -0
- data/lib/ec2/amitools/migratemanifest.rb +225 -0
- data/lib/ec2/amitools/migratemanifestparameters.rb +118 -0
- data/lib/ec2/amitools/minimalec2.rb +116 -0
- data/lib/ec2/amitools/parameter_exceptions.rb +34 -0
- data/lib/ec2/amitools/parameters_base.rb +168 -0
- data/lib/ec2/amitools/region.rb +93 -0
- data/lib/ec2/amitools/s3toolparameters.rb +183 -0
- data/lib/ec2/amitools/showversion.rb +12 -0
- data/lib/ec2/amitools/syschecks.rb +27 -0
- data/lib/ec2/amitools/tool_base.rb +224 -0
- data/lib/ec2/amitools/unbundle.rb +107 -0
- data/lib/ec2/amitools/unbundleparameters.rb +65 -0
- data/lib/ec2/amitools/uploadbundle.rb +361 -0
- data/lib/ec2/amitools/uploadbundleparameters.rb +108 -0
- data/lib/ec2/amitools/util.rb +532 -0
- data/lib/ec2/amitools/version.rb +33 -0
- data/lib/ec2/amitools/xmlbuilder.rb +237 -0
- data/lib/ec2/amitools/xmlutil.rb +55 -0
- data/lib/ec2/common/constants.rb +16 -0
- data/lib/ec2/common/curl.rb +110 -0
- data/lib/ec2/common/headers.rb +95 -0
- data/lib/ec2/common/headersv4.rb +173 -0
- data/lib/ec2/common/http.rb +333 -0
- data/lib/ec2/common/s3support.rb +231 -0
- data/lib/ec2/common/signature.rb +68 -0
- data/lib/ec2/oem/LICENSE.txt +58 -0
- data/lib/ec2/oem/open4.rb +399 -0
- data/lib/ec2/platform/base/architecture.rb +26 -0
- data/lib/ec2/platform/base/constants.rb +54 -0
- data/lib/ec2/platform/base/pipeline.rb +181 -0
- data/lib/ec2/platform/base.rb +57 -0
- data/lib/ec2/platform/current.rb +55 -0
- data/lib/ec2/platform/linux/architecture.rb +35 -0
- data/lib/ec2/platform/linux/constants.rb +23 -0
- data/lib/ec2/platform/linux/fstab.rb +99 -0
- data/lib/ec2/platform/linux/identity.rb +16 -0
- data/lib/ec2/platform/linux/image.rb +811 -0
- data/lib/ec2/platform/linux/mtab.rb +74 -0
- data/lib/ec2/platform/linux/pipeline.rb +40 -0
- data/lib/ec2/platform/linux/rsync.rb +114 -0
- data/lib/ec2/platform/linux/tar.rb +124 -0
- data/lib/ec2/platform/linux/uname.rb +50 -0
- data/lib/ec2/platform/linux.rb +83 -0
- data/lib/ec2/platform/solaris/architecture.rb +28 -0
- data/lib/ec2/platform/solaris/constants.rb +30 -0
- data/lib/ec2/platform/solaris/fstab.rb +43 -0
- data/lib/ec2/platform/solaris/identity.rb +16 -0
- data/lib/ec2/platform/solaris/image.rb +327 -0
- data/lib/ec2/platform/solaris/mtab.rb +29 -0
- data/lib/ec2/platform/solaris/pipeline.rb +40 -0
- data/lib/ec2/platform/solaris/rsync.rb +24 -0
- data/lib/ec2/platform/solaris/tar.rb +36 -0
- data/lib/ec2/platform/solaris/uname.rb +21 -0
- data/lib/ec2/platform/solaris.rb +38 -0
- data/lib/ec2/platform.rb +69 -0
- data/lib/ec2/version.rb +8 -0
- data/lib/ec2_amitools +1 -0
- data/lib/ec2_amitools.rb +7 -0
- metadata +184 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 61e05c7c7f9a080bb9b10d5a15e481da80ae6aa0
|
4
|
+
data.tar.gz: d4285e6efa71a9cd56e7f7952594c249ae178384
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 53819c3f2ab95eb3d778f8216b9411e48da84384947859058e77390af355ff8fca42ea8424d97cf4f68b07d981e4356333ce7084404a743b9d878374fb862c80
|
7
|
+
data.tar.gz: 6ebc9c3a6fa31f1654aae27a5321c2031451058585a0799303b5beba885d840206c2d1a30416cee6f6156d6b8616ef4223aea2e10ad714f746034eefca3c97fd
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# ec2_amitools
|
2
|
+
|
3
|
+
Install Amazon's EC2 AMI Tools as gem.
|
4
|
+
|
5
|
+
## Origins
|
6
|
+
|
7
|
+
Source files for this library were taken from here: http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools-1.5.7.zip
|
8
|
+
More info about original installation from AWS: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-up-ami-tools.html
|
9
|
+
|
10
|
+
## Dependencies
|
11
|
+
|
12
|
+
- curl
|
13
|
+
- gzip
|
14
|
+
- mkfifo
|
15
|
+
- openssl
|
16
|
+
- rsync
|
17
|
+
- Ruby 2.0.0 or later
|
18
|
+
- tee
|
19
|
+
|
20
|
+
For more info take a look at: https://github.com/sfate/ec2_amitools/blob/master/readme-install.txt
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
gem 'ec2_amitools'
|
28
|
+
```
|
29
|
+
|
30
|
+
And then execute:
|
31
|
+
|
32
|
+
$ bundle
|
33
|
+
|
34
|
+
Or install it yourself as:
|
35
|
+
|
36
|
+
$ gem install ec2_amitools
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ami-tools-commands.html
|
41
|
+
|
42
|
+
## Development
|
43
|
+
|
44
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
45
|
+
|
46
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
47
|
+
|
48
|
+
## Contributing
|
49
|
+
|
50
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/sfate/ec2_amitools
|
51
|
+
|
52
|
+
## License - Amazon Software License
|
53
|
+
|
54
|
+
http://github.com/sfate/ec2_amitools/blob/master/license.txt
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "ec2_amitools"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/ec2-bundle-vol
ADDED
data/bin/ec2-unbundle
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIEwTCCA6mgAwIBAgIJALBg5STuwebSMA0GCSqGSIb3DQEBBQUAMIGbMQswCQYD
|
3
|
+
VQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv
|
4
|
+
d24xHDAaBgNVBAoTE0FtYXpvbiBXZWIgU2VydmljZXMxDDAKBgNVBAsTA0VDMjEW
|
5
|
+
MBQGA1UEAxMNQU1JIE1hbmlmZXN0czEdMBsGCSqGSIb3DQEJARYOYWVzQGFtYXpv
|
6
|
+
bi5jb20wHhcNMTMwODI4MTAxNTEwWhcNMTkwMjE4MTAxNTEwWjCBmzELMAkGA1UE
|
7
|
+
BhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
|
8
|
+
MRwwGgYDVQQKExNBbWF6b24gV2ViIFNlcnZpY2VzMQwwCgYDVQQLEwNFQzIxFjAU
|
9
|
+
BgNVBAMTDUFNSSBNYW5pZmVzdHMxHTAbBgkqhkiG9w0BCQEWDmFlc0BhbWF6b24u
|
10
|
+
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA601VE9anUnkM5weg
|
11
|
+
THEUqNkT7fwaKKoTM+oV6n0h5D4LF/qY7IuS7YlxP308P00yE6In4ZHHvc1E/X1e
|
12
|
+
s36t7ojdlx8Pg0jzFLir27BWSl+ddZGJLl0u8FFzJUPmqeiQZW3mKosOqAoj/C5h
|
13
|
+
svXnSmLGxd619eGz2+Kel38LPhwzA8PZeNhil/eK53oo/h7dZvRUtH2+zbYXxq5Q
|
14
|
+
2tsRN1Ef4QaNeKHSdupo8eFNUnmSgeEYz1RC/2QDn6MK7uXijOft4G6iEO4c+PeR
|
15
|
+
wLyBW8YMla2SJk1n4z4gmSJ21uCZ0Bv0A2j/3f+JmgNo4QLIAl/UBWBTT+eSAFYw
|
16
|
+
LVDlrwIDAQABo4IBBDCCAQAwHQYDVR0OBBYEFJSvQRrRg2O1O/kSOEKH2z18OFfH
|
17
|
+
MIHQBgNVHSMEgcgwgcWAFJSvQRrRg2O1O/kSOEKH2z18OFfHoYGhpIGeMIGbMQsw
|
18
|
+
CQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBl
|
19
|
+
IFRvd24xHDAaBgNVBAoTE0FtYXpvbiBXZWIgU2VydmljZXMxDDAKBgNVBAsTA0VD
|
20
|
+
MjEWMBQGA1UEAxMNQU1JIE1hbmlmZXN0czEdMBsGCSqGSIb3DQEJARYOYWVzQGFt
|
21
|
+
YXpvbi5jb22CCQCwYOUk7sHm0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
|
22
|
+
A4IBAQACBMJpb8N7cT0PP3u814D1Ngd2vqEv6aB8saklT44kWwAXDcILVtPd09ae
|
23
|
+
8q1oWSKpWlGo9Z8gUS92QXMIMxSZCxDdN4MflYWGio5HFvpS/msHVkK9H80nypSd
|
24
|
+
pLS3FP0arr/3tETS8TIhs4aISwUUfHm0W7WrmLaQz8TyfuktVtPrKIMmWgXiJmCo
|
25
|
+
HQkuFe4rjx0y7r8CGQocwo79+m+35aLip44jWB4yLuUgp0wVhT5nxfG/iNX2lUiP
|
26
|
+
Bw/yCpzeJoLBWvFDlunBNu2s0Y3ddFdnlna/k7CQM1Js6+OGQBMh1zTtJlPkkHj3
|
27
|
+
mbaTR6i5yro01FowChTryrRTVfMe
|
28
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,17 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIICvzCCAigCCQD3V6lFvX6dzDANBgkqhkiG9w0BAQUFADCBozELMAkGA1UEBhMC
|
3
|
+
VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMRMwEQYDVQQKEwpBbWF6
|
4
|
+
b24uY29tMRYwFAYDVQQLEw1FQzIgQXV0aG9yaXR5MRowGAYDVQQDExFFQzIgQU1J
|
5
|
+
IEF1dGhvcml0eTEsMCoGCSqGSIb3DQEJARYdZWMyLWFtaS1nb3Ytd2VzdC0xQGFt
|
6
|
+
YXpvbi5jb20wHhcNMTEwODEyMTcyNjE1WhcNMjEwODA5MTcyNjE1WjCBozELMAkG
|
7
|
+
A1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMRMwEQYDVQQK
|
8
|
+
EwpBbWF6b24uY29tMRYwFAYDVQQLEw1FQzIgQXV0aG9yaXR5MRowGAYDVQQDExFF
|
9
|
+
QzIgQU1JIEF1dGhvcml0eTEsMCoGCSqGSIb3DQEJARYdZWMyLWFtaS1nb3Ytd2Vz
|
10
|
+
dC0xQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANshKnhw
|
11
|
+
DUZ2/6VJwVTsXMUI1CGd5rpSpSLUCHGuqII+BDUvnp/sPxd1u6+I1QrbaaBAOm6+
|
12
|
+
evM77M7vNJXY3+JW00VOs9NgPEXBmn6UV4R1P7DljKurWGmRp8Fj1yVU4sSgZqqv
|
13
|
+
74SyhD0Z4ASczVcOiTZICeuQoJwmeZ8F20oLAgMBAAEwDQYJKoZIhvcNAQEFBQAD
|
14
|
+
gYEAH3vpkD80ngP1e18UYSVBCODArik+aeUPAzJrPDYorrnffbamks50IMTktyiu
|
15
|
+
za1JuplrvVsAKcQhyoPOq69bwRDg4L8VOXSCjjvsNuEhHL603h8jn6ghEouPCPl7
|
16
|
+
8s4Sr5XikmAgwFcPb/frNnLuZsSol08tISgPOlFg4KLv/bo=
|
17
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,23 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDzjCCAzegAwIBAgIJALDnZV+lpZdSMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD
|
3
|
+
VQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv
|
4
|
+
d24xJzAlBgNVBAoTHkFtYXpvbiBEZXZlbG9wbWVudCBDZW50cmUgKFNBKTEMMAoG
|
5
|
+
A1UECxMDQUVTMREwDwYDVQQDEwhBRVMgVGVzdDEdMBsGCSqGSIb3DQEJARYOYWVz
|
6
|
+
QGFtYXpvbi5jb20wHhcNMDUwODA5MTYwMTA5WhcNMDYwODA5MTYwMTA5WjCBoTEL
|
7
|
+
MAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2Fw
|
8
|
+
ZSBUb3duMScwJQYDVQQKEx5BbWF6b24gRGV2ZWxvcG1lbnQgQ2VudHJlIChTQSkx
|
9
|
+
DDAKBgNVBAsTA0FFUzERMA8GA1UEAxMIQUVTIFRlc3QxHTAbBgkqhkiG9w0BCQEW
|
10
|
+
DmFlc0BhbWF6b24uY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8v/X5
|
11
|
+
zZv8CAVfNmvBM0br/RUcf1wU8xC5d2otFQQsQKB3qiWoj3oHeOWskOlTPFVZ8N+/
|
12
|
+
hEaMjyOUkg2+g6XEagCQtFCEBzUVoMjiQIBPiWj5CWkFtlav2zt33LZ0ErTND4xl
|
13
|
+
j7FQFqbaytHU9xuQcFO2p12bdITiBs5Kwoi9bQIDAQABo4IBCjCCAQYwHQYDVR0O
|
14
|
+
BBYEFPQnsX1kDVzPtX+38ACV8RhoYcw8MIHWBgNVHSMEgc4wgcuAFPQnsX1kDVzP
|
15
|
+
tX+38ACV8RhoYcw8oYGnpIGkMIGhMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2Vz
|
16
|
+
dGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xJzAlBgNVBAoTHkFtYXpvbiBE
|
17
|
+
ZXZlbG9wbWVudCBDZW50cmUgKFNBKTEMMAoGA1UECxMDQUVTMREwDwYDVQQDEwhB
|
18
|
+
RVMgVGVzdDEdMBsGCSqGSIb3DQEJARYOYWVzQGFtYXpvbi5jb22CCQCw52VfpaWX
|
19
|
+
UjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAJJlWll4uGlrqBzeIw7u
|
20
|
+
M3RvomlxMESwGKb9gI+ZeORlnHAyZxvd9XngIcjPuU+8uc3wc10LRQUCn45a5hFs
|
21
|
+
zaCp9BSewLCCirn6awZn2tP8JlagSbjrN9YShStt8S3S/Jj+eBoRvc7jJnmEeMkx
|
22
|
+
O0wHOzp5ZHRDK7tGULD6jCfU
|
23
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,9 @@
|
|
1
|
+
eu-west-1,us-east-1,manifest
|
2
|
+
ari-6b0d251f,ari-a23adfcb,initrd-2.6.20-1.3002.fc6xen.ari.manifest.xml
|
3
|
+
ari-7f0d250b,ari-b31cf9da,ec2-initrd-2.6.21.7-2.fc8xen.x86_64.manifest.xml
|
4
|
+
aki-6a0d251e,aki-a53adfcc,vmlinuz-2.6.20-1.3002.fc6xen.aki.manifest.xml
|
5
|
+
aki-550d2521,aki-9800e5f1,vmlinuz-2.6.18-xenU-ec2-v1.0.x86_64.aki.manifest.xml
|
6
|
+
aki-780d250c,aki-b51cf9dc,ec2-vmlinuz-2.6.21.7-2.fc8xen.x86_64.manifest.xml
|
7
|
+
ari-7d0d2509,ari-a51cf9cc,ec2-initrd-2.6.21.7-2.fc8xen.i386.manifest.xml
|
8
|
+
aki-540d2520,aki-9b00e5f2,vmlinuz-2.6.18-xenU-ec2-v1.0.i386.aki.manifest.xml
|
9
|
+
aki-7e0d250a,aki-a71cf9ce,ec2-vmlinuz-2.6.21.7-2.fc8xen.i386.manifest.xml
|
@@ -0,0 +1,251 @@
|
|
1
|
+
# Copyright 2008-2014 Amazon.com, Inc. or its affiliates. All Rights
|
2
|
+
# Reserved. Licensed under the Amazon Software License (the
|
3
|
+
# "License"). You may not use this file except in compliance with the
|
4
|
+
# License. A copy of the License is located at
|
5
|
+
# http://aws.amazon.com/asl or in the "license" file accompanying this
|
6
|
+
# file. This file is distributed on an "AS IS" BASIS, WITHOUT
|
7
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
|
8
|
+
# the License for the specific language governing permissions and
|
9
|
+
# limitations under the License.
|
10
|
+
|
11
|
+
require 'open-uri'
|
12
|
+
require 'ec2/amitools/fileutil'
|
13
|
+
require 'ec2/amitools/manifestv20071010'
|
14
|
+
require 'ec2/amitools/instance-data'
|
15
|
+
require 'ec2/amitools/version'
|
16
|
+
require 'ec2/platform/current'
|
17
|
+
|
18
|
+
# Module containing utility methods for bundling an AMI.
|
19
|
+
module Bundle
|
20
|
+
class ImageType < String
|
21
|
+
MACHINE = new 'machine'
|
22
|
+
KERNEL = new 'kernel'
|
23
|
+
RAMDISK = new 'ramdisk'
|
24
|
+
VOLUME = new 'machine'
|
25
|
+
def ==(o)
|
26
|
+
self.object_id == o.object_id
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
CHUNK_SIZE = 10 * 1024 * 1024 # 10 MB in bytes.
|
32
|
+
|
33
|
+
def self.bundle_image( image_file,
|
34
|
+
user,
|
35
|
+
arch,
|
36
|
+
image_type,
|
37
|
+
destination,
|
38
|
+
user_private_key_path,
|
39
|
+
user_cert_path,
|
40
|
+
ec2_cert_path,
|
41
|
+
prefix,
|
42
|
+
optional_args,
|
43
|
+
debug = false,
|
44
|
+
inherit = true
|
45
|
+
)
|
46
|
+
begin
|
47
|
+
raise "invalid image-type #{image_type}" unless image_type.is_a? Bundle::ImageType
|
48
|
+
# Create named pipes.
|
49
|
+
digest_pipe = File::join('/tmp', "ec2-bundle-image-digest-pipe-#{$$}")
|
50
|
+
File::delete(digest_pipe) if File::exist?(digest_pipe)
|
51
|
+
unless system( "mkfifo #{digest_pipe}" )
|
52
|
+
raise "Error creating named pipe #{digest_pipe}"
|
53
|
+
end
|
54
|
+
|
55
|
+
# If the prefix differs from the file name create a symlink
|
56
|
+
# so that the file is tarred with the prefix name.
|
57
|
+
if prefix and File::basename( image_file ) != prefix
|
58
|
+
image_file_link = File::join( destination, prefix )
|
59
|
+
begin
|
60
|
+
FileUtils.ln_s(image_file, image_file_link)
|
61
|
+
rescue Exception => e
|
62
|
+
raise "Error creating symlink to image file, #{e.message}."
|
63
|
+
end
|
64
|
+
image_file = image_file_link
|
65
|
+
end
|
66
|
+
|
67
|
+
# Load and generate necessary keys.
|
68
|
+
name = prefix || File::basename( image_file )
|
69
|
+
manifest_file = File.join( destination, name + '.manifest.xml')
|
70
|
+
bundled_file_path = File::join( destination, name + '.tar.gz.enc' )
|
71
|
+
user_public_key = Crypto::certfile2pubkey( user_cert_path )
|
72
|
+
ec2_public_key = Crypto::certfile2pubkey( ec2_cert_path )
|
73
|
+
key = Format::bin2hex( Crypto::gensymkey )
|
74
|
+
iv = Format::bin2hex( Crypto::gensymkey )
|
75
|
+
|
76
|
+
# Bundle the AMI.
|
77
|
+
# The image file is tarred - to maintain sparseness, gzipped for
|
78
|
+
# compression and then encrypted with AES in CBC mode for
|
79
|
+
# confidentiality.
|
80
|
+
# To minimize disk I/O the file is read from disk once and
|
81
|
+
# piped via several processes. The tee is used to allow a
|
82
|
+
# digest of the file to be calculated without having to re-read
|
83
|
+
# it from disk.
|
84
|
+
tar = EC2::Platform::Current::Tar::Command.new.create.dereference.sparse
|
85
|
+
tar.owner(0).group(0)
|
86
|
+
tar.add(File::basename( image_file ), File::dirname( image_file ))
|
87
|
+
openssl = EC2::Platform::Current::Constants::Utility::OPENSSL
|
88
|
+
pipeline = EC2::Platform::Current::Pipeline.new('image-bundle-pipeline', debug)
|
89
|
+
pipeline.concat([
|
90
|
+
['tar', "#{openssl} sha1 < #{digest_pipe} & " + tar.expand],
|
91
|
+
['tee', "tee #{digest_pipe}"],
|
92
|
+
['gzip', 'gzip -9'],
|
93
|
+
['encrypt', "#{openssl} enc -e -aes-128-cbc -K #{key} -iv #{iv} > #{bundled_file_path}"]
|
94
|
+
])
|
95
|
+
digest = nil
|
96
|
+
begin
|
97
|
+
digest = pipeline.execute.split(/\s+/).last.strip
|
98
|
+
rescue EC2::Platform::Current::Pipeline::ExecutionError => e
|
99
|
+
$stderr.puts e.message
|
100
|
+
exit 1
|
101
|
+
end
|
102
|
+
|
103
|
+
# Split the bundled AMI.
|
104
|
+
# Splitting is not done as part of the compress, encrypt digest
|
105
|
+
# stream, so that the filenames of the parts can be easily
|
106
|
+
# tracked. The alternative is to create a dedicated output
|
107
|
+
# directory, but this leaves the user less choice.
|
108
|
+
parts = Bundle::split( bundled_file_path, name, destination )
|
109
|
+
|
110
|
+
# Sum the parts file sizes to get the encrypted file size.
|
111
|
+
bundled_size = 0
|
112
|
+
parts.each do |part|
|
113
|
+
bundled_size += File.size( File.join( destination, part ) )
|
114
|
+
end
|
115
|
+
|
116
|
+
# Encrypt key and iv.
|
117
|
+
padding = OpenSSL::PKey::RSA::PKCS1_PADDING
|
118
|
+
user_encrypted_key = user_public_key.public_encrypt( key, padding )
|
119
|
+
ec2_encrypted_key = ec2_public_key.public_encrypt( key, padding )
|
120
|
+
user_encrypted_iv = user_public_key.public_encrypt( iv, padding )
|
121
|
+
ec2_encrypted_iv = ec2_public_key.public_encrypt( iv, padding )
|
122
|
+
|
123
|
+
# Digest parts.
|
124
|
+
part_digest_list = Bundle::digest_parts( parts, destination )
|
125
|
+
|
126
|
+
# Launch-customization data
|
127
|
+
patch_in_instance_meta_data(image_type, optional_args) if inherit
|
128
|
+
|
129
|
+
# Sanity-check block-device-mappings
|
130
|
+
bdm = optional_args[:block_device_mapping]
|
131
|
+
if bdm.is_a? Hash
|
132
|
+
[ 'root', 'ami' ].each do |item|
|
133
|
+
if bdm[item].to_s.strip.empty?
|
134
|
+
$stdout.puts "Block-device-mapping has no '#{item}' entry. A launch-time default will be used."
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
# Create bundle manifest.
|
141
|
+
$stdout.puts 'Creating bundle manifest...'
|
142
|
+
manifest = ManifestV20071010.new()
|
143
|
+
manifest.init(optional_args.merge({:name => name,
|
144
|
+
:user => user,
|
145
|
+
:image_type => image_type.to_s,
|
146
|
+
:arch => arch,
|
147
|
+
:reserved => nil,
|
148
|
+
:parts => part_digest_list,
|
149
|
+
:size => File::size( image_file ),
|
150
|
+
:bundled_size => bundled_size,
|
151
|
+
:user_encrypted_key => Format::bin2hex( user_encrypted_key ),
|
152
|
+
:ec2_encrypted_key => Format::bin2hex( ec2_encrypted_key ),
|
153
|
+
:cipher_algorithm => Crypto::SYM_ALG,
|
154
|
+
:user_encrypted_iv => Format::bin2hex( user_encrypted_iv ),
|
155
|
+
:ec2_encrypted_iv => Format::bin2hex( ec2_encrypted_iv ),
|
156
|
+
:digest => digest,
|
157
|
+
:digest_algorithm => Crypto::DIGEST_ALG,
|
158
|
+
:privkey_filename => user_private_key_path,
|
159
|
+
:kernel_id => optional_args[:kernel_id],
|
160
|
+
:ramdisk_id => optional_args[:ramdisk_id],
|
161
|
+
:product_codes => optional_args[:product_codes],
|
162
|
+
:ancestor_ami_ids => optional_args[:ancestor_ami_ids],
|
163
|
+
:block_device_mapping => optional_args[:block_device_mapping],
|
164
|
+
:bundler_name => EC2Version::PKG_NAME,
|
165
|
+
:bundler_version => EC2Version::PKG_VERSION,
|
166
|
+
:bundler_release => EC2Version::PKG_RELEASE}))
|
167
|
+
|
168
|
+
# Write out the manifest file.
|
169
|
+
File.open( manifest_file, 'w' ) { |f| f.write( manifest.to_s ) }
|
170
|
+
$stdout.puts 'Bundle manifest is %s' % manifest_file
|
171
|
+
ensure
|
172
|
+
# Clean up.
|
173
|
+
if bundled_file_path and File.exist?( bundled_file_path )
|
174
|
+
File.delete( bundled_file_path )
|
175
|
+
end
|
176
|
+
File::delete( digest_pipe ) if digest_pipe and File::exist?(digest_pipe)
|
177
|
+
if image_file_link and File::exist?( image_file_link )
|
178
|
+
File::delete( image_file_link )
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.patch_in_instance_meta_data(image_type, optional_args)
|
184
|
+
if (image_type == ImageType::VOLUME || image_type == ImageType::MACHINE )
|
185
|
+
instance_data = EC2::InstanceData.new
|
186
|
+
if !instance_data.instance_data_accessible
|
187
|
+
raise "Error accessing instance data. If you are not bundling on an EC2 instance use --no-inherit."
|
188
|
+
else
|
189
|
+
[
|
190
|
+
[:ancestor_ami_ids, instance_data.ancestor_ami_ids, Proc.new do |key, value|
|
191
|
+
if (optional_args[key].nil?)
|
192
|
+
ancestry = nil
|
193
|
+
if value.nil? or value.to_s.empty?
|
194
|
+
ancestry = []
|
195
|
+
elsif value.is_a? Array
|
196
|
+
ancestry = value
|
197
|
+
else
|
198
|
+
ancestry = [value]
|
199
|
+
end
|
200
|
+
ami_id = instance_data.ami_id
|
201
|
+
$stdout.puts "Unable to read instance meta-data for ami-id" if ami_id.nil?
|
202
|
+
ancestry << ami_id unless(ami_id.nil? or ancestry.include?(ami_id))
|
203
|
+
optional_args[key] = ancestry if ancestry && ancestry.length > 0
|
204
|
+
end
|
205
|
+
end],
|
206
|
+
[:kernel_id, instance_data.kernel_id, nil],
|
207
|
+
[:ramdisk_id, instance_data.ramdisk_id, nil],
|
208
|
+
[:product_codes, instance_data.product_codes, nil],
|
209
|
+
[:block_device_mapping, instance_data.block_device_mapping, nil],
|
210
|
+
].each do |key, value, block|
|
211
|
+
begin
|
212
|
+
if value.nil?
|
213
|
+
$stdout.puts "Unable to read instance meta-data for #{key.to_s.gsub('_','-')}"
|
214
|
+
block.call(key, value) if block
|
215
|
+
else
|
216
|
+
if block
|
217
|
+
block.call(key, value)
|
218
|
+
else
|
219
|
+
optional_args[key] ||= value
|
220
|
+
end
|
221
|
+
end
|
222
|
+
rescue
|
223
|
+
$stdout.puts "Unable to set #{key.to_s.gsub('_','-')} from instance meta-data"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.split( filename, prefix, destination )
|
231
|
+
$stdout.puts "Splitting #{filename}..."
|
232
|
+
part_filenames = FileUtil::split(filename,
|
233
|
+
prefix,
|
234
|
+
CHUNK_SIZE,
|
235
|
+
destination)
|
236
|
+
part_filenames.each { |name| puts "Created #{name}" }
|
237
|
+
part_filenames
|
238
|
+
end
|
239
|
+
|
240
|
+
def self.digest_parts( basenames, dir )
|
241
|
+
$stdout.puts 'Generating digests for each part...'
|
242
|
+
parts_digests = Array.new
|
243
|
+
basenames.each do |basename|
|
244
|
+
File.open(File.join(dir, basename)) do |f|
|
245
|
+
parts_digests << [basename, Crypto.digest( f )]
|
246
|
+
end
|
247
|
+
end
|
248
|
+
$stdout.puts 'Digests generated.'
|
249
|
+
parts_digests
|
250
|
+
end
|
251
|
+
end
|