static gboolean copy_modules (const char *release, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; ot_lobj GFile *src_modules_file = NULL; ot_lobj GFile *dest_modules_parent = NULL; ot_lobj GFile *dest_modules_file = NULL; src_modules_file = ot_gfile_from_build_path ("/lib/modules", release, NULL); dest_modules_file = ot_gfile_from_build_path (opt_ostree_dir, "modules", release, NULL); dest_modules_parent = g_file_get_parent (dest_modules_file); if (!ot_gfile_ensure_directory (dest_modules_parent, FALSE, error)) goto out; if (!g_file_query_exists (dest_modules_file, cancellable)) { if (!ot_gio_shutil_cp_al_or_fallback (src_modules_file, dest_modules_file, cancellable, error)) goto out; } ret = TRUE; out: if (error) g_prefix_error (error, "Error copying kernel modules: "); return ret; }
static gboolean do_checkout (OtAdminDeploy *self, const char *deploy_target, const char *revision, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; ot_lobj GFile *deploy_path = NULL; ot_lobj GFile *deploy_parent = NULL; ot_lfree char *tree_ref = NULL; ot_lptrarray GPtrArray *checkout_args = NULL; deploy_path = ot_gfile_from_build_path ("/ostree", deploy_target, NULL); deploy_parent = g_file_get_parent (deploy_path); if (!ot_gfile_ensure_directory (deploy_parent, TRUE, error)) goto out; checkout_args = g_ptr_array_new (); ot_ptrarray_add_many (checkout_args, "ostree", "--repo=/ostree/repo", "checkout", "--atomic-retarget", revision ? revision : deploy_target, ot_gfile_get_path_cached (deploy_path), NULL); g_ptr_array_add (checkout_args, NULL); if (!ot_spawn_sync_checked ("/ostree", (char**)checkout_args->pdata, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, error)) goto out; ret = TRUE; out: return ret; }
gboolean ot_gfile_ensure_directory (GFile *dir, gboolean with_parents, GError **error) { gboolean ret = FALSE; GError *temp_error = NULL; if (!g_file_make_directory (dir, NULL, &temp_error)) { if (with_parents && g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { ot_lobj GFile *parent = NULL; g_clear_error (&temp_error); parent = g_file_get_parent (dir); if (parent) { if (!ot_gfile_ensure_directory (parent, TRUE, error)) goto out; } if (!ot_gfile_ensure_directory (dir, FALSE, error)) goto out; } else if (!g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) { g_propagate_error (error, temp_error); goto out; } else g_clear_error (&temp_error); } ret = TRUE; out: return ret; }
static gboolean cp_internal (GFile *src, GFile *dest, gboolean use_hardlinks, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; ot_lobj GFileEnumerator *enumerator = NULL; ot_lobj GFileInfo *file_info = NULL; GError *temp_error = NULL; enumerator = g_file_enumerate_children (src, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!enumerator) goto out; if (!ot_gfile_ensure_directory (dest, FALSE, error)) goto out; while ((file_info = g_file_enumerator_next_file (enumerator, cancellable, &temp_error)) != NULL) { const char *name = g_file_info_get_name (file_info); ot_lobj GFile *src_child = g_file_get_child (src, name); ot_lobj GFile *dest_child = g_file_get_child (dest, name); if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) { if (!ot_gfile_ensure_directory (dest_child, FALSE, error)) goto out; /* Can't do this even though we'd like to; it fails with an error about * setting standard::type not being supported =/ * if (!g_file_set_attributes_from_info (dest_child, file_info, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error)) goto out; */ if (chmod (ot_gfile_get_path_cached (dest_child), g_file_info_get_attribute_uint32 (file_info, "unix::mode")) == -1) { ot_util_set_error_from_errno (error, errno); goto out; } if (!cp_internal (src_child, dest_child, use_hardlinks, cancellable, error)) goto out; } else { gboolean did_link = FALSE; (void) unlink (ot_gfile_get_path_cached (dest_child)); if (use_hardlinks) { if (link (ot_gfile_get_path_cached (src_child), ot_gfile_get_path_cached (dest_child)) == -1) { if (!(errno == EMLINK || errno == EXDEV)) { ot_util_set_error_from_errno (error, errno); goto out; } use_hardlinks = FALSE; } else did_link = TRUE; } if (!did_link) { if (!g_file_copy (src_child, dest_child, G_FILE_COPY_OVERWRITE | G_FILE_COPY_ALL_METADATA | G_FILE_COPY_NOFOLLOW_SYMLINKS, cancellable, NULL, NULL, error)) goto out; } } g_clear_object (&file_info); } if (temp_error) { g_propagate_error (error, temp_error); goto out; } ret = TRUE; out: return ret; }
static gboolean update_initramfs (const char *release, const char *deploy_target, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; ot_lobj GFile *dest_modules_parent = NULL; ot_lobj GFile *dest_modules_file = NULL; ot_lfree char *initramfs_name = NULL; ot_lobj GFile *initramfs_file = NULL; ot_lfree char *last_deploy_path = NULL; dest_modules_file = ot_gfile_from_build_path ("/ostree/modules", release, NULL); dest_modules_parent = g_file_get_parent (dest_modules_file); if (!ot_gfile_ensure_directory (dest_modules_parent, FALSE, error)) goto out; if (!g_file_query_exists (dest_modules_file, NULL)) { ot_lptrarray GPtrArray *cp_args = NULL; ot_lobj GFile *src_modules_file = ot_gfile_from_build_path ("/lib/modules", release, NULL); cp_args = g_ptr_array_new (); ot_ptrarray_add_many (cp_args, "cp", "-al", ot_gfile_get_path_cached (src_modules_file), ot_gfile_get_path_cached (dest_modules_file), NULL); g_ptr_array_add (cp_args, NULL); g_print ("Copying kernel modules from %s\n", ot_gfile_get_path_cached (src_modules_file)); if (!ot_spawn_sync_checked (NULL, (char**)cp_args->pdata, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, error)) goto out; } initramfs_name = g_strconcat ("initramfs-ostree-", release, ".img", NULL); initramfs_file = ot_gfile_from_build_path ("/boot", initramfs_name, NULL); if (!g_file_query_exists (initramfs_file, NULL)) { ot_lptrarray GPtrArray *mkinitramfs_args = NULL; ot_lobj GFile *tmpdir = NULL; ot_lfree char *initramfs_tmp_path = NULL; ot_lobj GFile *initramfs_tmp_file = NULL; ot_lobj GFileInfo *initramfs_tmp_info = NULL; if (!ostree_create_temp_dir (NULL, "ostree-initramfs", NULL, &tmpdir, cancellable, error)) goto out; last_deploy_path = g_build_filename ("/ostree", deploy_target, NULL); mkinitramfs_args = g_ptr_array_new (); /* Note: the hardcoded /tmp path below is not actually a * security flaw, because we've bind-mounted dracut's view * of /tmp to the securely-created tmpdir above. */ ot_ptrarray_add_many (mkinitramfs_args, "linux-user-chroot", "--mount-readonly", "/", "--mount-proc", "/proc", "--mount-bind", "/dev", "/dev", "--mount-bind", "/ostree/var", "/var", "--mount-bind", ot_gfile_get_path_cached (tmpdir), "/tmp", "--mount-bind", "/ostree/modules", "/lib/modules", last_deploy_path, "dracut", "-f", "/tmp/initramfs-ostree.img", release, NULL); g_ptr_array_add (mkinitramfs_args, NULL); g_print ("Generating initramfs using %s...\n", last_deploy_path); if (!ot_spawn_sync_checked (NULL, (char**)mkinitramfs_args->pdata, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, error)) goto out; initramfs_tmp_file = g_file_get_child (tmpdir, "initramfs-ostree.img"); initramfs_tmp_info = g_file_query_info (initramfs_tmp_file, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!initramfs_tmp_info) goto out; if (g_file_info_get_size (initramfs_tmp_info) == 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Initramfs generation failed, check dracut.log"); goto out; } if (!g_file_copy (initramfs_tmp_file, initramfs_file, 0, cancellable, NULL, NULL, error)) goto out; g_print ("Created: %s\n", ot_gfile_get_path_cached (initramfs_file)); (void) ot_gfile_unlink (initramfs_tmp_file, NULL, NULL); (void) rmdir (ot_gfile_get_path_cached (tmpdir)); } ret = TRUE; out: return ret; }