Class: BundleMigrator

Inherits:
AMITool show all
Defined in:
lib/ec2/amitools/migratebundle.rb

Constant Summary

Constants inherited from AMITool

AMITool::BACKOFF_PERIOD, AMITool::MAX_TRIES, AMITool::PROMPT_TIMEOUT

Instance Method Summary collapse

Methods inherited from AMITool

#get_parameters, #handle_early_exit_parameters, #interactive?, #interactive_prompt, #retry_s3, #run, #warn_confirm

Instance Method Details

#copy_part(s3_conn, bucket, keyprefix, dest_bucket, dest_keyprefix, part, acl, retry_copy) ⇒ Object

——————————————————————————#



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/ec2/amitools/migratebundle.rb', line 103

def copy_part(s3_conn, bucket, keyprefix, dest_bucket, dest_keyprefix, part, acl, retry_copy)
  source = "/#{bucket}/#{keyprefix}#{part}"
  retry_s3(retry_copy) do
    begin
      s3_conn.copy(dest_bucket, dest_keyprefix+part, source, {"x-amz-acl"=>acl})
      return
    rescue => e
      raise TryFailed.new("Failed to copy \"#{part}\": #{e.message}")
    end
  end
end

#download_manifest(s3_conn, bucket, manifest_name, manifest_path, user_pk_path, retry_stuff) ⇒ Object

——————————————————————————#



85
86
87
88
89
90
91
92
# File 'lib/ec2/amitools/migratebundle.rb', line 85

def download_manifest(s3_conn, bucket, manifest_name, manifest_path, user_pk_path, retry_stuff)
  BundleDownloader.new().download_manifest(s3_conn,
                                           bucket,
                                           manifest_name,
                                           manifest_path,
                                           user_pk_path,
                                           retry_stuff)
end

#get_manualObject

——————————————————————————# Overrides ——————————————————————————#



184
185
186
# File 'lib/ec2/amitools/migratebundle.rb', line 184

def get_manual()
  MIGRATE_BUNDLE_MANUAL
end

#get_nameObject



188
189
190
# File 'lib/ec2/amitools/migratebundle.rb', line 188

def get_name()
  MIGRATE_BUNDLE_NAME
end

#get_part_filenames(manifest_path, user_cert_path) ⇒ Object

——————————————————————————#



96
97
98
99
# File 'lib/ec2/amitools/migratebundle.rb', line 96

def get_part_filenames(manifest_path, user_cert_path)
  manifest = ManifestMigrator.new().get_manifest(manifest_path, user_cert_path)
  manifest.parts.collect { |part| part.filename }.sort
end

#main(p) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/ec2/amitools/migratebundle.rb', line 192

def main(p)
  migrate_bundle(p.s3_url,
                 p.bucket,
                 p.keyprefix,
                 p.dest_bucket,
                 p.dest_keyprefix,
                 p.manifest_name,
                 p.user_pk_path,
                 p.user_cert_path,
                 p.user,
                 p.pass,
                 p.location,
                 p.kernel_id,
                 p.ramdisk_id,
                 p.acl,
                 p.retry,
                 p.use_mapping,
                 p.region)
  
  $stdout.puts("\nYour new bundle is in S3 at the following location:")
  $stdout.puts("#{p.dest_bucket}/#{p.dest_keyprefix}#{p.manifest_name}")
  $stdout.puts("Please register it using your favorite EC2 client.")
end

#make_s3_connection(s3_url, user, pass, bucket) ⇒ Object

——————————————————————————#



76
77
78
79
80
81
# File 'lib/ec2/amitools/migratebundle.rb', line 76

def make_s3_connection(s3_url, user, pass, bucket)
  s3_uri = URI.parse(s3_url)
  s3_url = uri2string(s3_uri)
  v2_bucket = EC2::Common::S3Support::bucket_name_s3_v2_safe?(bucket)
  EC2::Common::S3Support.new(s3_url, user, pass, (v2_bucket ? nil : :path))
end

