Class: Machinery::Migration
Overview
SystemDescription Migrations
Migrations are used for migrating descriptions with an older format version to the current version. They are defined as subclasses of ‘Migration` in `schema/migrations`.
Naming schema
Migrations need to follow a naming schema defining which format version they are working on. ‘Migrate1To2` defines a migration which converts a version 1 description to a version 2 one, for example.
Defining migrations
The migration classes need to define a ‘migrate` method which does the actual migration. The raw hash of the system description in question is made available as the `@hash` instance variable, the path to the description on disk is given ash the `@path` instance variable.
Migrations also need to describe their purpose using the ‘desc` class method (see example below).
Note: Migrations do not need to take care of updating the format version attribute in the system description. That is already handled by the base class.
Simple example migration which adds a new attribute to the JSON:
class Machinery::Migrate1To2 < Machinery::Migration
desc <<-EOT
Add 'foo' element to the system description root.
EOT
def migrate
is_extracted = Dir.exist?(File.join(@path, "config-files"))
@hash["changed_config_files"]["extracted"] = is_extracted
end
end
Constant Summary collapse
Class Attribute Summary collapse
-
.migration_desc ⇒ Object
readonly
Returns the value of attribute migration_desc.
Instance Attribute Summary collapse
-
#hash ⇒ Object
Returns the value of attribute hash.
-
#path ⇒ Object
Returns the value of attribute path.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(hash, path) ⇒ Migration
constructor
A new instance of Migration.
Constructor Details
#initialize(hash, path) ⇒ Migration
Returns a new instance of Migration.
160 161 162 163 |
# File 'lib/migration.rb', line 160 def initialize(hash, path) @hash = hash @path = path end |
Class Attribute Details
.migration_desc ⇒ Object (readonly)
Returns the value of attribute migration_desc.
60 61 62 |
# File 'lib/migration.rb', line 60 def migration_desc @migration_desc end |
Instance Attribute Details
#hash ⇒ Object
Returns the value of attribute hash.
155 156 157 |
# File 'lib/migration.rb', line 155 def hash @hash end |
#path ⇒ Object
Returns the value of attribute path.
156 157 158 |
# File 'lib/migration.rb', line 156 def path @path end |
Class Method Details
.desc(s) ⇒ Object
62 63 64 |
# File 'lib/migration.rb', line 62 def desc(s) @migration_desc = s end |
.migrate_description(store, description_name, options = {}) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/migration.rb', line 66 def migrate_description(store, description_name, = {}) load_migrations hash = Machinery::Manifest.load( description_name, store.manifest_path(description_name) ).to_hash errors = Machinery::JsonValidator.new(hash).validate errors += Machinery::FileValidator.new( hash, store.description_path(description_name) ).validate unless errors.empty? if [:force] Machinery::Ui.warn("Warning: System Description validation errors:") Machinery::Ui.warn(errors.join(", ")) else raise Machinery::Errors::SystemDescriptionValidationFailed.new(errors) end end current_version = hash["meta"]["format_version"] unless current_version raise Machinery::Errors::SystemDescriptionIncompatible.new( "The system description '#{description_name}' was generated by an old " \ "version of machinery that is not supported by the upgrade mechanism." ) end if current_version == Machinery::SystemDescription::CURRENT_FORMAT_VERSION Machinery::Ui.puts "No upgrade necessary." return false end backup_description = store.backup(description_name) backup_path = store.description_path(backup_description) backup_hash = Machinery::Manifest.load( backup_description, store.manifest_path(backup_description) ).to_hash (current_version..Machinery::SystemDescription::CURRENT_FORMAT_VERSION - 1).each do |version| next_version = version + 1 begin klass = Object.const_get("Machinery::Migrate#{version}To#{next_version}") rescue NameError return end # Make sure that the migration was documented if klass.migration_desc.nil? raise Machinery::Errors::MigrationError.new( "Invalid migration '#{klass}'. It does not specify its purpose using" \ " the 'desc' class method." ) end klass.new(backup_hash, backup_path).migrate backup_hash["meta"]["format_version"] = next_version end File.write(store.manifest_path(backup_description), JSON.pretty_generate(backup_hash)) if [:force] store.swap(description_name, backup_description) Machinery::Ui.puts "Saved backup to #{backup_path}" else begin Machinery::SystemDescription.load!(backup_description, store) store.remove(description_name) store.rename(backup_description, description_name) rescue Machinery::Errors::SystemDescriptionError store.remove(backup_description) raise end end true end |