Class: SystemDescription

Inherits:
Machinery::Object show all
Defined in:
lib/system_description.rb

Overview

Copyright © 2013-2014 SUSE LLC

This program is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, contact SUSE LLC.

To contact SUSE about this file by physical or electronic mail, you may find current contact information at www.suse.com

Constant Summary collapse

CURRENT_FORMAT_VERSION =
2
EXTRACTABLE_SCOPES =
[
  "changed_managed_files",
  "config_files",
  "unmanaged_files"
]

Instance Attribute Summary collapse

Attributes inherited from Machinery::Object

#attributes

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Machinery::Object

#==, #[], #[]=, #as_json, #compare_with, #empty?, has_property, #hash, #initialize_copy, #method_missing, #respond_to?

Constructor Details

#initialize(name, hash = {}, store = nil) ⇒ SystemDescription

Returns a new instance of SystemDescription.



103
104
105
106
107
108
109
# File 'lib/system_description.rb', line 103

def initialize(name, hash = {}, store = nil)
  @name = name
  @store = store
  @format_version = CURRENT_FORMAT_VERSION

  super(hash)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Machinery::Object

Instance Attribute Details

#format_versionObject

Returns the value of attribute format_version.



28
29
30
# File 'lib/system_description.rb', line 28

def format_version
  @format_version
end

#nameObject

Returns the value of attribute name.



26
27
28
# File 'lib/system_description.rb', line 26

def name
  @name
end

#storeObject

Returns the value of attribute store.



27
28
29
# File 'lib/system_description.rb', line 27

def store
  @store
end

Class Method Details

.create_attrs(hash) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/system_description.rb', line 76

def create_attrs(hash)
  entries = hash.map do |key, value|
    next if key == "meta"

    class_name = "#{key.split("_").map(&:capitalize).join}Scope"
    value_converted = Object.const_get(class_name).from_json(value)

    # Set metadata
    if hash["meta"] && hash["meta"][key]
      value_converted.meta = Machinery::Object.from_json(hash["meta"][key])
    end

    [key, value_converted]
  end.compact

  Hash[entries]
end

.from_json(name, json, store = nil) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/system_description.rb', line 31

def from_json(name, json, store = nil)
  begin
    json_hash = JSON.parse(json)
  rescue JSON::ParserError => e
    lines = e.message.split("\n")
    error_pos = json.split("\n").length - lines.length + 2
    block_end = lines.index { |l| l =~ / [\}\]],?$/ }

    # remove needless json error information
    lines[0].gsub!(/^\d+: (.*)$/, "\\1")
    json_error = lines[0..block_end].join("\n")

    if error_pos == 1
      json_error = "An opening bracket, a comma or quotation is missing " \
        "in one of the global scope definitions or in the meta section. " \
        "Unlike issues with the elements of the scopes, our JSON parser " \
        "isn't able to locate issues like these."
      error_pos = nil
    end

    error = "The JSON data of the system description '#{name}' " \
      "couldn't be parsed. The following error occured"
    error += " around line #{error_pos}" if error_pos
    error += " in file '#{store.manifest_path(name)}'" if store
    error += ":\n\n#{json_error}"

    raise Machinery::Errors::SystemDescriptionError.new(error)
  end

  if compatible_json?(json_hash)
    SystemDescriptionValidator.new(self).validate_json(json_hash)
  end

  begin
    description = self.new(name, self.create_attrs(json_hash), store)
  rescue NameError
    raise Machinery::Errors::SystemDescriptionIncompatible.new(name)
  end

  json_format_version = json_hash["meta"]["format_version"] if json_hash["meta"]
  description.format_version = json_format_version

  description
end

Instance Method Details

#additional_files(scope, file_list) ⇒ Object



193
194
195
196
197
198
# File 'lib/system_description.rb', line 193

def additional_files(scope, file_list)
  file_list.map! { |file| File.join(file_store(scope), file) }
  files = list_file_store_content(scope)

  files - file_list
end

#assert_scopes(*scopes) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/system_description.rb', line 146

