class Chef::TarFile

Constants

API_CLIENTS_PATH
CHEF_FILE_EXTENSIONS

A list of valid chef file extensions

COOKBOOKS_PATH

The named conventions for chef components

DATA_BAGS_PATH
ENVIRONMENTS_PATH
NODES_PATH
ROLES_PATH
WEB_USERS_PATH

Public Class Methods

new(tarPath, create=false) click to toggle source
# File lib/chef/tar_file.rb, line 23
def initialize tarPath, create=false
  
  if tarPath==nil
    raise ArgumentError, "A tar file path must be given"
  end
  
  @create_tar = create
  
  unless create
    @temp_directory = TmpDirectory.new.path
    
    #Assume for now that the components live directly inside the tar file
    @tar_contents_path = @temp_directory
    
    localTarFile = File.join(@temp_directory, 'cookbooks.tgz')
  
    #Move/Download tar file to tmp directory
    File.open(localTarFile, 'wb') do |f|
      open(tarPath) do |r|
        f.write(r.read)
      end
    end
  
    #Untar file
    Chef::Mixin::Command.run_command(:command => "tar zxfC #{localTarFile} #{@temp_directory}")
    
    #Verify tar file structure and update tar_contents_path if necessary
    
    dirList = get_directories_names @tar_contents_path
    
    if !is_tar_valid? dirList
      #The tar does not contain any immediate chef component directories, check to see if there is a top-level project folder
      #that contains any chef component directories
      
      if dirList.size!=1 or !is_tar_valid? get_directories_names(File.join(@tar_contents_path, dirList.first))
        raise InvalidStructureError, "The tar file has an invalid structure"
      end
      
      #The tar file is valid but contains a top-level project folder so update the @tar_contents_path
      @tar_contents_path = File.join(@tar_contents_path, dirList.first)
    end
    
    #Remove tar file
    FileUtils.rm_f localTarFile
    
  else
    
    # Verify that the tarPath doesn't already exist
    if File.exists? tarPath
      raise ArgumentError, "We cannot create a tar file at path : #{tarPath} because it already exists"
    end
    
    @temp_directory = TmpDirectory.new("chef-server").path
    
    #We will create the tar file such that their is no single root directory inside the tar file
    @tar_contents_path = @temp_directory
    
    FileUtils.mkdir_p @temp_directory
    
    @create_tar_path = File.absolute_path tarPath
    
    # We are setting up a directory to become a Chef TarFile so create the resource directories
    FileUtils.mkdir_p File.join @tar_contents_path, COOKBOOKS_PATH
    FileUtils.mkdir_p File.join @tar_contents_path, ROLES_PATH
    FileUtils.mkdir_p File.join @tar_contents_path, ENVIRONMENTS_PATH
    FileUtils.mkdir_p File.join @tar_contents_path, DATA_BAGS_PATH
    FileUtils.mkdir_p File.join @tar_contents_path, API_CLIENTS_PATH
    FileUtils.mkdir_p File.join @tar_contents_path, WEB_USERS_PATH
    FileUtils.mkdir_p File.join @tar_contents_path, NODES_PATH
    
  end
  
end

Public Instance Methods

api_clients() click to toggle source

Returns a list of absolute paths to the api_clients json files

# File lib/chef/tar_file.rb, line 163
def api_clients
  get_chef_files_absolute_paths api_clients_path
end
api_clients_path() click to toggle source

Returns the absolute path to the api_clients directory

# File lib/chef/tar_file.rb, line 157
def api_clients_path
  verify_path API_CLIENTS_PATH
  File.join @tar_contents_path, API_CLIENTS_PATH
end
cookbooks() click to toggle source

Returns list of absolute paths of the cookbooks

# File lib/chef/tar_file.rb, line 104
def cookbooks
  get_directories_absolute_paths cookbooks_path
end
cookbooks_path() click to toggle source

Returns the absolute path to the cookbooks directory

# File lib/chef/tar_file.rb, line 98
def cookbooks_path
  verify_path COOKBOOKS_PATH
  File.join @tar_contents_path, COOKBOOKS_PATH
end
data_bags() click to toggle source

Returns a list of absolute paths to the data_bags json files

# File lib/chef/tar_file.rb, line 137
def data_bags
  
  #Data bags follow a different structure then the other components, their structure is
  #|- data_bags
  #\ \- data_bag_1
  #| | |- values_1.json
  #| ...
  
  dir_list = get_directories_absolute_paths(data_bags_path)
  
  data_bags_absolute_paths = Array.new
  
  dir_list.each do |dir_path|
    data_bags_absolute_paths = data_bags_absolute_paths | get_chef_files_absolute_paths(dir_path)
  end
  
  data_bags_absolute_paths
end
data_bags_path() click to toggle source

Returns the absolute path to the data_bags directory

# File lib/chef/tar_file.rb, line 131
def data_bags_path
  verify_path DATA_BAGS_PATH
  File.join @tar_contents_path, DATA_BAGS_PATH
