Class: Builderator::Interface::Packer

Inherits:
Builderator::Interface show all
Defined in:
lib/builderator/interface/packer.rb

Overview

Generate packer.json

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Builderator::Interface

berkshelf, #bundled?, #clean, command, #directory, from_gem, packer, #source, template, vagrant, #which, #write

Constructor Details

#initialize(*_) ⇒ Packer

Returns a new instance of Packer.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
# File 'lib/builderator/interface/packer.rb', line 20

def initialize(*_)
  super

  docker_builders = Config.profile.current.packer.build.select do |_, builder|
    builder.to_h[:type] == 'docker'
  end

  @packerfile ||= {
    :builders => [],
    :provisioners => [],
    'post-processors' => []
  }.tap do |json|
    Config.profile.current.packer.build.each do |_, build|
      build_hash = build.to_hash.tap do |b|
        b[:tags] = Config.profile.current.tags unless Config.profile.current.tags.empty?
      end

      if build_hash[:type] == 'docker'
        raise 'The Docker builder requires a base image' unless build_hash.key?(:image)

        # The Docker builder requires one and only one of 'commit', 'discard', or 'export_path' set
        if build_hash.keys.select { |k| [:commit, :discard, :export_path].include?(k) }.length != 1
          raise 'The Docker builder requires one and only one of `commit`, `discard`, or `export_path` attributes to be defined'
        end
      end

      # If we specify encrypted boot, packer won't allow ami_users.
      # See: https://github.com/MYOB-Technology/packer/blob/509cd7dcf194beb6ca6d0c39057f7490fa630d78/builder/amazon/common/ami_config.go#L59-L61

      # A PR (https://github.com/mitchellh/packer/pull/4023) has been
      # submitted to resolve this issue but we shouldn't remove this
      # until a new Packer release with this feature.
      if build_hash.key?(:encrypt_boot)
        build_hash.delete(:ami_users)
      end

      ## Support is missing for several regions in some versions of Packer
      # Moving this functionality into a task until we can confirm that Packer
      # has full support again.
      build_hash.delete(:ami_regions)

      # This is not directly supported by Packer
      build_hash.delete(:tagging_role)

      # Use a security group that doesn't suck if user didn't specify.
      # Note that @security_group_id in this class will only ever be the one created here,
      # and will be nil if the user specified their own
      if build_hash.key?(:security_group_ids)
        puts "Using SecurityGroups #{build_hash[:security_group_ids]}"
      elsif build_hash.key?(:security_group_id)
        puts "Using SecurityGroup #{build_hash[:security_group_id]}"
      else
        @security_group_id = Util.get_security_group_id(build_hash[:region])
        build_hash[:security_group_id] = @security_group_id

        # Delete the security group created above when on builderator exit.
        # Note that for an unclean exit in which the instance was NOT terminated,
        # Amazon will refuse to delete the security group, as it is still attached
        # to an existing instance.  This is unfortunate, but is equivalent to packer's
        # default behavior except that now you'll get an exception from aws-sdk.
        at_exit { Util.remove_security_group(build_hash[:region], @security_group_id) }
      end

      json[:builders] << build_hash
    end

    # post_processors must be a List of Rashes.
    post_processors = Config.profile.current.packer.post_processors.to_a
    json['post-processors'] = post_processors.first unless post_processors.empty?
    json.delete('post-processors') if json['post-processors'].compact.empty?

    ## Initialize the staging directory unless using the docker builder
    json[:provisioners] << {
      :type => 'shell',
      :inline => "sudo mkdir -p #{Config.chef.staging_directory}/cache && "\
                 "sudo chown $(whoami) -R #{Config.chef.staging_directory}"
    } if docker_builders.empty?

    # Only add artifact provisioners if they're defined
    Config.profile.current.artifact.each do |_, artifact|
      json[:provisioners] << _artifact_provisioner(artifact)
    end unless Config.profile.current.artifact.attributes.empty?

    # Only add chef provisioners if they're defined
    unless Config.profile.current.chef.attributes.empty?
      # There are certain options (staging directory, run as sudo) that don't apply
      # to the docker builder.
      json[:provisioners] << if docker_builders.empty?
                               _chef_provisioner
                             else
                               _chef_provisioner_docker
                             end
    end

    # After adding the default provisioners, we add any additional ones to the provisioners array
    Config.profile.current.provisioner.each do |name, provisioner|
      json[:provisioners] << provisioner.attributes.tap { |p| p[:type] = name.to_s }
    end

    json.delete(:provisioners) if json[:provisioners].empty?
  end
end

Instance Attribute Details

#packerfileObject (readonly)

Returns the value of attribute packerfile.



17
18
19
# File 'lib/builderator/interface/packer.rb', line 17

def packerfile
  @packerfile
end

#security_group_idObject (readonly)

Returns the value of attribute security_group_id.



18
19
20
# File 'lib/builderator/interface/packer.rb', line 18

def security_group_id
  @security_group_id
end

Instance Method Details

#renderObject



123
124
125
# File 'lib/builderator/interface/packer.rb', line 123

def render
  JSON.pretty_generate(packerfile)
end