Class: TestRunner::RepositorySource
- Inherits:
-
Object
- Object
- TestRunner::RepositorySource
- Defined in:
- lib/test-runner/repository_source.rb
Constant Summary collapse
- ROOT_DIRECTORY =
'os-test-runner-repository-sources'.freeze
Instance Attribute Summary collapse
-
#original_path ⇒ Object
readonly
Returns the value of attribute original_path.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#root_directory ⇒ Object
readonly
Returns the value of attribute root_directory.
Class Method Summary collapse
Instance Method Summary collapse
- #cleanup_stale_roots ⇒ Object protected
- #default_root_directory ⇒ Object protected
- #helper_file ⇒ Object protected
-
#initialize(original_path:, root_directory: nil, nixpkgs_path: nil, nix_system: nil) ⇒ RepositorySource
constructor
A new instance of RepositorySource.
- #open ⇒ Object
- #registry_lock_path ⇒ Object protected
- #remove_gc_root ⇒ Object protected
- #reserve_gc_root ⇒ Object protected
- #resolve_and_root_source ⇒ Object protected
- #resolve_path(file_path) ⇒ Object
- #unlink_gc_root(root_path) ⇒ Object protected
- #with_registry_lock ⇒ Object protected
Constructor Details
#initialize(original_path:, root_directory: nil, nixpkgs_path: nil, nix_system: nil) ⇒ RepositorySource
Returns a new instance of RepositorySource.
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/test-runner/repository_source.rb', line 17 def initialize(original_path:, root_directory: nil, nixpkgs_path: nil, nix_system: nil) @original_path = File.(original_path) @root_directory = File.(root_directory || default_root_directory) @nixpkgs_path = File.(nixpkgs_path || ENV.fetch('TEST_RUNNER_NIXPKGS_PATH')) @nix_system = nix_system || ENV.fetch('TEST_RUNNER_NIX_SYSTEM') @path = nil @lock_file = nil @lock_path = nil @root_path = nil end |
Instance Attribute Details
#original_path ⇒ Object (readonly)
Returns the value of attribute original_path.
10 11 12 |
# File 'lib/test-runner/repository_source.rb', line 10 def original_path @original_path end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
10 11 12 |
# File 'lib/test-runner/repository_source.rb', line 10 def path @path end |
#root_directory ⇒ Object (readonly)
Returns the value of attribute root_directory.
10 11 12 |
# File 'lib/test-runner/repository_source.rb', line 10 def root_directory @root_directory end |
Class Method Details
.open(original_path:, root_directory: nil, nixpkgs_path: nil, nix_system: nil) ⇒ Object
12 13 14 15 |
# File 'lib/test-runner/repository_source.rb', line 12 def self.open(original_path:, root_directory: nil, nixpkgs_path: nil, nix_system: nil) source = new(original_path:, root_directory:, nixpkgs_path:, nix_system:) source.open { yield(source) } end |
Instance Method Details
#cleanup_stale_roots ⇒ Object (protected)
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/test-runner/repository_source.rb', line 125 def cleanup_stale_roots Dir.glob(File.join(root_directory, '*.lock')).each do |lock_path| File.open(lock_path, File::RDWR) do |lock_file| next unless lock_file.flock(File::LOCK_EX | File::LOCK_NB) unlink_gc_root(lock_path.sub(/\.lock\z/, '.root')) File.unlink(lock_path) end rescue Errno::ENOENT next end Dir.glob(File.join(root_directory, '*.root')).each do |root_path| lock_path = root_path.sub(/\.root\z/, '.lock') unlink_gc_root(root_path) unless File.exist?(lock_path) end end |
#default_root_directory ⇒ Object (protected)
165 166 167 168 169 170 |
# File 'lib/test-runner/repository_source.rb', line 165 def default_root_directory runtime_dir = ENV.fetch('XDG_RUNTIME_DIR', nil) runtime_dir = Dir.tmpdir if runtime_dir.nil? || runtime_dir.empty? File.join(runtime_dir, "#{ROOT_DIRECTORY}-#{Process.uid}") end |
#helper_file ⇒ Object (protected)
50 51 52 |
# File 'lib/test-runner/repository_source.rb', line 50 def helper_file File.('../../nix/resolve-repository-source.nix', __dir__) end |
#open ⇒ Object
28 29 30 31 32 33 34 35 36 |
# File 'lib/test-runner/repository_source.rb', line 28 def open FileUtils.mkdir_p(root_directory, mode: 0o700) reserve_gc_root @path = resolve_and_root_source yield(self) ensure remove_gc_root end |
#registry_lock_path ⇒ Object (protected)
161 162 163 |
# File 'lib/test-runner/repository_source.rb', line 161 def registry_lock_path "#{root_directory}.lock" end |
#remove_gc_root ⇒ Object (protected)
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/test-runner/repository_source.rb', line 106 def remove_gc_root return if @lock_path.nil? && @root_path.nil? with_registry_lock do unlink_gc_root(@root_path) @lock_file&.flock(File::LOCK_UN) @lock_file&.close @lock_file = nil File.unlink(@lock_path) if @lock_path && File.file?(@lock_path) end rescue Errno::ENOENT nil ensure @lock_path = nil @root_path = nil end |
#reserve_gc_root ⇒ Object (protected)
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/test-runner/repository_source.rb', line 81 def reserve_gc_root with_registry_lock do cleanup_stale_roots loop do token = "#{Process.pid}-#{SecureRandom.hex(8)}" @lock_path = File.join(root_directory, "#{token}.lock") @root_path = File.join(root_directory, "#{token}.root") begin @lock_file = File.open( @lock_path, File::RDWR | File::CREAT | File::EXCL, 0o600 ) break rescue Errno::EEXIST next end end @lock_file.flock(File::LOCK_EX) end end |
#resolve_and_root_source ⇒ Object (protected)
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/test-runner/repository_source.rb', line 54 def resolve_and_root_source out, status = Open3.capture2( 'nix-build', '--out-link', @root_path, helper_file, '--arg', 'repoRoot', original_path, '--arg', 'nixpkgsPath', @nixpkgs_path, '--argstr', 'nixSystem', @nix_system ) unless status.success? raise "unable to resolve and GC-root repository source (#{status.exitstatus})" end output_path = out.lines.map(&:strip).reject(&:empty?).last raise 'nix-build returned no repository source output' if output_path.nil? File.realpath(File.join(output_path, 'source')) end |
#resolve_path(file_path) ⇒ Object
38 39 40 41 42 43 44 45 46 |
# File 'lib/test-runner/repository_source.rb', line 38 def resolve_path(file_path) return nil if file_path.nil? || file_path.empty? = File.(file_path, original_path) relative = Pathname.new().relative_path_from(Pathname.new(original_path)) return if relative.each_filename.first == '..' File.join(path, relative.to_s) end |
#unlink_gc_root(root_path) ⇒ Object (protected)
152 153 154 155 156 157 158 159 |
# File 'lib/test-runner/repository_source.rb', line 152 def unlink_gc_root(root_path) return if root_path.nil? return unless File.file?(root_path) || File.symlink?(root_path) File.unlink(root_path) rescue Errno::ENOENT nil end |
#with_registry_lock ⇒ Object (protected)
143 144 145 146 147 148 149 150 |
# File 'lib/test-runner/repository_source.rb', line 143 def with_registry_lock File.open(registry_lock_path, File::RDWR | File::CREAT, 0o600) do |lock_file| lock_file.flock(File::LOCK_EX) yield ensure lock_file.flock(File::LOCK_UN) end end |