Merge branch 'edera-dev:main' into chore/fmt

This commit is contained in:
Khionu Sybiern 2024-06-27 15:35:44 -07:00 committed by GitHub
commit c849c3a63f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 472 additions and 106 deletions

47
.github/workflows/oci-distribution.yml vendored Normal file
View File

@ -0,0 +1,47 @@
name: OCI distribution
on:
workflow_dispatch:
schedule:
- cron: "0 10 * * *"
permissions:
contents: read
packages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
component:
- kratactl
- kratad
- kratanet
name: OCI build ${{ matrix.component }} on ${{ matrix.platform }}
steps:
- uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
with:
egress-policy: audit
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
submodules: recursive
- uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
- uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
- uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@15560696de535e4014efeff63c48f16952e52dd1 # v6.2.0
id: push-step
with:
file: ./images/Dockerfile.${{ matrix.component }}
platforms: linux/amd64,linux/aarch64
tags: ghcr.io/edera-dev/${{ matrix.component }}:nightly
push: true
- name: Sign the image
env:
DIGEST: ${{ steps.push-step.outputs.digest }}
TAGS: ghcr.io/edera-dev/${{ matrix.component }}:nightly
COSIGN_EXPERIMENTAL: "true"
run: cosign sign --yes "${TAGS}@${DIGEST}"

View File

@ -17,7 +17,7 @@ jobs:
- uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
with:
egress-policy: audit
- uses: actions/create-github-app-token@c8f55efbd427e7465d6da1106e7979bc8aaee856 # v1.10.1
- uses: actions/create-github-app-token@ad38cffc07bac6e3857755914c4c88bfd2db4da4 # v1.10.2
id: generate-token
with:
app-id: "${{ secrets.EDERA_CULTIVATION_APP_ID }}"

112
Cargo.lock generated
View File