def assert_scopes(*scopes)
  missing = scopes.reject do |e|
    self.send(e) && !self.send(e).empty?
  end

  unless missing.empty?
    raise Machinery::Errors::SystemDescriptionError.new(
      "The system description misses the following section(s): #{missing.join(", ")}."
    )
  end
end

#compatible?Boolean

Returns:

  • (Boolean)


111
112
113
114
# File 'lib/system_description.rb', line 111

def compatible?
  !format_version.nil? &&
    format_version == SystemDescription::CURRENT_FORMAT_VERSION
end

#create_file_store_sub_dir(store_name, sub_dir) ⇒ Object



225
226
227
# File 'lib/system_description.rb', line 225

def create_file_store_sub_dir(store_name, sub_dir)
  @store.create_file_store_sub_dir(self.name, store_name, sub_dir)
end

#file_store(store_name) ⇒ Object



209
210
211
# File 'lib/system_description.rb', line 209

def file_store(store_name)
  @store.file_store(self.name, store_name)
end

#initialize_file_store(store_name) ⇒ Object

Filestore handling



205
206
207
# File 'lib/system_description.rb', line 205

def initialize_file_store(store_name)
  @store.initialize_file_store(self.name, store_name)
end

#list_file_store_content(store_name) ⇒ Object



221
222
223
# File 'lib/system_description.rb', line 221

def list_file_store_content(store_name)
  @store.list_file_store_content(self.name, store_name)
end

#missing_files(scope, file_list) ⇒ Object



185
186
187
188
189
190
191
# File 'lib/system_description.rb', line 185

def missing_files(scope, file_list)
  file_list.map! { |file| File.join(file_store(scope), file) }

  file_list.select do |file|
    !File.exists?(file)
  end
end

#os_objectObject



175
176
177
178
179
180
181
182
183
# File 'lib/system_description.rb', line 175

def os_object
  assert_scopes("os")

  begin
    Os.for(self.os.name)
  rescue Machinery::Errors::UnknownOs => e
    raise Machinery::Errors::SystemDescriptionError.new(e)
  end
end

#remove_file_store(store_name) ⇒ Object



213
214
215
# File 'lib/system_description.rb', line 213

def remove_file_store(store_name)
  @store.remove_file_store(self.name, store_name)
end

#rename_file_store(old_name, new_name) ⇒ Object



217
218
219
# File 'lib/system_description.rb', line 217

def rename_file_store(old_name, new_name)
  @store.rename_file_store(self.name, old_name, new_name)
end

#scope_extracted?(scope) ⇒ Boolean

Returns:

  • (Boolean)


171
172
173
# File 'lib/system_description.rb', line 171

def scope_extracted?(scope)
  self[scope] && self[scope].is_extractable? && self[scope].extracted
end

#scopesObject



139
140
141
142
143
144
# File 'lib/system_description.rb', line 139

def scopes
  scopes = attributes.map {
    |key, value| key.to_s
  }.sort
  scopes
end

#short_os_versionObject



158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/system_description.rb', line 158

def short_os_version
  assert_scopes("os")

  case self.os.name
    when /^SUSE Linux Enterprise Server/
      "sles" + self.os.version[/\d+( SP\d+)*/].gsub(" ", "").downcase
    when /^openSUSE/
      self.os.version[/^\d+.\d+/]
    else
      "unknown"
  end
end

#to_hashObject



122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/system_description.rb', line 122

def to_hash
  meta = {}
  meta["format_version"] = self.format_version if self.format_version

  attributes.each do |key, value|
    meta[key] = self[key].meta.as_json if self[key].meta
  end

  hash = as_json
  hash["meta"] = meta unless meta.empty?
  hash
end

#to_jsonObject



135
136
137
# File 'lib/system_description.rb', line 135

def to_json
  JSON.pretty_generate(to_hash)
end

#validate_compatibilityObject



116
117
118
119
120
# File 'lib/system_description.rb', line 116

def validate_compatibility
  if !compatible?
    raise Machinery::Errors::SystemDescriptionIncompatible.new(self.name)
  end
end

#validate_file_dataObject



200
201
202
# File 'lib/system_description.rb', line 200

def validate_file_data
  SystemDescriptionValidator.new(self).validate_file_data
end