Class: Dapp::Dimg::Builder::Chef

Inherits:
Base
  • Object
show all
Defined in:
lib/dapp/dimg/builder/chef.rb

Defined Under Namespace

Classes: Berksfile, Cookbook, CookbookMetadata

Constant Summary collapse

CHEFDK_VERSION =
"2.3.17-2"

Instance Attribute Summary

Attributes inherited from Base

#dimg

Instance Method Summary collapse

Methods inherited from Base

#before_install, #before_install?, #before_install_checksum, #before_setup, #before_setup?, #before_setup_checksum, #build_artifact, #build_artifact?, #build_artifact_checksum, #initialize, #install, #install?, #install_checksum, #setup, #setup?, #setup_checksum

Constructor Details

This class inherits a constructor from Dapp::Dimg::Builder::Base

Instance Method Details

#before_build_checkObject



46
47
48
49
50
51
52
53
# File 'lib/dapp/dimg/builder/chef.rb', line 46

def before_build_check
  %i(before_install install before_setup setup build_artifact).tap do |stages|
    (builder_cookbook.enabled_recipes -
     stages.map {|stage| builder_cookbook.stage_enabled_recipes(stage)}.flatten.uniq).each do |recipe|
      dimg.dapp.log_warning(desc: {code: :recipe_does_not_used, data: {recipe: recipe}})
    end
  end
end

#before_dimg_should_be_built_checkObject



36
37
38
39
40
41
42
43
44
# File 'lib/dapp/dimg/builder/chef.rb', line 36

def before_dimg_should_be_built_check
  super

  %i(before_install install before_setup setup).each do |stage|
    unless stage_empty?(stage) || stage_cookbooks_checksum_path(stage).exist?
      raise Error::Chef, code: :stage_checksum_not_calculated, data: {stage: stage}
    end
  end
end

#berks_binObject



10
11
12
# File 'lib/dapp/dimg/builder/chef.rb', line 10

def berks_bin
  "/.dapp/deps/chefdk/#{CHEFDK_VERSION}/bin/berks"
end

#builder_cookbookObject



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
# File 'lib/dapp/dimg/builder/chef.rb', line 83

def builder_cookbook
  @builder_cookbook ||= begin
    unless dimg.dapp.builder_cookbook_path.exist?
      raise Error::Chef,
            code: :builder_cookbook_not_found,
            data: {path: dimg.dapp.builder_cookbook_path.to_s}
    end

    cookbooks = Marshal.load Marshal.dump(dimg.config._chef._cookbook)

    cookbooks.each do |_name, desc|
      # Получение относительного пути из директории .dapp_chef до указанной зависимости.
      # В Dappfile указываются пути относительно самого Dappfile либо абсолютные пути.
      # В объекте конфига должны лежать абсолютные пути по ключу :path.
      if desc[:path]
        relative_from_cookbook_path = Pathname.new(desc[:path]).relative_path_from(dimg.dapp.builder_cookbook_path).to_s
        desc[:path] = relative_from_cookbook_path
      end
    end

    # Добавление самого cookbook'а builder'а.
    cookbooks[dimg.dapp.name] = {
      name: dimg.dapp.name,
      path: '.'
    }

    berksfile = Berksfile.from_conf(cookbook_path: dimg.dapp.builder_cookbook_path.to_s, cookbooks: cookbooks)
     = CookbookMetadata.from_conf(name: dimg.dapp.name, version: '1.0.0', cookbooks: cookbooks)

    Cookbook.new(self,
                 path: dimg.dapp.builder_cookbook_path,
                 berksfile: berksfile,
                 metadata: ,
                 enabled_recipes: dimg.config._chef._recipe,
                 enabled_modules: dimg.config._chef._dimod)
  end
end

#chef_solo_binObject



6
7
8
# File 'lib/dapp/dimg/builder/chef.rb', line 6

def chef_solo_bin
  "/.dapp/deps/chefdk/#{CHEFDK_VERSION}/bin/chef-solo"
end

#chefdk_containerObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/dapp/dimg/builder/chef.rb', line 63

def chefdk_container
  @chefdk_container ||= begin
    is_container_exist = proc{dimg.dapp.shellout("#{dimg.dapp.host_docker} inspect #{chefdk_container_name}").exitstatus.zero?}
    if !is_container_exist.call
      dimg.dapp.lock("dappdeps.container.#{chefdk_container_name}", default_timeout: 600) do
        if !is_container_exist.call
          dimg.dapp.log_secondary_process(dimg.dapp.t(code: 'process.chefdk_container_creating', data: {name: chefdk_container_name}), short: true) do
            dimg.dapp.shellout!(
              ["#{dimg.dapp.host_docker} create",
              "--name #{chefdk_container_name}",
              "--volume /.dapp/deps/chefdk/#{CHEFDK_VERSION} #{chefdk_image}"].join(' ')
            )
          end
        end
      end
    end
    chefdk_container_name
  end
end

#chefdk_container_nameObject

FIXME: hashsum(image) or dockersafe()



59
60
61
# File 'lib/dapp/dimg/builder/chef.rb', line 59

def chefdk_container_name # FIXME: hashsum(image) or dockersafe()
  "dappdeps_chefdk_#{CHEFDK_VERSION}"