@ -249,26 +249,6 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bindgen"
version = "0.69.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
dependencies = [
"bitflags 2.5.0",
"cexpr",
"clang-sys",
"itertools",
"lazy_static",
"lazycell",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn 2.0.57",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@ -365,15 +345,6 @@ dependencies = [
"libc",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -411,17 +382,6 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da987586004ae7c43b7df5e3f7693775068522e1086f8d9b2d74c778a0f43313"
[[package]]
name = "clang-sys"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "4.5.7"
@ -1027,12 +987,6 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "h2"
version = "0.3.26"
@ -1526,6 +1480,13 @@ dependencies = [
"tokio",
]
[[package]]
name = "krata-loopdev"
version = "0.0.11"
dependencies = [
"libc",
]
[[package]]
name = "krata-network"
version = "0.0.11"
@ -1587,6 +1548,7 @@ dependencies = [
"ipnetwork",
"krata",
"krata-advmac",
"krata-loopdev",
"krata-oci",
"krata-xenclient",
"krata-xenevtchn",
@ -1594,7 +1556,6 @@ dependencies = [
"krata-xenplatform",
"krata-xenstore",
"log",
"loopdev-3",
"serde_json",
"tokio",
"uuid",
@ -1708,28 +1669,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libloading"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
dependencies = [
"cfg-if",
"windows-targets 0.52.4",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.13"
@ -1752,17 +1697,6 @@ version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "loopdev-3"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90a97d7a5124296ee9124a815acdc3dc4a91f577b72812b3f1f99bb959b46e8d"
dependencies = [
"bindgen",
"errno",
"libc",
]
[[package]]
name = "lru"
version = "0.12.3"
@ -1807,12 +1741,6 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.7.2"
@ -1952,16 +1880,6 @@ dependencies = [
"libc",
]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "ntapi"
version = "0.4.1"
@ -2706,9 +2624,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.117"
version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4"
dependencies = [
"itoa",
"ryu",
@ -2773,12 +2691,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook"
version = "0.3.17"
@ -3404,9 +3316,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.9.0"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ea73390fe27785838dcbf75b91b1d84799e28f1ce71e6f372a5dc2200c80de5"
checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
dependencies = [
"getrandom",
]

View File

@ -71,7 +71,7 @@ redb = "2.1.1"
regex = "1.10.5"
rtnetlink = "0.14.1"
scopeguard = "1.2.0"
serde_json = "1.0.117"
serde_json = "1.0.118"
serde_yaml = "0.9"
sha256 = "1.5.0"
signal-hook = "0.3.17"
@ -123,7 +123,7 @@ version = "0.11.0"
features = ["tls"]
[workspace.dependencies.uuid]
version = "1.9.0"
version = "1.9.1"
features = ["v4"]
[profile.release]

15
crates/loopdev/Cargo.toml Normal file
View File

@ -0,0 +1,15 @@
[package]
name = "krata-loopdev"
description = "Loop device handling library for krata"
license.workspace = true
version.workspace = true
homepage.workspace = true
repository.workspace = true
edition = "2021"
resolver = "2"
[lib]
name = "krataloopdev"
[dependencies]
libc.workspace = true

354
crates/loopdev/src/lib.rs Normal file
View File

@ -0,0 +1,354 @@
use libc::{c_int, ioctl};
use std::{
fs::{File, OpenOptions},
io,
os::fd::{AsRawFd, IntoRawFd, RawFd},
os::unix::fs::MetadataExt,
path::{Path, PathBuf},
};
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
type IoctlRequest = libc::c_ulong;
#[cfg(any(target_os = "android", target_env = "musl"))]
type IoctlRequest = libc::c_int;
const LOOP_CONTROL: &str = "/dev/loop-control";
const LOOP_PREFIX: &str = "/dev/loop";
/// Loop control interface IOCTLs.
const LOOP_CTL_GET_FREE: IoctlRequest = 0x4C82;
/// Loop device flags.
const LO_FLAGS_READ_ONLY: u32 = 1;
const LO_FLAGS_AUTOCLEAR: u32 = 4;
const LO_FLAGS_PARTSCAN: u32 = 8;
const LO_FLAGS_DIRECT_IO: u32 = 16;
/// Loop device IOCTLs.
const LOOP_SET_FD: IoctlRequest = 0x4C00;
const LOOP_CLR_FD: IoctlRequest = 0x4C01;
const LOOP_SET_STATUS64: IoctlRequest = 0x4C04;
const LOOP_SET_CAPACITY: IoctlRequest = 0x4C07;
const LOOP_SET_DIRECT_IO: IoctlRequest = 0x4C08;
/// Interface which wraps a handle to the loop control device.
#[derive(Debug)]
pub struct LoopControl {
dev_file: File,
}
/// Translate ioctl results to errors if appropriate.
fn translate_error(ret: i32) -> io::Result<i32> {
if ret < 0 {
Err(io::Error::last_os_error())
} else {
Ok(ret)
}
}
impl LoopControl {
/// Open the loop control device.
///
/// # Errors
///
/// Any errors from physically opening the loop control device are
/// bubbled up.
pub fn open() -> io::Result<Self> {
Ok(Self {
dev_file: OpenOptions::new()
.read(true)
.write(true)
.open(LOOP_CONTROL)?,
})
}
/// Requests the next available loop device from the kernel and opens it.
///
/// # Examples
///
/// ```no_run
/// use krataloopdev::LoopControl;
/// let lc = LoopControl::open().unwrap();
/// let ld = lc.next_free().unwrap();
/// println!("{}", ld.path().unwrap().display());
/// ```
///
/// # Errors
///
/// Any errors from opening the loop device are bubbled up.
pub fn next_free(&self) -> io::Result<LoopDevice> {
let dev_num = translate_error(unsafe {
ioctl(
self.dev_file.as_raw_fd() as c_int,
LOOP_CTL_GET_FREE as IoctlRequest,
)
})?;
LoopDevice::open(format!("{}{}", LOOP_PREFIX, dev_num))
}
}
/// Interface to a loop device itself, e.g. `/dev/loop0`.
#[derive(Debug)]
pub struct LoopDevice {
device: File,
}
impl AsRawFd for LoopDevice {
fn as_raw_fd(&self) -> RawFd {
self.device.as_raw_fd()
}
}
impl IntoRawFd for LoopDevice {
fn into_raw_fd(self) -> RawFd {
self.device.into_raw_fd()
}
}
impl LoopDevice {
/// Opens a loop device.
///
/// # Errors
///
/// Any errors from opening the underlying physical loop device are bubbled up.
pub fn open<P: AsRef<Path>>(dev: P) -> io::Result<Self> {
Ok(Self {
device: OpenOptions::new().read(true).write(true).open(dev)?,
})
}
/// Attach a loop device to a file with the given options.
pub fn with(&self) -> AttachOptions<'_> {
AttachOptions {
device: self,
info: LoopInfo64::default(),
}
}
/// Enables or disables Direct I/O mode.
pub fn set_direct_io(&self, direct_io: bool) -> io::Result<()> {
translate_error(unsafe {
ioctl(
self.device.as_raw_fd() as c_int,
LOOP_SET_DIRECT_IO as IoctlRequest,
if direct_io { 1 } else { 0 },
)
})?;
Ok(())
}
/// Attach the loop device to a fully-mapped file.
pub fn attach_file<P: AsRef<Path>>(&self, backing_file: P) -> io::Result<()> {
let info = LoopInfo64 {
..Default::default()
};
Self::attach_with_loop_info(self, backing_file, info)
}
/// Attach the loop device to a file with `LoopInfo64`.
fn attach_with_loop_info(
&self,
backing_file: impl AsRef<Path>,
info: LoopInfo64,
) -> io::Result<()> {
let write_access = (info.lo_flags & LO_FLAGS_READ_ONLY) == 0;
let bf = OpenOptions::new()
.read(true)
.write(write_access)
.open(backing_file)?;
self.attach_fd_with_loop_info(bf, info)
}
/// Attach the loop device to a file descriptor with `LoopInfo64`.
fn attach_fd_with_loop_info(&self, bf: impl AsRawFd, info: LoopInfo64) -> io::Result<()> {
translate_error(unsafe {
ioctl(
self.device.as_raw_fd() as c_int,
LOOP_SET_FD as IoctlRequest,
bf.as_raw_fd() as c_int,
)
})?;
let result = unsafe {
ioctl(
self.device.as_raw_fd() as c_int,
LOOP_SET_STATUS64 as IoctlRequest,
&info,
)
};
match translate_error(result) {
Err(err) => {
let _detach_err = self.detach();
Err(err)
}
Ok(_) => Ok(()),
}
}
/// Get the path for the loop device.
pub fn path(&self) -> Option<PathBuf> {
let mut p = PathBuf::from("/proc/self/fd");
p.push(self.device.as_raw_fd().to_string());
std::fs::read_link(&p).ok()
}
/// Detach a loop device.
pub fn detach(&self) -> io::Result<()> {
translate_error(unsafe {
ioctl(
self.device.as_raw_fd() as c_int,
LOOP_CLR_FD as IoctlRequest,
0,
)
})?;
Ok(())
}
/// Update a loop device's capacity.
pub fn set_capacity(&self) -> io::Result<()> {
translate_error(unsafe {
ioctl(
self.device.as_raw_fd() as c_int,
LOOP_SET_CAPACITY as IoctlRequest,
0,
)
})?;
Ok(())
}
/// Return the major device node number.
pub fn major(&self) -> io::Result<u32> {
self.device
.metadata()
.map(|m| unsafe { libc::major(m.rdev()) })
.map(|m| m as u32)
}
/// Return the minor device node number.
pub fn minor(&self) -> io::Result<u32> {
self.device
.metadata()
.map(|m| unsafe { libc::minor(m.rdev()) })
.map(|m| m as u32)
}
}
#[allow(dead_code)]
#[derive(Clone)]
pub struct LoopInfo64 {
lo_device: u64,
lo_inode: u64,
lo_rdevice: u64,
lo_offset: u64,
lo_sizelimit: u64,
lo_number: u32,
lo_encrypt_type: u32,
lo_encrypt_key_size: u32,
lo_flags: u32,
lo_file_name: [u8; 64],
lo_crypt_name: [u8; 64],
lo_encrypt_key: [u8; 32],
lo_init: [u64; 2],
}
impl Default for LoopInfo64 {
fn default() -> Self {
Self {
lo_device: 0,
lo_inode: 0,
lo_rdevice: 0,
lo_offset: 0,
lo_sizelimit: 0,
lo_number: 0,
lo_encrypt_type: 0,
lo_encrypt_key_size: 0,
lo_flags: 0,
lo_file_name: [0; 64],
lo_crypt_name: [0; 64],
lo_encrypt_key: [0; 32],
lo_init: [0, 2],
}
}
}
#[must_use]
pub struct AttachOptions<'d> {
device: &'d LoopDevice,
info: LoopInfo64,
}
impl AttachOptions<'_> {
pub fn offset(mut self, offset: u64) -> Self {
self.info.lo_offset = offset;
self
}
pub fn size_limit(mut self, size_limit: u64) -> Self {
self.info.lo_sizelimit = size_limit;
self
}
pub fn read_only(mut self, read_only: bool) -> Self {
if read_only {
self.info.lo_flags |= LO_FLAGS_READ_ONLY;
} else {
self.info.lo_flags &= !LO_FLAGS_READ_ONLY;
}
self
}
pub fn autoclear(mut self, autoclear: bool) -> Self {
if autoclear {
self.info.lo_flags |= LO_FLAGS_AUTOCLEAR;
} else {
self.info.lo_flags &= !LO_FLAGS_AUTOCLEAR;
}
self
}
pub fn part_scan(mut self, part_scan: bool) -> Self {
if part_scan {
self.info.lo_flags |= LO_FLAGS_PARTSCAN;
} else {
self.info.lo_flags &= !LO_FLAGS_PARTSCAN;
}
self
}
pub fn set_direct_io(mut self, direct_io: bool) -> Self {
if direct_io {
self.info.lo_flags |= LO_FLAGS_DIRECT_IO;
} else {
self.info.lo_flags &= !LO_FLAGS_DIRECT_IO;
}
self
}
pub fn direct_io(&self) -> bool {
if (self.info.lo_flags & LO_FLAGS_DIRECT_IO) == LO_FLAGS_DIRECT_IO {
true
} else {
false
}
}
pub fn attach(&self, backing_file: impl AsRef<Path>) -> io::Result<()> {
self.device
.attach_with_loop_info(backing_file, self.info.clone())?;
if self.direct_io() {
self.device.set_direct_io(self.direct_io())?;
}
Ok(())
}
pub fn attach_fd(&self, backing_file_fd: impl AsRawFd) -> io::Result<()> {
self.device
.attach_fd_with_loop_info(backing_file_fd, self.info.clone())?;
if self.direct_io() {
self.device.set_direct_io(self.direct_io())?;
}
Ok(())
}
}

View File

@ -16,10 +16,10 @@ krata = { path = "../krata", version = "^0.0.11" }
krata-advmac = { workspace = true }
krata-oci = { path = "../oci", version = "^0.0.11" }
log = { workspace = true }
loopdev-3 = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
uuid = { workspace = true }
krata-loopdev = { path = "../loopdev", version = "^0.0.11" }
krata-xenclient = { path = "../xen/xenclient", version = "^0.0.11" }
krata-xenevtchn = { path = "../xen/xenevtchn", version = "^0.0.11" }
krata-xengnt = { path = "../xen/xengnt", version = "^0.0.11" }

View File

@ -1,8 +1,8 @@
use std::{sync::Arc, time::Duration};
use anyhow::{anyhow, Result};
use krataloopdev::{LoopControl, LoopDevice};
use log::debug;
use loopdev::{LoopControl, LoopDevice};
use tokio::time::sleep;
use xenclient::BlockDeviceRef;

View File

@ -3,8 +3,8 @@ use std::{fs, net::Ipv4Addr, path::PathBuf, str::FromStr, sync::Arc};
use anyhow::{anyhow, Result};
use ip::IpVendor;
use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
use krataloopdev::LoopControl;
use log::error;
use loopdev::LoopControl;
use tokio::sync::Semaphore;
use uuid::Uuid;
use xenclient::XenClient;

View File

@ -0,0 +1,12 @@
FROM rust:1.79-alpine AS build
RUN apk update && apk add protoc protobuf-dev build-base && rm -rf /var/cache/apk/*
ENV TARGET_LIBC=musl TARGET_VENDOR=unknown
WORKDIR /usr/src/app
COPY . .
RUN ./hack/build/cargo.sh build --release --bin kratactl
RUN mv ./target/$(./hack/build/target.sh)/release/kratactl /usr/sbin
FROM cgr.dev/chainguard/static AS final
ENTRYPOINT ["/usr/sbin/kratactl"]
COPY --from=build /usr/sbin/kratactl /usr/sbin/kratactl

13
images/Dockerfile.kratad Normal file
View File

@ -0,0 +1,13 @@
FROM rust:1.79-alpine AS build
RUN apk update && apk add protoc protobuf-dev build-base && rm -rf /var/cache/apk/*
ENV TARGET_LIBC=musl TARGET_VENDOR=unknown
WORKDIR /usr/src/app
COPY . .
RUN ./hack/build/cargo.sh build --release --bin kratad
RUN mv ./target/$(./hack/build/target.sh)/release/kratad /usr/sbin
FROM cgr.dev/chainguard/static AS final
ENTRYPOINT ["/usr/sbin/kratad"]
COPY --from=build /usr/sbin/kratad /usr/sbin/kratad
COPY ./resources/systemd/kratad.service /usr/lib/systemd/system/kratad.service

View File

@ -0,0 +1,13 @@
FROM rust:1.79-alpine AS build
RUN apk update && apk add protoc protobuf-dev build-base && rm -rf /var/cache/apk/*
ENV TARGET_LIBC=musl TARGET_VENDOR=unknown
WORKDIR /usr/src/app
COPY . .
RUN ./hack/build/cargo.sh build --release --bin kratanet
RUN mv ./target/$(./hack/build/target.sh)/release/kratanet /usr/sbin
FROM cgr.dev/chainguard/static AS final
ENTRYPOINT ["/usr/sbin/kratanet"]
COPY --from=build /usr/sbin/kratanet /usr/sbin/kratanet
COPY ./resources/systemd/kratanet.service /usr/lib/systemd/system/kratanet.service