Class: Bosh::AwsCloud::StemcellCreator

Inherits:
Object
  • Object
show all
Includes:
Helpers, Exec
Defined in:
lib/cloud/aws/stemcell_creator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#cloud_error, #default_ephemeral_disk_mapping, #ebs_ephemeral_disk_mapping, #extract_security_groups

Constructor Details

#initialize(region, stemcell_properties) ⇒ StemcellCreator

Returns a new instance of StemcellCreator.



9
10
11
12
# File 'lib/cloud/aws/stemcell_creator.rb', line 9

def initialize(region, stemcell_properties)
  @region = region
  @stemcell_properties = stemcell_properties
end

Instance Attribute Details

#ebs_volumeObject (readonly)

Returns the value of attribute ebs_volume.



7
8
9
# File 'lib/cloud/aws/stemcell_creator.rb', line 7

def ebs_volume
  @ebs_volume
end

#image_pathObject (readonly)

Returns the value of attribute image_path.



7
8
9
# File 'lib/cloud/aws/stemcell_creator.rb', line 7

def image_path
  @image_path
end

#regionObject (readonly)

Returns the value of attribute region.



6
7
8
# File 'lib/cloud/aws/stemcell_creator.rb', line 6

def region
  @region
end

#stemcell_propertiesObject (readonly)

Returns the value of attribute stemcell_properties.



6
7
8
# File 'lib/cloud/aws/stemcell_creator.rb', line 6

def stemcell_properties
  @stemcell_properties
end

#volumeObject (readonly)

Returns the value of attribute volume.



7
8
9
# File 'lib/cloud/aws/stemcell_creator.rb', line 7

def volume
  @volume
end

Instance Method Details

#copy_root_imageObject

This method tries to execute the helper script stemcell-copy as root using sudo, since it needs to write to the ebs_volume. If stemcell-copy isn’t available, it falls back to writing directly to the device, which is used in the micro bosh deployer. The stemcell-copy script must be in the PATH of the user running the director, and needs sudo privileges to execute without password.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/cloud/aws/stemcell_creator.rb', line 53

def copy_root_image
  stemcell_copy = find_in_path("stemcell-copy")

  if stemcell_copy
    logger.debug("copying stemcell using stemcell-copy script")
    # note that is is a potentially dangerous operation, but as the
    # stemcell-copy script sets PATH to a sane value this is safe
    command = "sudo -n #{stemcell_copy} #{image_path} #{ebs_volume} 2>&1"
  else
    logger.info("falling back to using included copy stemcell")
    included_stemcell_copy = File.expand_path("../../../../scripts/stemcell-copy.sh", __FILE__)
    command = "sudo -n #{included_stemcell_copy} #{image_path} #{ebs_volume} 2>&1"
  end

  result = sh(command)

  logger.debug("stemcell copy output:\n#{result.output}")
rescue Bosh::Exec::Error => e
  raise Bosh::Clouds::CloudError, "Unable to copy stemcell root image: #{e.message}\nScript output:\n#{e.output}"
end

#create(volume, ebs_volume, image_path) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/cloud/aws/stemcell_creator.rb', line 14

def create(volume, ebs_volume, image_path)
  @volume = volume
  @ebs_volume = ebs_volume
  @image_path = image_path

  copy_root_image

  snapshot = volume.create_snapshot
  ResourceWait.for_snapshot(snapshot: snapshot, state: :completed)

  params = image_params(snapshot.id)
  image = region.images[region.client.register_image(params).image_id]
  ResourceWait.for_image(image: image, state: :available)

  TagManager.tag(image, 'Name', params[:description]) if params[:description]

  Stemcell.new(region, image)
end

#fakeObject

Raises:

  • (Bosh::Clouds::CloudError)


37
38
39
40
41
42
43
# File 'lib/cloud/aws/stemcell_creator.rb', line 37

def fake
  id = stemcell_properties['ami'][region.name]

  raise Bosh::Clouds::CloudError, "Stemcell does not contain an AMI for this region (#{region.name})" unless id

  StemcellFinder.find_by_region_and_id(region, "#{id} light")
end

#fake?Boolean

Returns:

  • (Boolean)


33
34
35
# File 'lib/cloud/aws/stemcell_creator.rb', line 33

def fake?
  stemcell_properties.has_key?('ami')
end

#find_in_path(command, path = ENV["PATH"]) ⇒ Object

checks if the stemcell-copy script can be found in the current PATH



76
77
78
79
80
81
82
# File 'lib/cloud/aws/stemcell_creator.rb', line 76

def find_in_path(command, path=ENV["PATH"])
  path.split(":").each do |dir|
    stemcell_copy = File.join(dir, command)
    return stemcell_copy if File.exist?(stemcell_copy)
  end
  nil
end

#image_params(snapshot_id) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/cloud/aws/stemcell_creator.rb', line 84

def image_params(snapshot_id)
  architecture = stemcell_properties["architecture"]
  virtualization_type = stemcell_properties["virtualization_type"]

  params = if virtualization_type == 'hvm'
             {
               :virtualization_type => virtualization_type,
               :root_device_name => "/dev/xvda",
               :sriov_net_support => "simple",
               :block_device_mappings => [
                 {
                   :device_name => "/dev/xvda",
                   :ebs => {
                     :snapshot_id => snapshot_id,
                   },
                 },
               ],
             }
           else
             root_device_name = stemcell_properties["root_device_name"]
             aki = AKIPicker.new(region).pick(architecture, root_device_name)

             {
               :kernel_id => aki,
               :root_device_name => root_device_name,
               :block_device_mappings => [
                 {
                   :device_name => "/dev/sda",
                   :ebs => {
                     :snapshot_id => snapshot_id,
                   },
                 },
               ],
             }
           end

  # old stemcells doesn't have name & version
  if stemcell_properties["name"] && stemcell_properties["version"]
    name = "#{stemcell_properties['name']} #{stemcell_properties['version']}"
    params[:description] = name
  end

  params.merge!(
    :name => "BOSH-#{SecureRandom.uuid}",
    :architecture => architecture,
  )

  params[:block_device_mappings].push(*default_ephemeral_disk_mapping)

  params
end

#loggerObject



136
137
138
# File 'lib/cloud/aws/stemcell_creator.rb', line 136

def logger
  Bosh::Clouds::Config.logger
end