gboolean
_ostree_sysroot_list_deployment_dirs_for_os (GFile               *osdir,
        GPtrArray           *inout_deployments,
        GCancellable        *cancellable,
        GError             **error)
{
    gboolean ret = FALSE;
    const char *osname = gs_file_get_basename_cached (osdir);
    gs_unref_object GFileEnumerator *dir_enum = NULL;
    gs_unref_object GFile *osdeploy_dir = NULL;
    GError *temp_error = NULL;

    osdeploy_dir = g_file_get_child (osdir, "deploy");

    dir_enum = g_file_enumerate_children (osdeploy_dir, OSTREE_GIO_FAST_QUERYINFO,
                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                          NULL, &temp_error);
    if (!dir_enum)
    {
        if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
            g_clear_error (&temp_error);
            goto done;
        }
        else
        {
            g_propagate_error (error, temp_error);
            goto out;
        }
    }

    while (TRUE)
    {
        const char *name;
        GFileInfo *file_info = NULL;
        GFile *child = NULL;
        gs_unref_object OstreeDeployment *deployment = NULL;
        gs_free char *csum = NULL;
        gint deployserial;

        if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
                                         cancellable, error))
            goto out;
        if (file_info == NULL)
            break;

        name = g_file_info_get_name (file_info);

        if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
            continue;

        if (!_ostree_sysroot_parse_deploy_path_name (name, &csum, &deployserial, error))
            goto out;

        deployment = ostree_deployment_new (-1, osname, csum, deployserial, NULL, -1);
        g_ptr_array_add (inout_deployments, g_object_ref (deployment));
    }

done:
    ret = TRUE;
out:
    return ret;
}
Beispiel #2
0
static gboolean
parse_deployment (OstreeSysroot       *self,
                  const char          *boot_link,
                  OstreeDeployment   **out_deployment,
                  GCancellable        *cancellable,
                  GError             **error)
{
  gboolean ret = FALSE;
  const char *relative_boot_link;
  glnx_unref_object OstreeDeployment *ret_deployment = NULL;
  int entry_boot_version;
  int treebootserial = -1;
  int deployserial = -1;
  g_autofree char *osname = NULL;
  g_autofree char *bootcsum = NULL;
  g_autofree char *treecsum = NULL;
  glnx_fd_close int deployment_dfd = -1;
  const char *deploy_basename;
  g_autofree char *treebootserial_target = NULL;
  g_autofree char *deploy_dir = NULL;
  GKeyFile *origin = NULL;

  if (!ensure_sysroot_fd (self, error))
    goto out;
      
  if (!parse_bootlink (boot_link, &entry_boot_version,
                       &osname, &bootcsum, &treebootserial,
                       error))
    goto out;

  relative_boot_link = boot_link;
  if (*relative_boot_link == '/')
    relative_boot_link++;

  treebootserial_target = glnx_readlinkat_malloc (self->sysroot_fd, relative_boot_link,
                                                  cancellable, error);
  if (!treebootserial_target)
    goto out;

  deploy_basename = glnx_basename (treebootserial_target);

  if (!_ostree_sysroot_parse_deploy_path_name (deploy_basename,
                                               &treecsum, &deployserial, error))
    goto out;

  if (!glnx_opendirat (self->sysroot_fd, relative_boot_link, TRUE,
                       &deployment_dfd, error))
    goto out;

  if (!parse_origin (self, deployment_dfd, deploy_basename, &origin,
                     cancellable, error))
    goto out;

  ret_deployment = ostree_deployment_new (-1, osname, treecsum, deployserial,
                                          bootcsum, treebootserial);
  if (origin)
    ostree_deployment_set_origin (ret_deployment, origin);

  ret = TRUE;
  gs_transfer_out_value (out_deployment, &ret_deployment);
 out:
  if (origin)
    g_key_file_unref (origin);
  return ret;
}