Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Still need to handle write new ostree ref in deploy_transaction_execute()
  • Loading branch information
kelvinfan001 committed Jun 30, 2021
1 parent 726ec79 commit 8691fe4
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 26 deletions.
7 changes: 7 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ pub mod ffi {
fn cliwrap_destdir() -> String;
}

// sysroot_upgrade.rs
extern "Rust" {
fn import_container(sysroot: Pin<&mut OstreeSysroot>, imgref: String) -> Result<String>;
}

// core.rs
extern "Rust" {
type TempEtcGuard;
Expand Down Expand Up @@ -583,6 +588,8 @@ pub(crate) use self::console_progress::*;
mod progress;
mod scripts;
pub(crate) use self::scripts::*;
mod sysroot_upgrade;
pub(crate) use crate::sysroot_upgrade::*;
mod rpmutils;
pub(crate) use self::rpmutils::*;
mod testutils;
Expand Down
28 changes: 28 additions & 0 deletions rust/src/sysroot_upgrade.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Rust portion of `rpmostree-sysroot-upgrader.cxx`.
// SPDX-License-Identifier: Apache-2.0 OR MIT

use crate::cxxrsutil::*;
use anyhow::{Context, Result};
use std::convert::TryInto;
use std::pin::Pin;

/// Import ostree commit in container image using ostree-rs-ext's API.
pub fn import_container(
mut sysroot: Pin<&mut crate::FFIOstreeSysroot>,
imgref: String,
) -> Result<String> {
let sysroot = &sysroot.gobj_wrap();
let repo = &sysroot.get_repo(gio::NONE_CANCELLABLE)?;
let imgref = imgref.as_str().try_into()?;
let commit = build_runtime()?
.block_on(async { ostree_ext::container::import(&repo, &imgref, None).await })?;
Ok(commit.ostree_commit)
}

fn build_runtime() -> Result<tokio::runtime::Runtime> {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.context("Failed to build tokio runtime")
}
5 changes: 5 additions & 0 deletions src/app/rpmostree-builtin-rebase.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ rpmostree_builtin_rebase (int argc,
if (strlen (new_provided_refspec) == 0)
return glnx_throw (error, "Refspec is empty");

/* When using the container refspec type, if rebasing to a specific commit, we expect a
* specific digest tag in the refspec, not in a separate argument */
if (revision && refspectype == RPMOSTREE_REFSPEC_TYPE_CONTAINER)
return glnx_throw (error, "Unexpected ostree revision alongside container refspec type");

/* Check if remote refers to a local repo */
g_autofree char *local_repo_remote = NULL;
if (G_IN_SET (refspectype, RPMOSTREE_REFSPEC_TYPE_OSTREE,
Expand Down
11 changes: 9 additions & 2 deletions src/app/rpmostree-builtin-status.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -559,14 +559,17 @@ print_one_deployment (RPMOSTreeSysroot *sysroot_proxy,
return TRUE;

const gchar *origin_refspec;
RpmOstreeRefspecType refspectype = RPMOSTREE_REFSPEC_TYPE_OSTREE;
g_autofree const gchar **origin_packages = NULL;
g_autofree const gchar **origin_requested_packages = NULL;
g_autofree const gchar **origin_requested_local_packages = NULL;
g_autoptr(GVariant) origin_base_removals = NULL;
g_autofree const gchar **origin_requested_base_removals = NULL;
g_autoptr(GVariant) origin_base_local_replacements = NULL;
g_autofree const gchar **origin_requested_base_local_replacements = NULL;
if (g_variant_dict_lookup (dict, "origin", "&s", &origin_refspec))
if (g_variant_dict_lookup (dict, "ostree-refspec", "&s", &origin_refspec) ||
g_variant_dict_lookup (dict, "ostree-checksum", "&s", &origin_refspec) ||
g_variant_dict_lookup (dict, "container-image-reference", "&s", &origin_refspec))
{
origin_packages =
lookup_array_and_canonicalize (dict, "packages");
Expand Down Expand Up @@ -606,7 +609,6 @@ print_one_deployment (RPMOSTreeSysroot *sysroot_proxy,

g_print ("%s ", is_booted ? libsd_special_glyph (BLACK_CIRCLE) : " ");

RpmOstreeRefspecType refspectype = RPMOSTREE_REFSPEC_TYPE_OSTREE;
const char *custom_origin_url = NULL;
const char *custom_origin_description = NULL;
if (origin_refspec)
Expand Down Expand Up @@ -637,6 +639,11 @@ print_one_deployment (RPMOSTreeSysroot *sysroot_proxy,
g_print ("%s", origin_refspec);
}
break;
case RPMOSTREE_REFSPEC_TYPE_CONTAINER:
{
g_print ("%s", origin_refspec);
}
break;
}
}
else
Expand Down
10 changes: 10 additions & 0 deletions src/daemon/rpmostree-sysroot-upgrader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,16 @@ rpmostree_sysroot_upgrader_pull_base (RpmOstreeSysrootUpgrader *self,

switch (refspec_type)
{
case RPMOSTREE_REFSPEC_TYPE_CONTAINER:
{
if (override_commit)
return glnx_throw (error, "Specifying commit overrides for container-image-reference type refspecs is not supported");

auto commit = rpmostreecxx::import_container(*self->sysroot, std::string(refspec));

new_base_rev = strdup (commit.c_str());
break;
}
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
{
Expand Down
9 changes: 6 additions & 3 deletions src/daemon/rpmostreed-deployment-utils.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ rpmostreed_deployment_generate_variant (OstreeSysroot *sysroot,

RpmOstreeRefspecType refspec_type;
g_autofree char *refspec = rpmostree_origin_get_full_refspec (origin, &refspec_type);
g_assert (refspec);

gboolean is_layered = FALSE;
g_autofree char *base_checksum = NULL;
Expand Down Expand Up @@ -301,8 +302,12 @@ rpmostreed_deployment_generate_variant (OstreeSysroot *sysroot,

switch (refspec_type)
{
case RPMOSTREE_REFSPEC_TYPE_CONTAINER:
g_variant_dict_insert (dict, "container-image-reference", "s", refspec);
break;
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
{
g_variant_dict_insert (dict, "ostree-checksum", "s", refspec);
g_autofree char *custom_origin_url = NULL;
g_autofree char *custom_origin_description = NULL;
rpmostree_origin_get_custom_description (origin, &custom_origin_url,
Expand All @@ -315,6 +320,7 @@ rpmostreed_deployment_generate_variant (OstreeSysroot *sysroot,
break;
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
{
g_variant_dict_insert (dict, "ostree-refspec", "s", refspec);
if (!variant_add_remote_status (repo, refspec, base_checksum, dict, error))
return NULL;

Expand All @@ -339,9 +345,6 @@ rpmostreed_deployment_generate_variant (OstreeSysroot *sysroot,
break;
}

if (refspec)
g_variant_dict_insert (dict, "origin", "s", refspec);

variant_add_from_hash_table (dict, "requested-packages",
rpmostree_origin_get_packages (origin));
variant_add_from_hash_table (dict, "requested-local-packages",
Expand Down
44 changes: 42 additions & 2 deletions src/daemon/rpmostreed-transaction-types.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,37 @@ change_origin_refspec (GVariantDict *options,
gchar **out_new_refspec,
GError **error)
{
RpmOstreeRefspecType refspectype;
if (!rpmostree_refspec_classify (refspec, &refspectype, error))
return FALSE;

RpmOstreeRefspecType current_refspectype;
g_autofree gchar *current_refspec = rpmostree_origin_get_full_refspec (origin, &current_refspectype);


switch (refspectype)
{
case RPMOSTREE_REFSPEC_TYPE_CONTAINER:
{
if (!rpmostree_origin_set_rebase (origin, refspec, error))
return FALSE;

if (current_refspectype == RPMOSTREE_REFSPEC_TYPE_CONTAINER
&& strcmp (current_refspec, refspec) == 0)
return glnx_throw (error, "Old and new refs are equal: %s", refspec);

if (out_old_refspec != NULL)
*out_old_refspec = current_refspec;
if (out_new_refspec != NULL)
*out_new_refspec = g_strdup (refspec);
return TRUE;
}
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
break;
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
break;
}

/* The rest of the code assumes TYPE_OSTREE refspec */
g_autofree gchar *new_refspec = NULL;
if (!rpmostreed_refspec_parse_partial (refspec,
current_refspec,
Expand Down Expand Up @@ -149,7 +177,12 @@ apply_revision_override (RpmostreedTransaction *transaction,
rpmostree_origin_classify_refspec (origin, &refspectype, NULL);

if (refspectype == RPMOSTREE_REFSPEC_TYPE_CHECKSUM)
return glnx_throw (error, "Cannot look up version while pinned to commit");
return glnx_throw (error, "Cannot look up version/checksum while pinned to commit");

if (refspectype == RPMOSTREE_REFSPEC_TYPE_CONTAINER)
/* NB: Not supported for now, but We can perhaps support this if we allow `revision` to
* possibly be a tag or digest */
return glnx_throw (error, "Cannot look up version/checksum while tracking a container image reference");

g_autofree char *checksum = NULL;
g_autofree char *version = NULL;
Expand All @@ -160,6 +193,8 @@ apply_revision_override (RpmostreedTransaction *transaction,
{
switch (refspectype)
{
case RPMOSTREE_REFSPEC_TYPE_CONTAINER:
g_assert_not_reached (); /* Handled above */
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
{
/* Perhaps down the line we'll drive history traversal into libostree */
Expand All @@ -183,6 +218,8 @@ apply_revision_override (RpmostreedTransaction *transaction,

switch (refspectype)
{
case RPMOSTREE_REFSPEC_TYPE_CONTAINER:
g_assert_not_reached (); /* Handled above */
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
if (!skip_branch_check)
{
Expand Down Expand Up @@ -1486,6 +1523,9 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
{
g_autofree char *remote = NULL;
g_autofree char *ref = NULL;

/* TODO: Handle `container-image-reference` refspectype. Currently, a new OSTree ref is not
* written if refspecdata is e.g. `registry:quay.io/fcos` */

/* The actual rebase has already succeeded, so ignore errors. */
if (ostree_parse_refspec (old_refspec, &remote, &ref, NULL))
Expand Down
23 changes: 23 additions & 0 deletions src/libpriv/rpmostree-core.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@

static OstreeRepo * get_pkgcache_repo (RpmOstreeContext *self);

/* Infer whether refspec if is a container image reference.
* Currently, we are simply relying on the fact that there
* cannot be multiple colons in TYPE_OSTREE or TYPE_COMMIT. */
static gboolean
is_container_image_reference (const char *refspec)
{
const char *first_colon = NULL;
first_colon = strchr (refspec, ':');
if (first_colon != NULL)
{
const char *second_colon = NULL;
second_colon = strchr (first_colon + 1, ':');
if (second_colon != NULL)
return TRUE;
}
return FALSE;
}

/* Given a string, infer its type and return it in `out_type`.
* Could be either an ostree refspec (TYPE_OSTREE)
* or a bare commit (TYPE_COMMIT).
Expand All @@ -59,6 +77,11 @@ rpmostree_refspec_classify (const char *refspec,
RpmOstreeRefspecType *out_type,
GError **error)
{
if (is_container_image_reference (refspec))
{
*out_type = RPMOSTREE_REFSPEC_TYPE_CONTAINER;
return TRUE;
}
/* Fall back to TYPE_OSTREE if we cannot infer type */
*out_type = RPMOSTREE_REFSPEC_TYPE_OSTREE;
if (ostree_validate_checksum_string (refspec, NULL))
Expand Down
5 changes: 5 additions & 0 deletions src/libpriv/rpmostree-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ G_DECLARE_FINAL_TYPE (RpmOstreeTreespec, rpmostree_treespec, RPMOSTREE, TREESPEC
typedef enum {
RPMOSTREE_REFSPEC_TYPE_OSTREE,
RPMOSTREE_REFSPEC_TYPE_CHECKSUM,
RPMOSTREE_REFSPEC_TYPE_CONTAINER,
} RpmOstreeRefspecType;

#define RPMOSTREE_REFSPEC_OSTREE_ORIGIN_KEY "refspec"
#define RPMOSTREE_REFSPEC_OSTREE_BASE_ORIGIN_KEY "baserefspec"
#define RPMOSTREE_REFSPEC_CONTAINER_ORIGIN_KEY "container-image-reference"

gboolean rpmostree_refspec_classify (const char *refspec,
RpmOstreeRefspecType *out_type,
GError **error);
Expand Down
Loading

0 comments on commit 8691fe4

Please sign in to comment.