Update to ostree-ext v0.1.2, add new ex-container
command
This new `rpm-ostree ex-container` CLI is just code copied from the `ostree-ext-cli container` binary code. In the future I may just add the CLI code as a library API too to simplify this. For now, I don't want to try to add a new Rust CLI as an RPM package for example. This exposes it via rpm-ostree, and in the future rpm-ostree may have some layering on top of this anyways.
This commit is contained in:
parent
38c25bfb75
commit
54a011df40
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1532,6 +1532,7 @@ dependencies = [
|
||||
"env_logger",
|
||||
"envsubst",
|
||||
"fn-error-context",
|
||||
"futures",
|
||||
"gio",
|
||||
"gio-sys",
|
||||
"glib",
|
||||
@ -1566,6 +1567,7 @@ dependencies = [
|
||||
"system-deps 3.1.1",
|
||||
"systemd",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
@ -35,6 +35,7 @@ cxx = "1.0.49"
|
||||
envsubst = "0.2.0"
|
||||
env_logger = "0.8.3"
|
||||
fn-error-context = "0.1.2"
|
||||
futures = "0.3.15"
|
||||
gio = "0.9.1"
|
||||
gio-sys = "0.10.1"
|
||||
gobject-sys = "0.10.0"
|
||||
@ -70,6 +71,7 @@ systemd = "0.8.2"
|
||||
tempfile = "3.2.0"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = "0.2"
|
||||
tokio = { version = "1.6.0", features = ["full"] }
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0"
|
||||
|
104
rust/src/container.rs
Normal file
104
rust/src/container.rs
Normal file
@ -0,0 +1,104 @@
|
||||
//! CLI exposing `ostree-rs-ext container`
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
enum Opts {
|
||||
/// Import an ostree commit embedded in a remote container image
|
||||
Import {
|
||||
/// Path to the repository
|
||||
#[structopt(long)]
|
||||
repo: String,
|
||||
|
||||
/// Image reference, e.g. registry:quay.io/exampleos/exampleos:latest
|
||||
imgref: String,
|
||||
},
|
||||
|
||||
/// Print information about an exported ostree-container image.
|
||||
Info {
|
||||
/// Image reference, e.g. registry:quay.io/exampleos/exampleos:latest
|
||||
imgref: String,
|
||||
},
|
||||
|
||||
/// Export an ostree commit to an OCI layout
|
||||
Export {
|
||||
/// Path to the repository
|
||||
#[structopt(long)]
|
||||
repo: String,
|
||||
|
||||
/// The ostree ref or commit to export
|
||||
rev: String,
|
||||
|
||||
/// Image reference, e.g. registry:quay.io/exampleos/exampleos:latest
|
||||
imgref: String,
|
||||
},
|
||||
}
|
||||
|
||||
async fn container_import(repo: &str, imgref: &str) -> Result<()> {
|
||||
let repo = &ostree::Repo::open_at(libc::AT_FDCWD, repo, gio::NONE_CANCELLABLE)?;
|
||||
let imgref = imgref.try_into()?;
|
||||
let (tx_progress, rx_progress) = tokio::sync::watch::channel(Default::default());
|
||||
let target = indicatif::ProgressDrawTarget::stdout();
|
||||
let style = indicatif::ProgressStyle::default_bar();
|
||||
let pb = indicatif::ProgressBar::new_spinner();
|
||||
pb.set_draw_target(target);
|
||||
pb.set_style(style.template("{spinner} {prefix} {msg}"));
|
||||
pb.enable_steady_tick(200);
|
||||
pb.set_message("Downloading...");
|
||||
let import = ostree_ext::container::import(repo, &imgref, Some(tx_progress));
|
||||
tokio::pin!(import);
|
||||
tokio::pin!(rx_progress);
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = rx_progress.changed() => {
|
||||
let n = rx_progress.borrow().processed_bytes;
|
||||
pb.set_message(&format!("Processed: {}", indicatif::HumanBytes(n)));
|
||||
}
|
||||
import = &mut import => {
|
||||
pb.finish();
|
||||
println!("Imported: {}", import?.ostree_commit);
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn container_export(repo: &str, rev: &str, imgref: &str) -> Result<()> {
|
||||
let repo = &ostree::Repo::open_at(libc::AT_FDCWD, repo, gio::NONE_CANCELLABLE)?;
|
||||
let imgref = imgref.try_into()?;
|
||||
let pushed = ostree_ext::container::export(repo, rev, &imgref).await?;
|
||||
println!("{}", pushed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn container_info(imgref: &str) -> Result<()> {
|
||||
let imgref = imgref.try_into()?;
|
||||
let info = ostree_ext::container::fetch_manifest_info(&imgref).await?;
|
||||
println!("{} @{}", imgref, info.manifest_digest);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Main entrypoint for container
|
||||
pub fn entrypoint(args: &[&str]) -> Result<()> {
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.context("Failed to build tokio runtime")?
|
||||
.block_on(async {
|
||||
match Opts::from_iter(args.iter().skip(1)) {
|
||||
Opts::Import { repo, imgref } => {
|
||||
container_import(repo.as_str(), imgref.as_str()).await
|
||||
}
|
||||
Opts::Info { imgref } => container_info(imgref.as_str()).await,
|
||||
Opts::Export { repo, rev, imgref } => {
|
||||
container_export(repo.as_str(), rev.as_str(), imgref.as_str()).await
|
||||
}
|
||||
}
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
@ -519,6 +519,7 @@ pub(crate) use bwrap::*;
|
||||
mod client;
|
||||
pub(crate) use client::*;
|
||||
mod cliwrap;
|
||||
pub mod container;
|
||||
pub use cliwrap::*;
|
||||
mod composepost;
|
||||
pub mod countme;
|
||||
|
@ -7,6 +7,7 @@ fn inner_main(args: &Vec<&str>) -> Result<()> {
|
||||
match args.get(1).map(|s| *s) {
|
||||
// Add custom Rust commands here, and also in `libmain.cxx` if user-visible.
|
||||
Some("countme") => rpmostree_rust::countme::entrypoint(args),
|
||||
Some("ex-container") => rpmostree_rust::container::entrypoint(args),
|
||||
_ => {
|
||||
// Otherwise fall through to C++ main().
|
||||
Ok(rpmostree_rust::ffi::rpmostree_main(&args)?)
|
||||
|
37
tests/kolainst/destructive/ex-container
Executable file
37
tests/kolainst/destructive/ex-container
Executable file
@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (C) 2021 Red Hat Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
. ${KOLA_EXT_DATA}/libtest.sh
|
||||
|
||||
set -x
|
||||
|
||||
libtest_prepare_offline
|
||||
|
||||
booted_commit=$(rpm-ostree status --json | jq -r '.deployments[0].checksum')
|
||||
rpm-ostree ex-container export --repo=/ostree/repo ${booted_commit} containers-storage:localhost/fcos
|
||||
target_sha256=$(podman run --entrypoint bash --rm -i localhost/fcos -c 'sha256sum /usr/bin/rpm-ostree' | cut -f 1 -d ' ')
|
||||
src_sha256=$(sha256sum /usr/bin/rpm-ostree | cut -f 1 -d ' ')
|
||||
assert_streq "${src_sha256}" "${target_sha256}"
|
||||
echo "ok container export"
|
||||
|
||||
# TODO test container import too, ideally via registry. But I don't want to
|
||||
# make this test super flaky right now by pulling from the internet, and
|
||||
# we need infrastructure to mock up serving via local registry.
|
Loading…
Reference in New Issue
Block a user