end

#chefdk_imageObject



55
56
57
# File 'lib/dapp/dimg/builder/chef.rb', line 55

def chefdk_image
  "dappdeps/chefdk:#{CHEFDK_VERSION}" # TODO: config, DSL, DEFAULT_CHEFDK_IMAGE
end

#container_stage_build_path(_stage) ⇒ Object



222
223
224
# File 'lib/dapp/dimg/builder/chef.rb', line 222

def container_stage_build_path(_stage)
  Pathname.new('/.dapp/chef/build')
end

#container_stage_config_path(stage) ⇒ Object



201
202
203
204
# File 'lib/dapp/dimg/builder/chef.rb', line 201

def container_stage_config_path(stage)
  install_chef_solo_stage_config(stage)
  container_stage_build_path(stage).join('config.rb')
end

#container_stage_json_attributes_path(stage) ⇒ Object



213
214
215
216
# File 'lib/dapp/dimg/builder/chef.rb', line 213

def container_stage_json_attributes_path(stage)
  install_json_attributes(stage)
  container_stage_build_path(stage).join('attributes.json')
end

#install_chef_solo_stage_config(stage) ⇒ Object



190
191
192
193
194
195
196
197
198
199
# File 'lib/dapp/dimg/builder/chef.rb', line 190

def install_chef_solo_stage_config(stage)
  @install_chef_solo_stage_config ||= {}
  @install_chef_solo_stage_config[stage] ||= true.tap do
    stage_build_path(stage).join('config.rb').write [
      "file_cache_path \"/.dapp/chef/cache\"\n",
      "cookbook_path \"#{container_stage_build_path(stage).join('cookbooks')}\"\n",
      ("log_level :debug\n" if ENV["DAPP_CHEF_DEBUG"]),
    ].compact.join
  end
end

#install_json_attributes(stage) ⇒ Object



206
207
208
209
210
211
# File 'lib/dapp/dimg/builder/chef.rb', line 206

def install_json_attributes(stage)
  @install_json_attributes ||= {}
  @install_json_attributes[stage] ||= true.tap do
    stage_build_path(stage).join('attributes.json').write "#{stage_attributes_raw(stage)}\n"
  end
end

#stage_attributes(stage) ⇒ Object



121
122
123
# File 'lib/dapp/dimg/builder/chef.rb', line 121

def stage_attributes(stage)
  dimg.config._chef.send("__#{stage}_attributes")
end

#stage_attributes_raw(stage) ⇒ Object



125
126
127
# File 'lib/dapp/dimg/builder/chef.rb', line 125

def stage_attributes_raw(stage)
  JSON.dump stage_attributes(stage)
end

#stage_build_path(stage) ⇒ Object



218
219
220
# File 'lib/dapp/dimg/builder/chef.rb', line 218

def stage_build_path(stage)
  dimg.tmp_path(dimg.name).join(stage.to_s)
end

#stage_cookbooks_checksum(stage) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/dapp/dimg/builder/chef.rb', line 133

def stage_cookbooks_checksum(stage)
  if stage_cookbooks_checksum_path(stage).exist?
    stage_cookbooks_checksum_path(stage).read.strip
  else
    checksum = builder_cookbook.stage_checksum(stage)

    stage_cookbooks_checksum_path(stage).tap do |path|
      path.parent.mkpath
      path.write "#{checksum}\n"
    end

    checksum
  end
end

#stage_cookbooks_checksum_path(stage) ⇒ Object



129
130
131
# File 'lib/dapp/dimg/builder/chef.rb', line 129

def stage_cookbooks_checksum_path(stage)
  dimg.build_path.join("#{builder_cookbook.checksum}.#{dimg.name}.#{stage}.checksum")
end

#stage_cookbooks_runlist(stage) ⇒ Object

rubocop:disable Metrics/PerceivedComplexity



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
179
180
181
182
183
# File 'lib/dapp/dimg/builder/chef.rb', line 149

def stage_cookbooks_runlist(stage)
  @stage_cookbooks_runlist ||= {}
  @stage_cookbooks_runlist[stage] ||= begin
    res = []

    format_entry = proc do |cookbook, entrypoint|
      entrypoint = 'void' if entrypoint.nil?
      "#{cookbook}::#{entrypoint}"
    end

    builder_cookbook.enabled_modules.map do |cookbook|
      if builder_cookbook.stage_enabled_modules(stage).include? cookbook
        [cookbook, stage]
      else
        [cookbook, nil]
      end
    end.tap {|entries| res.concat entries}

    builder_cookbook.stage_enabled_recipes(stage)
                    .map {|recipe| [builder_cookbook.name, recipe]}
                    .tap do |entries|
      if entries.any?
        res.concat entries
      else
        res << [builder_cookbook.name, nil]
      end
    end

    if res.all? {|_, entrypoint| entrypoint.nil?}
      []
    else
      res.map(&format_entry)
    end
  end
end

#stage_empty?(stage) ⇒ Boolean

rubocop:enable Metrics/PerceivedComplexity

Returns:

  • (Boolean)


186
187
188
# File 'lib/dapp/dimg/builder/chef.rb', line 186

def stage_empty?(stage)
  stage_cookbooks_runlist(stage).empty?
end