class BoxGrinder::ApplianceParser

Public Class Methods

new(options = {}) click to toggle source
# File lib/boxgrinder-core/appliance-parser.rb, line 27
def initialize(options = {})
  @log = options[:log] || LogHelper.new
  @schemas = {}
end

Public Instance Methods

load_schemas() click to toggle source
# File lib/boxgrinder-core/appliance-parser.rb, line 32
def load_schemas
  Dir.glob("#{File.dirname(__FILE__)}/schemas/{*.yaml,*.yml}").each do |f|
    # DON'T use Kwalify::Yaml here!
    # This will not treat '#' sign in schema files correctly
    schema = YAML.load_file(f)
    @schemas[schema['version']] = schema
  end
end
parse(schema_document, appliance_definition) click to toggle source
# File lib/boxgrinder-core/appliance-parser.rb, line 73
def parse(schema_document, appliance_definition)
  validator = ApplianceValidator.new(schema_document)
  parser = Kwalify::Yaml::Parser.new(validator)
  parser.data_binding = true

  begin
    parsed = parser.parse(appliance_definition)
  rescue Kwalify::KwalifyError => e
    raise ApplianceValidationError, "The appliance definition couldn't be parsed. [line #{e.linenum}, col #{e.column}] [#{e.path}] Make sure you use correct indentation (don't use tabs). If indentation is correct and you try to specify partition mount point, please quote it: \"/foo\" instead of /foo." if e.message =~ %rdocument end expected \(maybe invalid tab char found\)/
    raise ApplianceValidationError, "The appliance definition couldn't be parsed. #{e}"
  end

  [parsed, parser.errors]
end
parse_definition(appliance_definition, file = true) click to toggle source
# File lib/boxgrinder-core/appliance-parser.rb, line 41
def parse_definition(appliance_definition, file = true)
  if file
    @log.info "Validating appliance definition from #{appliance_definition} file..."
    appliance_definition = File.read(appliance_definition)
  else
    @log.info "Validating appliance definition from string..."
  end

  failures = {}
  schema_versions = @schemas.keys.sort.reverse

  schema_versions.each do |schema_version|
    @log.debug "Parsing definition using schema version #{schema_version}."
    @schemas[schema_version].delete('version')
    appliance_config, errors = parse(@schemas[schema_version], appliance_definition)

    if errors.empty?
      @log.info "Appliance definition is valid."
      return ApplianceTransformationHelper.new(schema_versions.first, :log => @log).transform(appliance_config, schema_version)
    end

    failures[schema_version] = errors
  end

  # If all schemas fail then we assume they are using the latest schema..
  failures[schema_versions.first].each do |error|
    @log.error "Error: [line #{error.linenum}, col #{error.column}] [#{error.path}] #{error.message}"
  end

  raise ApplianceValidationError, "The appliance definition was invalid according to schema #{schema_versions.first}. See log for details."
end