Merge pull request #4866 from Megan-Wright/CCv0

CCv0: Merge main into CCv0 branch
This commit is contained in:
Fabiano Fidêncio 2022-08-11 15:04:12 +02:00 committed by GitHub
commit 72691ed6af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 255 additions and 152 deletions

View File

@ -60,17 +60,26 @@ This section lists items that might be possible to fix.
## OCI CLI commands
### Docker and Podman support
Currently Kata Containers does not support Docker or Podman.
Currently Kata Containers does not support Podman.
See issue https://github.com/kata-containers/kata-containers/issues/722 for more information.
Docker supports Kata Containers since 22.06:
```bash
$ sudo docker run --runtime io.containerd.kata.v2
```
Kata Containers works perfectly with containerd, we recommend to use
containerd's Docker-style command line tool [`nerdctl`](https://github.com/containerd/nerdctl).
## Runtime commands
### checkpoint and restore
The runtime does not provide `checkpoint` and `restore` commands. There
are discussions about using VM save and restore to give us a
`[criu](https://github.com/checkpoint-restore/criu)`-like functionality,
[`criu`](https://github.com/checkpoint-restore/criu)-like functionality,
which might provide a solution.
Note that the OCI standard does not specify `checkpoint` and `restore`
@ -93,6 +102,42 @@ All other configurations are supported and are working properly.
## Networking
### Host network
Host network (`nerdctl/docker run --net=host`or [Kubernetes `HostNetwork`](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#hosts-namespaces)) is not supported.
It is not possible to directly access the host networking configuration
from within the VM.
The `--net=host` option can still be used with `runc` containers and
inter-mixed with running Kata Containers, thus enabling use of `--net=host`
when necessary.
It should be noted, currently passing the `--net=host` option into a
Kata Container may result in the Kata Container networking setup
modifying, re-configuring and therefore possibly breaking the host
networking setup. Do not use `--net=host` with Kata Containers.
### Support for joining an existing VM network
Docker supports the ability for containers to join another containers
namespace with the `docker run --net=containers` syntax. This allows
multiple containers to share a common network namespace and the network
interfaces placed in the network namespace. Kata Containers does not
support network namespace sharing. If a Kata Container is setup to
share the network namespace of a `runc` container, the runtime
effectively takes over all the network interfaces assigned to the
namespace and binds them to the VM. Consequently, the `runc` container loses
its network connectivity.
### docker run --link
The runtime does not support the `docker run --link` command. This
command is now deprecated by docker and we have no intention of adding support.
Equivalent functionality can be achieved with the newer docker networking commands.
See more documentation at
[docs.docker.com](https://docs.docker.com/network/links/).
## Resource management
Due to the way VMs differ in their CPU and memory allocation, and sharing

View File

@ -18,16 +18,13 @@ CONFIG_X86_SGX_KVM=y
* Kubernetes cluster configured with:
* [`kata-deploy`](../../tools/packaging/kata-deploy) based Kata Containers installation
* [Intel SGX Kubernetes device plugin](https://github.com/intel/intel-device-plugins-for-kubernetes/tree/main/cmd/sgx_plugin#deploying-with-pre-built-images)
* [Intel SGX Kubernetes device plugin](https://github.com/intel/intel-device-plugins-for-kubernetes/tree/main/cmd/sgx_plugin#deploying-with-pre-built-images) and associated components including [operator](https://github.com/intel/intel-device-plugins-for-kubernetes/blob/main/cmd/operator/README.md) and dependencies
> Note: Kata Containers supports creating VM sandboxes with Intel® SGX enabled
> using [cloud-hypervisor](https://github.com/cloud-hypervisor/cloud-hypervisor/) and [QEMU](https://www.qemu.org/) VMMs only.
### Kata Containers Configuration
Before running a Kata Container make sure that your version of `crio` or `containerd`
supports annotations.
For `containerd` check in `/etc/containerd/config.toml` that the list of `pod_annotations` passed
to the `sandbox` are: `["io.katacontainers.*", "sgx.intel.com/epc"]`.
@ -99,4 +96,4 @@ because socket passthrough is not supported. An alternative is to deploy the `ae
container.
* Projects like [Gramine Shielded Containers (GSC)](https://gramine-gsc.readthedocs.io/en/latest/) are
also known to work. For GSC specifically, the Kata guest kernel needs to have the `CONFIG_NUMA=y`
enabled and at least one CPU online when running the GSC container.
enabled and at least one CPU online when running the GSC container. The Kata Containers guest kernel currently has `CONFIG_NUMA=y` enabled by default.

82
src/agent/Cargo.lock generated
View File

@ -123,9 +123,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.60"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"
checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8"
[[package]]
name = "arc-swap"
@ -1426,9 +1426,9 @@ dependencies = [
[[package]]
name = "iana-time-zone"
version = "0.1.41"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1779539f58004e5dba1c1f093d44325ebeb244bfc04b791acdc0aaeca9c04570"
checksum = "9512e544c25736b82aebbd2bf739a47c8a1c935dfcc3a6adcde10e35cd3cd468"
dependencies = [
"android_system_properties",
"core-foundation",
@ -1660,8 +1660,8 @@ dependencies = [
"libc",
"log",
"logging",
"netlink-packet-utils",
"netlink-sys",
"netlink-packet-utils 0.4.1",
"netlink-sys 0.7.0",
"nix 0.23.1",
"oci",
"openssl",
@ -1758,9 +1758,9 @@ dependencies = [
[[package]]
name = "libm"
version = "0.2.4"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7ce35d4899fa3c0558d4f5082c98927789a01024270711cf113999b66ced65a"
checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565"
[[package]]
name = "libseccomp"
@ -1934,28 +1934,28 @@ dependencies = [
[[package]]
name = "netlink-packet-core"
version = "0.2.4"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac48279d5062bdf175bdbcb6b58ff1d6b0ecd54b951f7a0ff4bc0550fe903ccb"
checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297"
dependencies = [
"anyhow",
"byteorder",
"libc",
"netlink-packet-utils",
"netlink-packet-utils 0.5.1",
]
[[package]]
name = "netlink-packet-route"
version = "0.8.0"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76aed5d3b6e3929713bf1e1334a11fd65180b6d9f5d7c8572664c48b122604f8"
checksum = "f5dee5ed749373c298237fe694eb0a51887f4cc1a27370c8464bac4382348f1a"
dependencies = [
"anyhow",
"bitflags",
"byteorder",
"libc",
"netlink-packet-core",
"netlink-packet-utils",
"netlink-packet-utils 0.5.1",
]
[[package]]
@ -1971,18 +1971,30 @@ dependencies = [
]
[[package]]
name = "netlink-proto"
version = "0.7.0"
name = "netlink-packet-utils"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd06e90449ae973fe3888c1ff85949604ef5189b4ac9a2ae39518da1e00762d"
checksum = "25af9cf0dc55498b7bd94a1508af7a78706aa0ab715a73c5169273e03c84845e"
dependencies = [
"anyhow",
"byteorder",
"paste",
"thiserror",
]
[[package]]
name = "netlink-proto"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6"
dependencies = [
"bytes 1.1.0",
"futures",
"log",
"netlink-packet-core",
"netlink-sys",
"netlink-sys 0.8.3",
"thiserror",
"tokio",
"tokio-util 0.6.10",
]
[[package]]
@ -1997,6 +2009,19 @@ dependencies = [
"tokio",
]
[[package]]
name = "netlink-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92b654097027250401127914afb37cb1f311df6610a9891ff07a757e94199027"
dependencies = [
"bytes 1.1.0",
"futures",
"libc",
"log",
"tokio",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
@ -2016,19 +2041,6 @@ dependencies = [
"void",
]
[[package]]
name = "nix"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf"
dependencies = [
"bitflags",
"cc",
"cfg-if 1.0.0",
"libc",
"memoffset",
]
[[package]]
name = "nix"
version = "0.23.1"
@ -2989,15 +3001,15 @@ dependencies = [
[[package]]
name = "rtnetlink"
version = "0.8.1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c9a6200d18ec1acfc218ce71363dcc9b6075f399220f903fdfeacd476a876ef"
checksum = "46f1cfa18f8cebe685373a2697915d7e0db3b4554918bba118385e0f71f258a7"
dependencies = [
"futures",
"log",
"netlink-packet-route",
"netlink-proto",
"nix 0.22.3",
"nix 0.24.2",
"thiserror",
"tokio",
]

View File

@ -33,7 +33,7 @@ tokio = { version = "1.14.0", features = ["full"] }
tokio-vsock = "0.3.1"
netlink-sys = { version = "0.7.0", features = ["tokio_socket",]}
rtnetlink = "0.8.0"
rtnetlink = "0.11.0"
netlink-packet-utils = "0.4.1"
ipnetwork = "0.17.0"

View File

@ -4,7 +4,7 @@
//
use anyhow::{anyhow, Context, Result};
use futures::{future, StreamExt, TryStreamExt};
use futures::{future, TryStreamExt};
use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
use nix::errno::Errno;
use protobuf::RepeatedField;
@ -164,7 +164,7 @@ impl Handle {
let request = self.handle.link().get();
let filtered = match filter {
LinkFilter::Name(name) => request.set_name_filter(name.to_owned()),
LinkFilter::Name(name) => request.match_name(name.to_owned()),
LinkFilter::Index(index) => request.match_index(index),
_ => request, // Post filters
};
@ -516,7 +516,6 @@ impl Handle {
}
/// Adds an ARP neighbor.
/// TODO: `rtnetlink` has no neighbours API, remove this after https://github.com/little-dude/netlink/pull/135
async fn add_arp_neighbor(&mut self, neigh: &ARPNeighbor) -> Result<()> {
let ip_address = neigh
.toIPAddress
@ -528,58 +527,13 @@ impl Handle {
let ip = IpAddr::from_str(ip_address)
.map_err(|e| anyhow!("Failed to parse IP {}: {:?}", ip_address, e))?;
// Import rtnetlink objects that make sense only for this function
use packet::constants::{NDA_UNSPEC, NLM_F_ACK, NLM_F_CREATE, NLM_F_EXCL, NLM_F_REQUEST};
use packet::neighbour::{NeighbourHeader, NeighbourMessage};
use packet::nlas::neighbour::Nla;
use packet::{NetlinkMessage, NetlinkPayload, RtnlMessage};
use rtnetlink::Error;
const IFA_F_PERMANENT: u16 = 0x80; // See https://github.com/little-dude/netlink/blob/0185b2952505e271805902bf175fee6ea86c42b8/netlink-packet-route/src/rtnl/constants.rs#L770
let link = self.find_link(LinkFilter::Name(&neigh.device)).await?;
let message = NeighbourMessage {
header: NeighbourHeader {
family: match ip {
IpAddr::V4(_) => packet::AF_INET,
IpAddr::V6(_) => packet::AF_INET6,
} as u8,
ifindex: link.index(),
state: if neigh.state != 0 {
neigh.state as u16
} else {
IFA_F_PERMANENT
},
flags: neigh.flags as u8,
ntype: NDA_UNSPEC as u8,
},
nlas: {
let mut nlas = vec![Nla::Destination(match ip {
IpAddr::V4(v4) => v4.octets().to_vec(),
IpAddr::V6(v6) => v6.octets().to_vec(),
})];
if !neigh.lladdr.is_empty() {
nlas.push(Nla::LinkLocalAddress(
parse_mac_address(&neigh.lladdr)?.to_vec(),
));
}
nlas
},
};
// Send request and ACK
let mut req = NetlinkMessage::from(RtnlMessage::NewNeighbour(message));
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
let mut response = self.handle.request(req)?;
while let Some(message) = response.next().await {
if let NetlinkPayload::Error(err) = message.payload {
return Err(anyhow!(Error::NetlinkError(err)));
}
}
self.handle
.neighbours()
.add(link.index(), ip)
.execute()
.await?;
Ok(())
}
@ -950,7 +904,7 @@ mod tests {
.expect("prepare: failed to delete neigh");
}
fn prepare_env_for_test_add_one_arp_neighbor(dummy_name: &str, ip: &str) {
fn prepare_env_for_test_add_one_arp_neighbor(dummy_name: &str, ip: &str, mac: &str) {
clean_env_for_test_add_one_arp_neighbor(dummy_name, ip);
// modprobe dummy
Command::new("modprobe")
@ -964,6 +918,12 @@ mod tests {
.output()
.expect("failed to add dummy interface");
// ip link set dummy address 6a:92:3a:59:70:aa
Command::new("ip")
.args(&["link", "set", dummy_name, "address", mac])
.output()
.expect("failed to add dummy interface");
// ip addr add 192.168.0.2/16 dev dummy
Command::new("ip")
.args(&["addr", "add", "192.168.0.2/16", "dev", dummy_name])
@ -985,7 +945,7 @@ mod tests {
let to_ip = "169.254.1.1";
let dummy_name = "dummy_for_arp";
prepare_env_for_test_add_one_arp_neighbor(dummy_name, to_ip);
prepare_env_for_test_add_one_arp_neighbor(dummy_name, to_ip, mac);
let mut ip_address = IPAddress::new();
ip_address.set_address(to_ip.to_string());

View File

@ -2014,11 +2014,13 @@ func (k *kataAgent) sendReq(spanCtx context.Context, request interface{}) (inter
k.Lock()
if k.reqHandlers == nil {
k.Unlock()
return nil, errors.New("Client has already disconnected")
}
handler := k.reqHandlers[msgName]
if msgName == "" || handler == nil {
k.Unlock()
return nil, errors.New("Invalid request type")
}

View File

@ -1056,7 +1056,7 @@ func (q *qemu) StopVM(ctx context.Context, waitOnly bool) error {
if err == nil {
scanner := bufio.NewScanner(f)
for scanner.Scan() {
q.Logger().Debug(scanner.Text())
q.Logger().WithField("file", q.qemuConfig.LogFile).Debug(scanner.Text())
}
if err := scanner.Err(); err != nil {
q.Logger().WithError(err).Debug("read qemu log failed")

View File

@ -39,3 +39,5 @@ humantime = "2.1.0"
# For Options (state passing)
serde = { version = "1.0.131", features = ["derive"] }
serde_json = "1.0.73"
[workspace]

View File

@ -503,11 +503,7 @@ mod tests {
let root = tempdir().unwrap();
// let bundle = temp
let id = "test".to_string();
create_activated_dirs(
&root.path().to_path_buf(),
&id,
&bundle_dir.path().to_path_buf(),
);
create_activated_dirs(root.path(), &id, bundle_dir.path());
let pid = getpid().as_raw();
let mut spec = create_dummy_spec();
@ -517,7 +513,7 @@ mod tests {
.to_string_lossy()
.to_string();
let status = create_dummy_status(&id, pid, &root.path().to_path_buf(), &spec);
let status = create_dummy_status(&id, pid, root.path(), &spec);
status.save().unwrap();
let result = ActivatedContainerBuilder::default()
@ -600,13 +596,9 @@ mod tests {
.join(TEST_ROOTFS_PATH)
.to_string_lossy()
.to_string();
create_activated_dirs(
&root.path().to_path_buf(),
&id,
&bundle_dir.path().to_path_buf(),
);
create_activated_dirs(root.path(), &id, bundle_dir.path());
let status = create_dummy_status(&id, pid, &root.path().to_path_buf(), &spec);
let status = create_dummy_status(&id, pid, root.path(), &spec);
status.save().unwrap();
let launcher = ActivatedContainerBuilder::default()
.id(id)

View File

@ -3,9 +3,14 @@
// SPDX-License-Identifier: Apache-2.0
//
use crate::status::Status;
use crate::status::{self, get_all_pid, get_current_container_state, Status};
use anyhow::{anyhow, Result};
use nix::unistd::{chdir, unlink};
use nix::sys::signal::kill;
use nix::{
sys::signal::Signal,
unistd::{chdir, unlink, Pid},
};
use oci::ContainerState;
use rustjail::{
container::{BaseContainer, LinuxContainer, EXEC_FIFO_FILENAME},
process::{Process, ProcessOperations},
@ -26,6 +31,47 @@ pub enum ContainerAction {
Run,
}
#[derive(Debug)]
pub struct Container {
pub status: Status,
pub state: ContainerState,
}
impl Container {
pub fn load(state_root: &Path, id: &str) -> Result<Self> {
let status = Status::load(state_root, id)?;
let state = get_current_container_state(&status)?;
Ok(Self { status, state })
}
pub fn processes(&self) -> Result<Vec<Pid>> {
get_all_pid(&self.status.cgroup_manager)
}
pub fn kill(&self, signal: Signal, all: bool) -> Result<()> {
if all {
let pids = self.processes()?;
for pid in pids {
if !status::is_process_running(pid)? {
continue;
}
kill(pid, signal)?;
}
} else {
if self.state == ContainerState::Stopped {
return Err(anyhow!("container {} not running", self.status.id));
}
let pid = Pid::from_raw(self.status.pid);
if status::is_process_running(pid)? {
kill(pid, signal)?;
}
}
Ok(())
}
// TODO: add pause and resume
}
/// Used to run a process. If init is set, it will create a container and run the process in it.
/// If init is not set, it will run the process in an existing container.
#[derive(Debug)]

View File

@ -4,44 +4,22 @@
//
use crate::Kill;
use anyhow::{anyhow, Result};
use libcontainer::status::{self, get_current_container_state, Status};
use nix::{
sys::signal::{kill, Signal},
unistd::Pid,
};
use oci::ContainerState;
use anyhow::Result;
use libcontainer::container::Container;
use nix::sys::signal::Signal;
use slog::{info, Logger};
use std::{convert::TryFrom, path::Path, str::FromStr};
pub fn run(opts: Kill, state_root: &Path, logger: &Logger) -> Result<()> {
let container_id = &opts.container_id;
let status = Status::load(state_root, container_id)?;
let current_state = get_current_container_state(&status)?;
let container = Container::load(state_root, container_id)?;
let sig = parse_signal(&opts.signal)?;
// TODO: liboci-cli does not support --all option for kill command.
// After liboci-cli supports the option, we will change the following code.
// as a workaround we use a custom Kill command.
let all = opts.all;
if all {
let pids = status::get_all_pid(&status.cgroup_manager)?;
for pid in pids {
if !status::is_process_running(pid)? {
continue;
}
kill(pid, sig)?;
}
} else {
if current_state == ContainerState::Stopped {
return Err(anyhow!("container {} not running", container_id));
}
let p = Pid::from_raw(status.pid);
if status::is_process_running(p)? {
kill(p, sig)?;
}
}
container.kill(sig, all)?;
info!(&logger, "kill command finished successfully");

View File

@ -8,6 +8,7 @@ pub mod delete;
pub mod exec;
pub mod kill;
pub mod list;
pub mod ps;
pub mod run;
pub mod spec;
pub mod start;

View File

@ -0,0 +1,63 @@
// Copyright 2021-2022 Kata Contributors
//
// SPDX-License-Identifier: Apache-2.0
//
use anyhow::anyhow;
use anyhow::Result;
use libcontainer::container::Container;
use liboci_cli::Ps;
use slog::{info, Logger};
use std::path::Path;
use std::process::Command;
use std::str;
pub fn run(opts: Ps, root: &Path, logger: &Logger) -> Result<()> {
let container = Container::load(root, opts.container_id.as_str())?;
let pids = container
.processes()?
.iter()
.map(|pid| pid.as_raw())
.collect::<Vec<_>>();
match opts.format.as_str() {
"json" => println!("{}", serde_json::to_string(&pids)?),
"table" => {
let ps_options = if opts.ps_options.is_empty() {
vec!["-ef".to_string()]
} else {
opts.ps_options
};
let output = Command::new("ps").args(ps_options).output()?;
if !output.status.success() {
return Err(anyhow!("{}", std::str::from_utf8(&output.stderr)?));
}
let lines = str::from_utf8(&output.stdout)?.lines().collect::<Vec<_>>();
if lines.is_empty() {
return Err(anyhow!("no processes found"));
}
let pid_index = lines[0]
.split_whitespace()
.position(|field| field == "PID")
.ok_or_else(|| anyhow!("could't find PID field in ps output"))?;
println!("{}", lines[0]);
for &line in &lines[1..] {
if line.is_empty() {
continue;
}
let fields = line.split_whitespace().collect::<Vec<_>>();
if pid_index >= fields.len() {
continue;
}
let pid: i32 = fields[pid_index].parse()?;
if pids.contains(&pid) {
println!("{}", line);
}
}
}
_ => return Err(anyhow!("unknown format: {}", opts.format)),
}
info!(&logger, "ps command finished successfully");
Ok(())
}

View File

@ -80,6 +80,7 @@ async fn cmd_run(subcmd: SubCommand, root_path: &Path, logger: &Logger) -> Resul
CommonCmd::Spec(spec) => commands::spec::run(spec, logger),
CommonCmd::List(list) => commands::list::run(list, root_path, logger),
CommonCmd::Exec(exec) => commands::exec::run(exec, root_path, logger).await,
CommonCmd::Ps(ps) => commands::ps::run(ps, root_path, logger),
_ => {
return Err(anyhow!("command is not implemented yet"));
}

View File

@ -1,13 +1,17 @@
# Intel Trust Domain Extensions (Intel TDX)
CONFIG_CLK_LGM_CGU=y
CONFIG_DMA_RESTRICTED_POOL=y
CONFIG_EFI=y
CONFIG_EFI_STUB=y
CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
CONFIG_INTEL_TDX_GUEST=y
CONFIG_INTEL_IOMMU_SVM=y
CONFIG_INTEL_TDX_ATTESTATION=y
CONFIG_INTEL_TDX_FIXES=y
CONFIG_X86_MEM_ENCRYPT_COMMON=y
CONFIG_X86_5LEVEL=y
CONFIG_INTEL_TDX_GUEST=y
CONFIG_OF=y
CONFIG_CLK_LGM_CGU=y
CONFIG_OF_RESERVED_MEM=y
CONFIG_DMA_RESTRICTED_POOL=y
CONFIG_X86_5LEVEL=y
CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
CONFIG_X86_MEM_ENCRYPT_COMMON=y
CONFIG_X86_PLATFORM_DEVICES=y
CONFIG_X86_PLATFORM_DRIVERS_INTEL=y

View File

@ -1 +1 @@
93
94

View File

@ -101,7 +101,7 @@ assets:
tdx:
description: "VMM that uses KVM and supports TDX"
url: "https://github.com/intel/qemu-dcp"
tag: "SPR-BKC-QEMU-v2.2"
tag: "SPR-BKC-QEMU-v2.5"
qemu-experimental:
description: "QEMU with virtiofs support"
@ -154,8 +154,8 @@ assets:
version: "v5.15.48"
tdx:
description: "Linux kernel that supports TDX"
url: "https://github.com/intel/tdx/archive/refs/tags"
tag: "tdx-guest-v5.15-4"
url: "https://github.com/intel/linux-kernel-dcp/archive/refs/tags"
tag: "SPR-BKC-PC-v9.6"
sev:
description: "Linux kernel with efi_secret support"
url: "https://github.com/confidential-containers-demo/\
@ -284,8 +284,8 @@ externals:
td-shim:
description: "Confidential Containers Shim Firmware"
url: "https://github.com/confidential-containers/td-shim"
version: "5f62a0e367b1845a54e534d103ed4a697a599ac3"
toolchain: "nightly-2022-04-07"
version: "cf9592ef70bd6ba4c7ab1330d278a743f5ba3133"
toolchain: "nightly-2022-05-15"
virtiofsd:
description: "vhost-user virtio-fs device backend written in Rust"