From 5f90a16c9b946d737475b8356d8530ae615679f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tina=20M=C3=BCller?= Date: Fri, 23 Jun 2023 11:06:35 +0200 Subject: [PATCH] Do not hardlink symlink assets Issue: https://progress.opensuse.org/issues/129340 Hardlinking a symlink will only work if the link is absolute, and we would have to check that recursively if the symlink target itself is a symlink, so just fall back to symlink then. --- lib/OpenQA/Worker/Engines/isotovideo.pm | 12 ++++++--- t/24-worker-engine.t | 26 ++++++++++++++----- t/data/openqa/share/factory/hdd/symlink.qcow2 | 1 + 3 files changed, 29 insertions(+), 10 deletions(-) create mode 120000 t/data/openqa/share/factory/hdd/symlink.qcow2 diff --git a/lib/OpenQA/Worker/Engines/isotovideo.pm b/lib/OpenQA/Worker/Engines/isotovideo.pm index 447400d10c87..77481785818f 100644 --- a/lib/OpenQA/Worker/Engines/isotovideo.pm +++ b/lib/OpenQA/Worker/Engines/isotovideo.pm @@ -176,10 +176,16 @@ sub _link_asset ($asset, $pooldir) { # Try to use hardlinks first and only fall back to symlinks when that fails, # to ensure that assets cannot be purged early from the pool even if the # cache service runs out of space - eval { link($asset, $target) or die qq{Cannot create link from "$asset" to "$target": $!} }; - if (my $err = $@) { + # If the given asset is a symlink itself, to not hardlink a symlink + my $linked = 0; + unless (-l $asset) { + $linked = eval { link($asset, $target) or die qq{Cannot create link from "$asset" to "$target": $!} }; + if (my $err = $@) { + log_debug(qq{Symlinking asset because hardlink failed: $err}); + } + } + unless ($linked) { symlink($asset, $target) or die qq{Cannot create symlink from "$asset" to "$target": $!}; - log_debug(qq{Symlinked asset because hardlink failed: $err}); } log_debug(qq{Linked asset "$asset" to "$target"}); diff --git a/t/24-worker-engine.t b/t/24-worker-engine.t index 7653f7a72ce0..5af0c18aa833 100644 --- a/t/24-worker-engine.t +++ b/t/24-worker-engine.t @@ -428,21 +428,33 @@ subtest 'behavior with ABSOLUTE_TEST_CONFIG_PATHS=1' => sub { }; }; -subtest 'symlink asset' => sub { +subtest 'link asset' => sub { my $pool_directory = tempdir('poolXXXX'); my $worker = OpenQA::Test::FakeWorker->new(pool_directory => $pool_directory); my $client = Test::FakeClient->new; - my $settings - = {JOBTOKEN => 'token000', ISO => 'openSUSE-13.1-DVD-x86_64-Build0091-Media.iso', HDD_1 => 'foo.qcow2'}; + my $settings = { + JOBTOKEN => 'token000', + ISO => 'openSUSE-13.1-DVD-x86_64-Build0091-Media.iso', + HDD_1 => 'foo.qcow2', + HDD_2 => 'symlink.qcow2', + }; my $job = OpenQA::Worker::Job->new($worker, $client, {id => 16, settings => $settings}); combined_like { my $result = _run_engine($job) } qr/Linked asset/, 'linked asset'; my $vars_data = get_job_json_data($pool_directory); - ok(-e "$pool_directory/openSUSE-13.1-DVD-x86_64-Build0091-Media.iso", 'the iso is symlinked to pool directory'); - ok(-e "$pool_directory/foo.qcow2", 'the hdd is symlinked to pool directory'); + my $orig_hdd = locate_asset('hdd', 'foo.qcow2'); + my $orig_iso = locate_asset('iso', 'openSUSE-13.1-DVD-x86_64-Build0091-Media.iso'); + my $linked_iso = "$pool_directory/openSUSE-13.1-DVD-x86_64-Build0091-Media.iso"; + my $linked_hdd = "$pool_directory/foo.qcow2"; + my $linked_hdd2 = "$pool_directory/symlink.qcow2"; + ok -e $linked_iso, 'the iso is linked to pool directory'; + ok -e $linked_hdd, 'the hdd is linked to pool directory'; + ok -l $linked_hdd2, 'the hdd 2 is symlinked to pool directory'; + is + (stat $linked_hdd)[1], +(stat $orig_hdd)[1], 'hdd is hardlinked'; + is + (stat $linked_iso)[1], +(stat $orig_iso)[1], 'iso is hardlinked'; is $vars_data->{ISO}, 'openSUSE-13.1-DVD-x86_64-Build0091-Media.iso', - 'the value of ISO is basename when doing symlink'; - is $vars_data->{HDD_1}, 'foo.qcow2', 'the value of HDD_1 is basename when doing symlink'; + 'the value of ISO is basename when doing link'; + is $vars_data->{HDD_1}, 'foo.qcow2', 'the value of HDD_1 is basename when doing link'; }; done_testing(); diff --git a/t/data/openqa/share/factory/hdd/symlink.qcow2 b/t/data/openqa/share/factory/hdd/symlink.qcow2 new file mode 120000 index 000000000000..e54be38efb37 --- /dev/null +++ b/t/data/openqa/share/factory/hdd/symlink.qcow2 @@ -0,0 +1 @@ +foo.qcow2 \ No newline at end of file