Class: CloudFormationTool::CloudInit

Inherits:
Object
  • Object
show all
Includes:
Storable
Defined in:
lib/cloud_formation_tool/cloud_init.rb

Constant Summary

Constants included from CloudFormationTool

VERSION

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Storable

#make_filename, #upload

Methods included from CloudFormationTool

#aws_config, #awsas, #awscf, #awscreds, #awsec2, #awss3, #cf_bucket_name, #find_profile, #profile, #region, #s3_bucket_name

Constructor Details

#initialize(path) ⇒ CloudInit

Returns a new instance of CloudInit.



11
12
13
14
15
16
17
18
19
# File 'lib/cloud_formation_tool/cloud_init.rb', line 11

def initialize(path)
  @path = path
  log "Loading #{path}"
  begin
    @initfile = YAML.load(File.read(path)).to_h
  rescue Errno::ENOENT => e
    raise CloudFormationTool::Errors::AppError.new("Error reading #{@path}: " + e.message)
  end
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



9
10
11
# File 'lib/cloud_formation_tool/cloud_init.rb', line 9

def path
  @path
end

Instance Method Details

#compileObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/cloud_formation_tool/cloud_init.rb', line 21

def compile
  basepath = File.dirname(path)
  basepath = "." if basepath.empty?
  @initfile['write_files'] = (@initfile['write_files'] || []).collect do |file|
    if file['file']
      begin
        read_file_content(basepath + "/" + file.delete('file'), file)
      rescue Errno::EISDIR => e
        raise CloudFormationTool::Errors::AppError, "#{path} - error loading embedded file for #{file['path']}: " + e.message
      rescue Errno::ENOENT => e
        raise CloudFormationTool::Errors::AppError, "#{path} - error loading embedded file for #{file['path']}: " + e.message
      end
    else
      file
    end
  end
  @initfile['write_files'] += (@initfile.delete('write_directories') || []).collect do |directory|
    realdir = "#{basepath}/#{directory['source']}"
    raise CloudFormationTool::Errors::AppError.new("Cloud-init file #{path} references missing directory #{realdir}") unless File.exist? realdir
    read_dir_files(realdir, directory['target'])
  end.flatten
  "#cloud-config\n" + @initfile.to_yaml
end

#encode(allow_gzip = true) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/cloud_formation_tool/cloud_init.rb', line 45

def encode(allow_gzip = true)
  yamlout = compile
  usegzip = false
  if allow_gzip and yamlout.size > 16384 # max AWS EC2 user data size - try compressing it
    yamlout = Zlib::Deflate.new(nil, 31).deflate(yamlout, Zlib::FINISH) # 31 is the magic word to have deflate create a gzip compatible header
    usegzip = true
  end
  if yamlout.size > 16384 # still to big, we should upload to S3 and create an include file
    url = upload  make_filename('init'),
                  yamlout, mime_type: 'text/cloud-config', gzip: usegzip
    log "Wrote cloud config to #{url}"
    [ "#include", url ].join "\n"  
  else
    yamlout
  end
end

#read_dir_files(source, target) ⇒ Object



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

def read_dir_files(source, target)
  Dir.entries(source).select do |entry|
    entry !~ /^\.{1,2}$/
  end.collect do |entry|
    path = source + "/" + entry
    targetpath = target + "/" + entry
    if File.directory? path
      read_dir_files(path, targetpath)
    else
      [ read_file_content(path, {
        'path' => targetpath,
        'permissions' => (("%o" % File.stat(path).mode)[-4..-1])
      }) ]
    end
  end.flatten
end

#read_file_content(filepath, spec) ⇒ Object



62
63
64
65
66
# File 'lib/cloud_formation_tool/cloud_init.rb', line 62

def read_file_content(filepath, spec)
  spec['encoding'] = 'base64'
  spec['content'] = Base64.strict_encode64(File.read(filepath))
  spec
end

#to_base64Object



85
86
87
# File 'lib/cloud_formation_tool/cloud_init.rb', line 85

def to_base64
  Base64.encode64(encode)
end