Class: Tebako::ReleaseStore
- Inherits:
-
Object
- Object
- Tebako::ReleaseStore
- Defined in:
- lib/tebako/release_store.rb
Overview
Content-addressed package releases with verified atomic activation and rollback.
Constant Summary collapse
- SCHEMA_VERSION =
1
Instance Method Summary collapse
- #activate(release_id, target) ⇒ Object
- #import(package_path) ⇒ Object
-
#initialize(root) ⇒ ReleaseStore
constructor
A new instance of ReleaseStore.
- #rollback(target) ⇒ Object
- #status ⇒ Object
Constructor Details
#initialize(root) ⇒ ReleaseStore
Returns a new instance of ReleaseStore.
22 23 24 25 26 27 28 |
# File 'lib/tebako/release_store.rb', line 22 def initialize(root) @root = File.(root) @objects = File.join(@root, "objects", "sha256") @releases = File.join(@root, "releases") @history = File.join(@root, "history.json") @lock = File.join(@root, "update.lock") end |
Instance Method Details
#activate(release_id, target) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/tebako/release_store.rb', line 58 def activate(release_id, target) with_lock do release = load_release(release_id) package_object = object_path(release.fetch("package_sha256")) verify_object!(package_object, release.fetch("package_sha256"), release.fetch("package_size")) previous = File.file?(target) ? Digest::SHA256.file(target).hexdigest : nil publish_target(package_object, target) append_history(release_id, previous) release end end |
#import(package_path) ⇒ Object
30 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 |
# File 'lib/tebako/release_store.rb', line 30 def import(package_path) inspection = Tebako::LayeredPackage.inspect(package_path) package = File.binread(package_path) FileUtils.mkdir_p([@objects, @releases]) new_objects = 0 new_objects += 1 if store_object(inspection.sha256, package) layers = inspection.layers.map do |layer| payload = package.byteslice(layer.offset, layer.byte_size) new_objects += 1 if store_object(layer.sha256, payload) { "mount_point" => layer.mount_point, "sha256" => layer.sha256, "size" => layer.byte_size } end release = { "schema_version" => SCHEMA_VERSION, "release_id" => inspection.sha256, "package_sha256" => inspection.sha256, "package_size" => inspection.byte_size, "format" => inspection.format, "format_version" => "#{inspection.major_version}.#{inspection.minor_version}", "layers" => layers } atomic_write_json(release_path(inspection.sha256), release) release.merge("new_objects" => new_objects) end |
#rollback(target) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/tebako/release_store.rb', line 70 def rollback(target) with_lock do history = read_history raise ArgumentError, "No previous release is available" if history.length < 2 history.pop previous = history.last.fetch("release_id") release = load_release(previous) package_object = object_path(release.fetch("package_sha256")) verify_object!(package_object, release.fetch("package_sha256"), release.fetch("package_size")) publish_target(package_object, target) atomic_write_json(@history, history) release end end |
#status ⇒ Object
86 87 88 89 90 91 92 93 |
# File 'lib/tebako/release_store.rb', line 86 def status { "schema_version" => SCHEMA_VERSION, "history" => read_history, "objects" => Dir.exist?(@objects) ? Dir.children(@objects).length : 0, "releases" => Dir.exist?(@releases) ? Dir.glob(File.join(@releases, "*.json")).length : 0 } end |