ec2_amitools 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +54 -0
  3. data/bin/console +14 -0
  4. data/bin/ec2-ami-tools-version +6 -0
  5. data/bin/ec2-bundle-image +6 -0
  6. data/bin/ec2-bundle-vol +6 -0
  7. data/bin/ec2-delete-bundle +6 -0
  8. data/bin/ec2-download-bundle +6 -0
  9. data/bin/ec2-migrate-bundle +6 -0
  10. data/bin/ec2-migrate-manifest +6 -0
  11. data/bin/ec2-unbundle +6 -0
  12. data/bin/ec2-upload-bundle +6 -0
  13. data/bin/setup +8 -0
  14. data/etc/ec2/amitools/cert-ec2-cn-north-1.pem +28 -0
  15. data/etc/ec2/amitools/cert-ec2-gov.pem +17 -0
  16. data/etc/ec2/amitools/cert-ec2.pem +23 -0
  17. data/etc/ec2/amitools/mappings.csv +9 -0
  18. data/lib/ec2/amitools/bundle.rb +251 -0
  19. data/lib/ec2/amitools/bundle_base.rb +58 -0
  20. data/lib/ec2/amitools/bundleimage.rb +94 -0
  21. data/lib/ec2/amitools/bundleimageparameters.rb +42 -0
  22. data/lib/ec2/amitools/bundlemachineparameters.rb +60 -0
  23. data/lib/ec2/amitools/bundleparameters.rb +120 -0
  24. data/lib/ec2/amitools/bundlevol.rb +240 -0
  25. data/lib/ec2/amitools/bundlevolparameters.rb +164 -0
  26. data/lib/ec2/amitools/crypto.rb +379 -0
  27. data/lib/ec2/amitools/decryptmanifest.rb +20 -0
  28. data/lib/ec2/amitools/defaults.rb +12 -0
  29. data/lib/ec2/amitools/deletebundle.rb +212 -0
  30. data/lib/ec2/amitools/deletebundleparameters.rb +78 -0
  31. data/lib/ec2/amitools/downloadbundle.rb +161 -0
  32. data/lib/ec2/amitools/downloadbundleparameters.rb +84 -0
  33. data/lib/ec2/amitools/exception.rb +86 -0
  34. data/lib/ec2/amitools/fileutil.rb +219 -0
  35. data/lib/ec2/amitools/format.rb +127 -0
  36. data/lib/ec2/amitools/instance-data.rb +97 -0
  37. data/lib/ec2/amitools/manifest_wrapper.rb +132 -0
  38. data/lib/ec2/amitools/manifestv20070829.rb +361 -0
  39. data/lib/ec2/amitools/manifestv20071010.rb +403 -0
  40. data/lib/ec2/amitools/manifestv3.rb +331 -0
  41. data/lib/ec2/amitools/mapids.rb +148 -0
  42. data/lib/ec2/amitools/migratebundle.rb +222 -0
  43. data/lib/ec2/amitools/migratebundleparameters.rb +173 -0
  44. data/lib/ec2/amitools/migratemanifest.rb +225 -0
  45. data/lib/ec2/amitools/migratemanifestparameters.rb +118 -0
  46. data/lib/ec2/amitools/minimalec2.rb +116 -0
  47. data/lib/ec2/amitools/parameter_exceptions.rb +34 -0
  48. data/lib/ec2/amitools/parameters_base.rb +168 -0
  49. data/lib/ec2/amitools/region.rb +93 -0
  50. data/lib/ec2/amitools/s3toolparameters.rb +183 -0
  51. data/lib/ec2/amitools/showversion.rb +12 -0
  52. data/lib/ec2/amitools/syschecks.rb +27 -0
  53. data/lib/ec2/amitools/tool_base.rb +224 -0
  54. data/lib/ec2/amitools/unbundle.rb +107 -0
  55. data/lib/ec2/amitools/unbundleparameters.rb +65 -0
  56. data/lib/ec2/amitools/uploadbundle.rb +361 -0
  57. data/lib/ec2/amitools/uploadbundleparameters.rb +108 -0
  58. data/lib/ec2/amitools/util.rb +532 -0
  59. data/lib/ec2/amitools/version.rb +33 -0
  60. data/lib/ec2/amitools/xmlbuilder.rb +237 -0
  61. data/lib/ec2/amitools/xmlutil.rb +55 -0
  62. data/lib/ec2/common/constants.rb +16 -0
  63. data/lib/ec2/common/curl.rb +110 -0
  64. data/lib/ec2/common/headers.rb +95 -0
  65. data/lib/ec2/common/headersv4.rb +173 -0
  66. data/lib/ec2/common/http.rb +333 -0
  67. data/lib/ec2/common/s3support.rb +231 -0
  68. data/lib/ec2/common/signature.rb +68 -0
  69. data/lib/ec2/oem/LICENSE.txt +58 -0
  70. data/lib/ec2/oem/open4.rb +399 -0
  71. data/lib/ec2/platform/base/architecture.rb +26 -0
  72. data/lib/ec2/platform/base/constants.rb +54 -0
  73. data/lib/ec2/platform/base/pipeline.rb +181 -0
  74. data/lib/ec2/platform/base.rb +57 -0
  75. data/lib/ec2/platform/current.rb +55 -0
  76. data/lib/ec2/platform/linux/architecture.rb +35 -0
  77. data/lib/ec2/platform/linux/constants.rb +23 -0
  78. data/lib/ec2/platform/linux/fstab.rb +99 -0
  79. data/lib/ec2/platform/linux/identity.rb +16 -0
  80. data/lib/ec2/platform/linux/image.rb +811 -0
  81. data/lib/ec2/platform/linux/mtab.rb +74 -0
  82. data/lib/ec2/platform/linux/pipeline.rb +40 -0
  83. data/lib/ec2/platform/linux/rsync.rb +114 -0
  84. data/lib/ec2/platform/linux/tar.rb +124 -0
  85. data/lib/ec2/platform/linux/uname.rb +50 -0
  86. data/lib/ec2/platform/linux.rb +83 -0
  87. data/lib/ec2/platform/solaris/architecture.rb +28 -0
  88. data/lib/ec2/platform/solaris/constants.rb +30 -0
  89. data/lib/ec2/platform/solaris/fstab.rb +43 -0
  90. data/lib/ec2/platform/solaris/identity.rb +16 -0
  91. data/lib/ec2/platform/solaris/image.rb +327 -0
  92. data/lib/ec2/platform/solaris/mtab.rb +29 -0
  93. data/lib/ec2/platform/solaris/pipeline.rb +40 -0
  94. data/lib/ec2/platform/solaris/rsync.rb +24 -0
  95. data/lib/ec2/platform/solaris/tar.rb +36 -0
  96. data/lib/ec2/platform/solaris/uname.rb +21 -0
  97. data/lib/ec2/platform/solaris.rb +38 -0
  98. data/lib/ec2/platform.rb +69 -0
  99. data/lib/ec2/version.rb +8 -0
  100. data/lib/ec2_amitools +1 -0
  101. data/lib/ec2_amitools.rb +7 -0
  102. 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__)
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/showversion.rb'
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/bundleimage.rb'
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/bundlevol.rb'
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/deletebundle.rb'
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/downloadbundle.rb'
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/migratebundle.rb'
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/migratemanifest.rb'
data/bin/ec2-unbundle ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/unbundle.rb'
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ec2_amitools"
5
+
6
+ load 'ec2/amitools/uploadbundle.rb'
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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