#migrate_bundle(s3_url, bucket, keyprefix, dest_bucket, dest_keyprefix, manifest_name, user_pk_path, user_cert_path, user, pass, location, kernel_id = nil, ramdisk_id = nil, acl = 'aws-exec-read', retry_stuff = nil, use_mapping = true, region = nil) ⇒ Object

——————————————————————————#



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/ec2/amitools/migratebundle.rb', line 123

def migrate_bundle(s3_url,
                   bucket,
                   keyprefix,
                   dest_bucket,
                   dest_keyprefix,
                   manifest_name,
                   user_pk_path,
                   user_cert_path,
                   user,
                   pass,
                   location,
                   kernel_id=nil,
                   ramdisk_id=nil,
                   acl='aws-exec-read',
                   retry_stuff=nil,
                   use_mapping=true,
                   region=nil)

  src_s3_conn = make_s3_connection(s3_url, user, pass, bucket)
  dest_s3_conn = make_s3_connection(s3_url, user, pass, dest_bucket)
  
  # Locate destination bucket and create it if necessary.
  bu = BundleUploader.new()
  bu.check_bucket_name(dest_bucket)
  bucket_location = bu.get_bucket_location(dest_s3_conn, dest_bucket)
  bu.create_bucket(dest_s3_conn, dest_bucket, bucket_location, location, retry_stuff)
  
  # Region/location hack:
  if region.nil?
    location ||= bucket_location
    region = AwsRegion.guess_region_from_s3_bucket(location)
    puts "Region not provided, guessing from S3 location: #{region}"
  end
  
  with_temp_dir(manifest_name) do |tempdir|
    manifest_path = File::join(tempdir, "temp-migration.manifest.xml")
    download_manifest(src_s3_conn, bucket, keyprefix+manifest_name, manifest_path, user_pk_path, retry_stuff)
    
    ManifestMigrator.new().migrate_manifest(manifest_path,
                                            user_pk_path,
                                            user_cert_path,
                                            user,
                                            pass,
                                            use_mapping,
                                            kernel_id,
                                            ramdisk_id,
                                            region,
                                            true)
    
    get_part_filenames(manifest_path, user_cert_path).each do |part|
      $stdout.puts("Copying '#{part}'...")
      copy_part(dest_s3_conn, bucket, keyprefix, dest_bucket, dest_keyprefix, part, acl, retry_stuff)
    end
    upload_manifest(dest_s3_conn, dest_keyprefix+manifest_name, manifest_path, dest_bucket, tempdir, acl, retry_stuff)
  end
end

#upload_manifest(s3_conn, key, manifest_path, bucket, tempdir, acl, retry_stuff) ⇒ Object

——————————————————————————#



117
118
119
# File 'lib/ec2/amitools/migratebundle.rb', line 117

def upload_manifest(s3_conn, key, manifest_path, bucket, tempdir, acl, retry_stuff)
  BundleUploader.new().upload(s3_conn, bucket, key, manifest_path, acl, retry_stuff)
end

#uri2string(uri) ⇒ Object

——————————————————————————#



68
69
70
71
72
# File 'lib/ec2/amitools/migratebundle.rb', line 68

def uri2string(uri)
  s = "#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}"
  # Remove the trailing '/'.
  return (s[-1..-1] == "/" ? s[0..-2] : s)
end

#with_temp_dir(manifest_name) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ec2/amitools/migratebundle.rb', line 45

def with_temp_dir(manifest_name)
  # Set up temporary dir
  tempdir = File::join(Dir::tmpdir, "ami-migration-#{manifest_name}")
  if File::exists?(tempdir)
    raise EC2FatalError.new(2, "Temporary directory '#{tempdir}' already exists. Please delete or rename it and try again.")
  end
  Dir::mkdir(tempdir)

  # Let the caller use it
  begin
    result = yield tempdir
  rescue Exception => e
    # Nuke it
    FileUtils::rm_rf(tempdir)
    raise e
  end
  # Nuke it
  FileUtils::rm_rf(tempdir)
  result
end