end
environments() click to toggle source

Returns a list of absolute paths to the environemnts json files

# File lib/chef/tar_file.rb, line 126
def environments
  get_chef_files_absolute_paths environments_path
end
environments_path() click to toggle source

Returns the absolute path to the environments directory

# File lib/chef/tar_file.rb, line 120
def environments_path
  verify_path ENVIRONMENTS_PATH
  File.join @tar_contents_path, ENVIRONMENTS_PATH
end
nodes() click to toggle source

Returns a list of absolute paths to the nodes json files

# File lib/chef/tar_file.rb, line 174
def nodes
  get_chef_files_absolute_paths nodes_path
end
nodes_path() click to toggle source

Returns the absolute path of the nodes directory

# File lib/chef/tar_file.rb, line 168
def nodes_path
  verify_path NODES_PATH
  File.join @tar_contents_path, NODES_PATH
end
roles() click to toggle source

Returns a list of absolute paths to the roles json files

# File lib/chef/tar_file.rb, line 115
def roles
  get_chef_files_absolute_paths roles_path
end
roles_path() click to toggle source

Returns the absolute path to the roles directory

# File lib/chef/tar_file.rb, line 109
def roles_path
  verify_path ROLES_PATH
  File.join @tar_contents_path, ROLES_PATH
end
save() click to toggle source
# File lib/chef/tar_file.rb, line 189
def save
  if @create_tar
    
    #Tar up the directory from the parent directory of the tar's contents (this will really be /tmp)
    Chef::Mixin::Command.run_command(:cwd => File.expand_path("..",@tar_contents_path), :command => "tar zfc #{@create_tar_path} #{File.basename @tar_contents_path}")
    
    @create_tar = false
  else
    raise StandardError, "The tar file is not in the correct state to be saved"
  end
end
web_users() click to toggle source

Returns a list of absolute paths to the web_users json files

# File lib/chef/tar_file.rb, line 185
def web_users
  get_chef_files_absolute_paths web_users_path
end
web_users_path() click to toggle source

Returns the absolute path of the web_users directory

# File lib/chef/tar_file.rb, line 179
def web_users_path
  verify_path WEB_USERS_PATH
  File.join @tar_contents_path, WEB_USERS_PATH
end

Private Instance Methods

get_chef_files_absolute_paths(path) click to toggle source

Returns a list of the absolute paths of all the valid chef component files at the given path

# File lib/chef/tar_file.rb, line 254
def get_chef_files_absolute_paths path
  get_file_absolute_paths(path).select { |file| is_valid_chef_component_file?(file) }
end
get_directories_absolute_paths(path) click to toggle source

Returns a list of the absolute paths of all the directories at the given path

# File lib/chef/tar_file.rb, line 233
def get_directories_absolute_paths path
  dir_list = Dir["#{path}/*/"]
  
  #Remove unnecessary directories
  dir_list.delete(File.join(path, "."))
  dir_list.delete(File.join(path, ".."))
  
  dir_list
end
get_directories_names(path) click to toggle source

Returns a list of the base file names for all the directories at the given path

# File lib/chef/tar_file.rb, line 228
def get_directories_names path
  get_directories_absolute_paths(path).map {|dir| File.basename(dir) }
end
get_file_absolute_paths(path) click to toggle source

Returns a list of the absolute paths of all the files at the given path

# File lib/chef/tar_file.rb, line 249
def get_file_absolute_paths path
  get_file_names(path).map { |file| File.join(path, file) }
end
get_file_names(path) click to toggle source

Returns a list of the base file names for all files at the given path

# File lib/chef/tar_file.rb, line 244
def get_file_names path
  Dir.entries(path).select { |file| !File.directory? File.join(path, file) }
end
is_tar_valid?(dir_list) click to toggle source

Returns true if the list of directories contains at least one chef component

# File lib/chef/tar_file.rb, line 204
def is_tar_valid? dir_list
  
  #Remove unnessary directories
  dir_list.delete(".")
  dir_list.delete("..")
  
  dir_list.each do |dir|
    [API_CLIENTS_PATH, COOKBOOKS_PATH, DATA_BAGS_PATH, ENVIRONMENTS_PATH, NODES_PATH, ROLES_PATH, WEB_USERS_PATH].each do |component|
      if dir == component
        return true
      end
    end
  end
  return false
end
is_valid_chef_component_file?(filename) click to toggle source

Returns true if the filename is a valid chef component file

# File lib/chef/tar_file.rb, line 259
def is_valid_chef_component_file? filename
  extension = File.extname(filename)
  CHEF_FILE_EXTENSIONS.each do |validExtension|
    if extension.casecmp(validExtension) == 0
      return true
    end
  end
  return false
end
verify_path(component) click to toggle source

Throws an exception if the given component does not exist within the tar's contents

# File lib/chef/tar_file.rb, line 221
def verify_path component
  if !File.exists? File.join @tar_contents_path, component
    raise MissingChefComponentError, "The '#{component}' directory does not exist within the tar file"
  end
end