]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
import: Only keep RO copy if ETag header is set 15194/head
authorKevin Kuehler <keur@xcf.berkeley.edu>
Sun, 15 Mar 2020 20:46:27 +0000 (13:46 -0700)
committerKevin Kuehler <keur@xcf.berkeley.edu>
Tue, 24 Mar 2020 04:39:59 +0000 (21:39 -0700)
We fix the case when the webserver servers container images without
setting the ETag header in the response.  When an image is downloaded to
image root, a read only copy is stored alongside it.  The filename has
the following form:
    .raw-<encoded-url-of-image>.\x22<ETAG-header>\22.raw.
This is so, if the same resource is fetched multiple times, importd can
avoid extra downloads by creating the new image using the local read-only copy.

The current code assumes the ETag header is set because, if the server
does not set the ETag header, the file is stored without the ETag value
in the filename. When importd fetches a duplicate image, it will run
rename_noreplace and fail:

  Failed to rename raw file to /var/lib/machines/.raw-http:\x2f\x2flocalhost:8000\x2fwalkthroughd.raw: File exists

This patch makes importd only store a read-only image if the webserver
has set the ETag header.

src/import/pull-raw.c

index 51c12444e00af53491ff855f1b55aa24447795ea..0183c13f461112aeb1c6af9aeb0ce542255918f6 100644 (file)
@@ -509,14 +509,17 @@ static void raw_pull_job_on_finished(PullJob *j) {
 
                 raw_pull_report_progress(i, RAW_FINALIZING);
 
-                r = import_make_read_only_fd(i->raw_job->disk_fd);
-                if (r < 0)
-                        goto finish;
+                if (i->raw_job->etag) {
+                        /* Only make a read-only copy if ETag header is set. */
+                        r = import_make_read_only_fd(i->raw_job->disk_fd);
+                        if (r < 0)
+                                goto finish;
 
-                r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path);
-                        goto finish;
+                        r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
+                        if (r < 0) {
+                                log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path);
+                                goto finish;
+                        }
                 }
 
                 i->temp_path = mfree(i->temp_path);