Module: Tebako::SingleFileBundle
- Defined in:
- lib/tebako/single_file_bundle.rb
Overview
Atomically combines a layered application with a reusable runtime executable.
Defined Under Namespace
Classes: Inspection
Constant Summary collapse
- Format =
Tebako::Generated::SingleFileBundleFormat
- MACHO_64_MAGIC =
"\xcf\xfa\xed\xfe".b
- MACHO_SEGMENT_64 =
0x19- MACHO_HEADER_SIZE =
32- MACHO_SEGMENT_SIZE =
72- MACHO_SECTION_SIZE =
80- MACHO_SEGMENT =
"__TEBAKO"- MACHO_SECTION =
"__app"
Class Method Summary collapse
- .application_bytes(path) ⇒ Object
- .bundle?(path) ⇒ Boolean
- .inspect(path) ⇒ Object
- .write(output, runtime:, application:, assembler: nil) ⇒ Object
Class Method Details
.application_bytes(path) ⇒ Object
102 103 104 105 106 107 |
# File 'lib/tebako/single_file_bundle.rb', line 102 def application_bytes(path) data = File.binread(path) envelope, = locate_envelope(data) application, = decode(envelope, require_runtime: false) application end |
.bundle?(path) ⇒ Boolean
47 48 49 50 51 52 53 54 |
# File 'lib/tebako/single_file_bundle.rb', line 47 def bundle?(path) return false unless File.file?(path) data = File.binread(path) appended_bundle?(data) || !macho_envelope(data).nil? rescue SystemCallError false end |
.inspect(path) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/tebako/single_file_bundle.rb', line 82 def inspect(path) data = File.binread(path) envelope, runtime_size, container = locate_envelope(data) application, _, digest = decode(envelope, require_runtime: false) actual_digest = Digest::SHA256.hexdigest(application) raise ArgumentError, "Single-file bundle application checksum is invalid" unless actual_digest == digest Inspection.new( format: "single_file_bundle", container: container, major_version: Format::MAJOR_VERSION, minor_version: Format::MINOR_VERSION, runtime_size: runtime_size, application_size: application.bytesize, application_sha256: digest, byte_size: data.bytesize, application: Tebako::LayeredPackage.inspect_bytes(application) ) end |
.write(output, runtime:, application:, assembler: nil) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/tebako/single_file_bundle.rb', line 56 def write(output, runtime:, application:, assembler: nil) application_inspection = Tebako::LayeredPackage.inspect(application) temporary = "#{output}.#{Process.pid}.#{SecureRandom.hex(6)}.tmp" payload = "#{temporary}.payload" FileUtils.mkdir_p(File.dirname(File.(output))) write_envelope(payload, application, application_inspection.sha256) if assembler assembler.call(temporary, payload) else File.open(temporary, "wb") do |bundle| File.open(runtime, "rb") { |source| IO.copy_stream(source, bundle) } File.open(payload, "rb") { |source| IO.copy_stream(source, bundle) } bundle.flush bundle.fsync end end FileUtils.chmod(File.stat(runtime).mode & 0o7777, temporary) inspection = inspect(temporary) File.rename(temporary, output) report(runtime, application, output, inspection.container) output ensure FileUtils.rm_f(temporary) if temporary FileUtils.rm_f(payload) if payload end |