ec2_amitools 1.0.2

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.
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