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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}