Class: EY::Enzyme::CookbookSet

Inherits:
Object
  • Object
show all
Defined in:
lib/ey_enzyme/cookbook_set.rb

Instance Method Summary collapse

Constructor Details

#initialize(opts, name, recipes_path, recipes_url, api) ⇒ CookbookSet

Returns a new instance of CookbookSet.



3
4
5
6
7
8
9
10
11
12
# File 'lib/ey_enzyme/cookbook_set.rb', line 3

def initialize(opts, name, recipes_path, recipes_url, api)
  @opts           = opts
  @name           = name
  @recipes_path   = recipes_path
  @logger         = MultiLogger.new(opts[:logfile])
  @timestamp      = Time.now.strftime("%Y-%m-%dT%H-%M-%S")
  @chef_log       = "/var/log/chef.#{name}.#{@timestamp}.log"
  @recipes_url    = recipes_url
  @api            = api
end

Instance Method Details

#chef_configObject



89
90
91
# File 'lib/ey_enzyme/cookbook_set.rb', line 89

def chef_config
  main? ? "/etc/chef/solo.rb" : "/etc/chef-custom/solo.rb"
end

#chef_dnaObject



93
94
95
# File 'lib/ey_enzyme/cookbook_set.rb', line 93

def chef_dna
  main? ? '/etc/chef/dna.json' : '/etc/chef-custom/dna.json'
end

#chef_error_from_logObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ey_enzyme/cookbook_set.rb', line 97

def chef_error_from_log
  unless File.exist?(@chef_log)
    return "(log doesn't exist)"
  end

  error = ""
  saw_error = false

  File.open(@chef_log) do |f|
    while line = f.gets
      if line =~ / ERROR: /
        saw_error = true
      end

      if saw_error
        error << line
      end
    end
  end

  error
end

#executeObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ey_enzyme/cookbook_set.rb', line 51

def execute
  command = "#{@opts[:chef_bin]} -j #{chef_dna} -c #{chef_config} -r \"#{@recipes_url}\" > #{@chef_log} 2>&1"
  @logger.debug "Running: #{command}"
  if system(command)
    @logger.info "Running telinit"
    system("telinit q")
    @logger.info "Finished #{@name} chef run"
  else
    @logger.error("#{@name} chef run failed. Reporting error")
    @logger.error("#{@name} error output: #{chef_error_from_log}")
    raise DeployError, "#{@name} chef run failed"
  end
ensure
  if File.exists?(@chef_log)
    FileUtils.ln_sf(@chef_log, "/var/log/chef.#{@name}.log")
  end
end

#instance_id_valid?Boolean

Returns:

  • (Boolean)


120
121
122
# File 'lib/ey_enzyme/cookbook_set.rb', line 120

def instance_id_valid?
  local_instance_id == @opts[:instance_id]
end

#local_instance_idObject



124
125
126
# File 'lib/ey_enzyme/cookbook_set.rb', line 124

def local_instance_id
  @local_instance_id ||= open('http://169.254.169.254/latest/meta-data/instance-id').read
end

#main?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/ey_enzyme/cookbook_set.rb', line 85

def main?
  @name == "main"
end

#runObject



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/ey_enzyme/cookbook_set.rb', line 14

def run
  unless @recipes_url
    @logger.info "No recipes for #{@name} chef run. Skipping"
    return
  end

  setup
  execute
ensure
  upload
end

#setupObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/ey_enzyme/cookbook_set.rb', line 26

def setup
  @logger.info "Starting #{@name} chef run"

  abort("Instance ID mismatch") unless instance_id_valid?
  FileUtils.rm(@chef_log) if File.exist?(@chef_log)

  FileUtils.mkdir_p('/etc/chef-custom/') unless File.exists?('/etc/chef-custom/')

  File.open(chef_config, "w") do |f|
    f.puts <<-EOS
      cookbook_path     "#{@recipes_path}/cookbooks"
      file_store_path   "#{@recipes_path}/"
      file_cache_path   "#{@recipes_path}/"
      log_location      "#{@chef_log}"
      log_level         :info
      node_name         "#{@opts[:instance_id]}"
    EOS
  end

  @logger.info "Removing #{@name} cookbooks"

  FileUtils.rm_rf(@recipes_path)
  FileUtils.mkdir_p(@recipes_path)
end

#uploadObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ey_enzyme/cookbook_set.rb', line 69

def upload
  return unless File.exist?(@chef_log)

  file = "#{@chef_log}.#{rand(1000)}.gz"
  Zlib::GzipWriter.open(file) { |io| io << File.read(@chef_log) }

  unless @api.upload(@name, File.read(file))
    @logger.error "Failed to upload #{@name} log. Reporting error"
    raise UploadError, "failed to upload #{@name} log"
  end
rescue UploadError => error
  @api.notify_error("logupload", error)
ensure
  FileUtils.rm_f(file) if file
end