mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-20 00:48:04 +00:00
Merge pull request #6104 from stevenhorsman/remove-skopeo-umoci
CC: Remove skopeo umoci
This commit is contained in:
commit
d3547814e5
@ -68,7 +68,7 @@ $ chmod u+x ccv0.sh
|
|||||||
- Configure Kata to use containerd and for debug and confidential containers features to be enabled (including
|
- Configure Kata to use containerd and for debug and confidential containers features to be enabled (including
|
||||||
enabling console access to the Kata guest shell, which should only be done in development)
|
enabling console access to the Kata guest shell, which should only be done in development)
|
||||||
- Create, build and install a rootfs for the Kata hypervisor to use. For 'CCv0' this is currently based on Ubuntu
|
- Create, build and install a rootfs for the Kata hypervisor to use. For 'CCv0' this is currently based on Ubuntu
|
||||||
20.04 and has extra packages like `umoci` added.
|
20.04.
|
||||||
- Build the Kata guest kernel
|
- Build the Kata guest kernel
|
||||||
- Install the hypervisor (in order to select which hypervisor will be used, the `KATA_HYPERVISOR` environment
|
- Install the hypervisor (in order to select which hypervisor will be used, the `KATA_HYPERVISOR` environment
|
||||||
variable can be used to select between `qemu` or `cloud-hypervisor`)
|
variable can be used to select between `qemu` or `cloud-hypervisor`)
|
||||||
@ -176,8 +176,6 @@ there.
|
|||||||
```
|
```
|
||||||
total 72
|
total 72
|
||||||
-rw-r--r-- 1 root root 2977 Jan 20 10:03 config.json
|
-rw-r--r-- 1 root root 2977 Jan 20 10:03 config.json
|
||||||
-rw-r--r-- 1 root root 372 Jan 20 10:03 umoci.json
|
|
||||||
-rw-r--r-- 1 root root 63584 Jan 20 10:03 sha256_be9faa75035c20288cde7d2cdeb6cd1f5f4dbcd845d3f86f7feab61c4eff9eb5.mtree
|
|
||||||
drwxr-xr-x 12 root root 240 Jan 20 10:03 rootfs
|
drwxr-xr-x 12 root root 240 Jan 20 10:03 rootfs
|
||||||
```
|
```
|
||||||
which shows how the image has been pulled and then unbundled on the guest.
|
which shows how the image has been pulled and then unbundled on the guest.
|
||||||
@ -279,8 +277,6 @@ the `ccv0.sh` script to automatically fill in the variables:
|
|||||||
total 72
|
total 72
|
||||||
drwxr-xr-x 10 root root 200 Jan 1 1970 rootfs
|
drwxr-xr-x 10 root root 200 Jan 1 1970 rootfs
|
||||||
-rw-r--r-- 1 root root 2977 Jan 20 16:45 config.json
|
-rw-r--r-- 1 root root 2977 Jan 20 16:45 config.json
|
||||||
-rw-r--r-- 1 root root 372 Jan 20 16:45 umoci.json
|
|
||||||
-rw-r--r-- 1 root root 63584 Jan 20 16:45 sha256_be9faa75035c20288cde7d2cdeb6cd1f5f4dbcd845d3f86f7feab61c4eff9eb5.mtree
|
|
||||||
```
|
```
|
||||||
- Leave the Kata shell by running:
|
- Leave the Kata shell by running:
|
||||||
```bash
|
```bash
|
||||||
@ -301,9 +297,9 @@ In our test repository there are three tagged images:
|
|||||||
|
|
||||||
| Test Image | Base Image used | Signature status | GPG key status |
|
| Test Image | Base Image used | Signature status | GPG key status |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `quay.io/kata-containers/confidential-containers:signed` | `busybox:1.33.1` | [signature](https://github.com/kata-containers/tests/tree/CCv0/integration/confidential/fixtures/quay_verification/signatures.tar) embedded in kata rootfs | [public key](https://github.com/kata-containers/tests/tree/CCv0/integration/confidential/fixtures/quay_verification/public.gpg) embedded in kata rootfs |
|
| `quay.io/kata-containers/confidential-containers:signed` | `busybox:1.33.1` | [signature](https://github.com/kata-containers/tests/tree/CCv0/integration/confidential/fixtures/quay_verification/x86_64/signatures.tar) embedded in kata rootfs | [public key](https://github.com/kata-containers/tests/tree/CCv0/integration/confidential/fixtures/quay_verification/x86_64/public.gpg) embedded in kata rootfs |
|
||||||
| `quay.io/kata-containers/confidential-containers:unsigned` | `busybox:1.33.1` | not signed | not signed |
|
| `quay.io/kata-containers/confidential-containers:unsigned` | `busybox:1.33.1` | not signed | not signed |
|
||||||
| `quay.io/kata-containers/confidential-containers:other_signed` | `nginx:1.21.3` | [signature](https://github.com/kata-containers/tests/tree/CCv0/integration/confidential/fixtures/quay_verification/signatures.tar) embedded in kata rootfs | GPG key not kept |
|
| `quay.io/kata-containers/confidential-containers:other_signed` | `nginx:1.21.3` | [signature](https://github.com/kata-containers/tests/tree/CCv0/integration/confidential/fixtures/quay_verification/x86_64/signatures.tar) embedded in kata rootfs | GPG key not kept |
|
||||||
|
|
||||||
Using a standard unsigned `busybox` image that can be pulled from another, *unprotected*, `quay.io` repository we can
|
Using a standard unsigned `busybox` image that can be pulled from another, *unprotected*, `quay.io` repository we can
|
||||||
test a few scenarios.
|
test a few scenarios.
|
||||||
|
@ -26,7 +26,6 @@ const LOG_VPORT_OPTION: &str = "agent.log_vport";
|
|||||||
const CONTAINER_PIPE_SIZE_OPTION: &str = "agent.container_pipe_size";
|
const CONTAINER_PIPE_SIZE_OPTION: &str = "agent.container_pipe_size";
|
||||||
const UNIFIED_CGROUP_HIERARCHY_OPTION: &str = "agent.unified_cgroup_hierarchy";
|
const UNIFIED_CGROUP_HIERARCHY_OPTION: &str = "agent.unified_cgroup_hierarchy";
|
||||||
const CONFIG_FILE: &str = "agent.config_file";
|
const CONFIG_FILE: &str = "agent.config_file";
|
||||||
const CONTAINER_POLICY_FILE: &str = "agent.container_policy_file";
|
|
||||||
const AA_KBC_PARAMS: &str = "agent.aa_kbc_params";
|
const AA_KBC_PARAMS: &str = "agent.aa_kbc_params";
|
||||||
const HTTPS_PROXY: &str = "agent.https_proxy";
|
const HTTPS_PROXY: &str = "agent.https_proxy";
|
||||||
const NO_PROXY: &str = "agent.no_proxy";
|
const NO_PROXY: &str = "agent.no_proxy";
|
||||||
@ -59,11 +58,6 @@ const ERR_INVALID_CONTAINER_PIPE_SIZE_PARAM: &str = "unable to parse container p
|
|||||||
const ERR_INVALID_CONTAINER_PIPE_SIZE_KEY: &str = "invalid container pipe size key name";
|
const ERR_INVALID_CONTAINER_PIPE_SIZE_KEY: &str = "invalid container pipe size key name";
|
||||||
const ERR_INVALID_CONTAINER_PIPE_NEGATIVE: &str = "container pipe size should not be negative";
|
const ERR_INVALID_CONTAINER_PIPE_NEGATIVE: &str = "container pipe size should not be negative";
|
||||||
|
|
||||||
const ERR_INVALID_CONTAINER_POLICY_PATH_VALUE: &str = "invalid container_policy_file value";
|
|
||||||
const ERR_INVALID_CONTAINER_POLICY_PATH_KEY: &str = "invalid container_policy_file key";
|
|
||||||
const ERR_INVALID_CONTAINER_POLICY_ABSOLUTE: &str =
|
|
||||||
"container_policy_file path must be an absolute file path";
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize)]
|
#[derive(Debug, Default, Deserialize)]
|
||||||
pub struct EndpointsConfig {
|
pub struct EndpointsConfig {
|
||||||
pub allowed: Vec<String>,
|
pub allowed: Vec<String>,
|
||||||
@ -327,13 +321,6 @@ impl AgentConfig {
|
|||||||
get_bool_value
|
get_bool_value
|
||||||
);
|
);
|
||||||
|
|
||||||
parse_cmdline_param!(
|
|
||||||
param,
|
|
||||||
CONTAINER_POLICY_FILE,
|
|
||||||
config.container_policy_path,
|
|
||||||
get_container_policy_path_value
|
|
||||||
);
|
|
||||||
|
|
||||||
parse_cmdline_param!(param, AA_KBC_PARAMS, config.aa_kbc_params, get_string_value);
|
parse_cmdline_param!(param, AA_KBC_PARAMS, config.aa_kbc_params, get_string_value);
|
||||||
parse_cmdline_param!(param, HTTPS_PROXY, config.https_proxy, get_url_value);
|
parse_cmdline_param!(param, HTTPS_PROXY, config.https_proxy, get_url_value);
|
||||||
parse_cmdline_param!(param, NO_PROXY, config.no_proxy, get_string_value);
|
parse_cmdline_param!(param, NO_PROXY, config.no_proxy, get_string_value);
|
||||||
@ -505,29 +492,6 @@ fn get_container_pipe_size(param: &str) -> Result<i32> {
|
|||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
|
||||||
fn get_container_policy_path_value(param: &str) -> Result<String> {
|
|
||||||
let fields: Vec<&str> = param.split('=').collect();
|
|
||||||
|
|
||||||
ensure!(!fields[0].is_empty(), ERR_INVALID_CONTAINER_POLICY_PATH_KEY);
|
|
||||||
ensure!(fields.len() == 2, ERR_INVALID_CONTAINER_POLICY_PATH_VALUE);
|
|
||||||
|
|
||||||
let key = fields[0];
|
|
||||||
ensure!(
|
|
||||||
key == CONTAINER_POLICY_FILE,
|
|
||||||
ERR_INVALID_CONTAINER_POLICY_PATH_KEY
|
|
||||||
);
|
|
||||||
|
|
||||||
let value = String::from(fields[1]);
|
|
||||||
ensure!(!value.is_empty(), ERR_INVALID_CONTAINER_POLICY_PATH_VALUE);
|
|
||||||
ensure!(
|
|
||||||
value.starts_with('/'),
|
|
||||||
ERR_INVALID_CONTAINER_POLICY_ABSOLUTE
|
|
||||||
);
|
|
||||||
ensure!(!value.contains(".."), ERR_INVALID_CONTAINER_POLICY_ABSOLUTE);
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
fn get_url_value(param: &str) -> Result<String> {
|
fn get_url_value(param: &str) -> Result<String> {
|
||||||
let value = get_string_value(param)?;
|
let value = get_string_value(param)?;
|
||||||
@ -968,11 +932,6 @@ mod tests {
|
|||||||
tracing: true,
|
tracing: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
TestData {
|
|
||||||
contents: "agent.container_policy_file=/etc/containers/policy.json",
|
|
||||||
container_policy_path: "/etc/containers/policy.json",
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
TestData {
|
TestData {
|
||||||
contents: "agent.aa_kbc_params=offline_fs_kbc::null",
|
contents: "agent.aa_kbc_params=offline_fs_kbc::null",
|
||||||
aa_kbc_params: "offline_fs_kbc::null",
|
aa_kbc_params: "offline_fs_kbc::null",
|
||||||
@ -1580,72 +1539,6 @@ Caused by:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_get_container_policy_path_value() {
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct TestData<'a> {
|
|
||||||
param: &'a str,
|
|
||||||
result: Result<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
let tests = &[
|
|
||||||
TestData {
|
|
||||||
param: "",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_PATH_KEY)),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.container_policy_file",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_PATH_VALUE)),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.container_policy_file=",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_PATH_VALUE)),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "foo=bar",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_PATH_KEY)),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.policy_path=/another/absolute/path.json",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_PATH_KEY)),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.container_policy_file=/etc/container/policy.json",
|
|
||||||
result: Ok("/etc/container/policy.json".into()),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.container_policy_file=/another/absolute/path.json",
|
|
||||||
result: Ok("/another/absolute/path.json".into()),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.container_policy_file=./relative/path.json",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_ABSOLUTE)),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.container_policy_file=./relative/path.json",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_ABSOLUTE)),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.container_policy_file=../../relative/path.json",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_ABSOLUTE)),
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
param: "agent.container_policy_file=junk_string",
|
|
||||||
result: Err(anyhow!(ERR_INVALID_CONTAINER_POLICY_ABSOLUTE)),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
for (i, d) in tests.iter().enumerate() {
|
|
||||||
let msg = format!("test[{}]: {:?}", i, d);
|
|
||||||
|
|
||||||
let result = get_container_policy_path_value(d.param);
|
|
||||||
|
|
||||||
let msg = format!("{}: result: {:?}", msg, result);
|
|
||||||
|
|
||||||
assert_result!(d.result, result, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_config_builder_from_string() {
|
fn test_config_builder_from_string() {
|
||||||
let config = AgentConfig::from_str(
|
let config = AgentConfig::from_str(
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
// Copyright (c) 2021 Alibaba Cloud
|
// Copyright (c) 2021 Alibaba Cloud
|
||||||
|
// Copyright (c) 2021, 2023 IBM Corporation
|
||||||
|
// Copyright (c) 2022 Intel Corporation
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt::Write as _;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::{Command, ExitStatus};
|
use std::process::Command;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::{anyhow, ensure, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use protocols::image;
|
use protocols::image;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
@ -24,9 +25,6 @@ use crate::AGENT_CONFIG;
|
|||||||
use image_rs::image::ImageClient;
|
use image_rs::image::ImageClient;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
const SKOPEO_PATH: &str = "/usr/bin/skopeo";
|
|
||||||
const UMOCI_PATH: &str = "/usr/local/bin/umoci";
|
|
||||||
const IMAGE_OCI: &str = "image_oci";
|
|
||||||
const AA_PATH: &str = "/usr/local/bin/attestation-agent";
|
const AA_PATH: &str = "/usr/local/bin/attestation-agent";
|
||||||
const AA_KEYPROVIDER_PORT: &str = "127.0.0.1:50000";
|
const AA_KEYPROVIDER_PORT: &str = "127.0.0.1:50000";
|
||||||
const AA_GETRESOURCE_PORT: &str = "127.0.0.1:50001";
|
const AA_GETRESOURCE_PORT: &str = "127.0.0.1:50001";
|
||||||
@ -59,95 +57,6 @@ impl ImageService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pull_image_from_registry(
|
|
||||||
image: &str,
|
|
||||||
cid: &str,
|
|
||||||
source_creds: Option<&str>,
|
|
||||||
policy_path: Option<&str>,
|
|
||||||
aa_kbc_params: &str,
|
|
||||||
) -> Result<()> {
|
|
||||||
let source_image = format!("{}{}", "docker://", image);
|
|
||||||
|
|
||||||
let tmp_cid_path = Path::new("/tmp/").join(cid);
|
|
||||||
let oci_path = tmp_cid_path.join(IMAGE_OCI);
|
|
||||||
let target_path_oci = format!("oci://{}:latest", oci_path.to_string_lossy());
|
|
||||||
|
|
||||||
fs::create_dir_all(&oci_path)?;
|
|
||||||
|
|
||||||
let mut pull_command = Command::new(SKOPEO_PATH);
|
|
||||||
pull_command
|
|
||||||
.arg("copy")
|
|
||||||
.arg(source_image)
|
|
||||||
.arg(&target_path_oci)
|
|
||||||
.arg("--remove-signatures"); //umoci requires signatures to be removed
|
|
||||||
|
|
||||||
// If source credentials were passed (so not using an anonymous registry), pass them through
|
|
||||||
if let Some(source_creds) = source_creds {
|
|
||||||
pull_command.arg("--src-creds").arg(source_creds);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a policy_path provided, use it, otherwise fall back to allow all image registries
|
|
||||||
if let Some(policy_path) = policy_path {
|
|
||||||
pull_command.arg("--policy").arg(policy_path);
|
|
||||||
} else {
|
|
||||||
info!(
|
|
||||||
sl!(),
|
|
||||||
"No policy path was supplied, so revert to allow all images to be pulled."
|
|
||||||
);
|
|
||||||
pull_command.arg("--insecure-policy");
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!(sl!(), "skopeo command: {:?}", &pull_command);
|
|
||||||
if !aa_kbc_params.is_empty() {
|
|
||||||
// Skopeo will copy an unencrypted image even if the decryption key argument is provided.
|
|
||||||
// Thus, this does not guarantee that the image was encrypted.
|
|
||||||
pull_command
|
|
||||||
.arg("--decryption-key")
|
|
||||||
.arg(format!("provider:attestation-agent:{}", aa_kbc_params))
|
|
||||||
.env("OCICRYPT_KEYPROVIDER_CONFIG", OCICRYPT_CONFIG_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
let status: ExitStatus = pull_command.status()?;
|
|
||||||
|
|
||||||
if !status.success() {
|
|
||||||
let mut error_message = format!("failed to pull image: {:?}", status);
|
|
||||||
|
|
||||||
if let Err(e) = fs::remove_dir_all(&tmp_cid_path) {
|
|
||||||
let _ = write!(
|
|
||||||
error_message,
|
|
||||||
" and clean up of temporary container directory {:?} failed with error {:?}",
|
|
||||||
tmp_cid_path, e
|
|
||||||
);
|
|
||||||
};
|
|
||||||
return Err(anyhow!(error_message));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unpack_image(cid: &str) -> Result<()> {
|
|
||||||
let tmp_cid_path = Path::new("/tmp/").join(cid);
|
|
||||||
let source_path_oci = tmp_cid_path.join(IMAGE_OCI);
|
|
||||||
|
|
||||||
let target_path_bundle = Path::new(CONTAINER_BASE).join(cid);
|
|
||||||
|
|
||||||
info!(sl!(), "unpack image {:?} to {:?}", cid, target_path_bundle);
|
|
||||||
|
|
||||||
// Unpack image
|
|
||||||
let status: ExitStatus = Command::new(UMOCI_PATH)
|
|
||||||
.arg("unpack")
|
|
||||||
.arg("--image")
|
|
||||||
.arg(&source_path_oci)
|
|
||||||
.arg(&target_path_bundle)
|
|
||||||
.status()?;
|
|
||||||
|
|
||||||
ensure!(status.success(), "failed to unpack image: {:?}", status);
|
|
||||||
|
|
||||||
// To save space delete the oci image after unpack
|
|
||||||
fs::remove_dir_all(&tmp_cid_path)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// pause image is packaged in rootfs for CC
|
// pause image is packaged in rootfs for CC
|
||||||
fn unpack_pause_image(cid: &str) -> Result<()> {
|
fn unpack_pause_image(cid: &str) -> Result<()> {
|
||||||
let cc_pause_bundle = Path::new(KATA_CC_PAUSE_BUNDLE);
|
let cc_pause_bundle = Path::new(KATA_CC_PAUSE_BUNDLE);
|
||||||
@ -174,7 +83,7 @@ impl ImageService {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we fail to start the AA, Skopeo/ocicrypt won't be able to unwrap keys
|
// If we fail to start the AA, ocicrypt won't be able to unwrap keys
|
||||||
// and container decryption will fail.
|
// and container decryption will fail.
|
||||||
fn init_attestation_agent() -> Result<()> {
|
fn init_attestation_agent() -> Result<()> {
|
||||||
let config_path = OCICRYPT_CONFIG_PATH;
|
let config_path = OCICRYPT_CONFIG_PATH;
|
||||||
@ -211,7 +120,7 @@ impl ImageService {
|
|||||||
let cid = if !req_cid.is_empty() {
|
let cid = if !req_cid.is_empty() {
|
||||||
req_cid.to_string()
|
req_cid.to_string()
|
||||||
} else if let Some(last) = req.get_image().rsplit('/').next() {
|
} else if let Some(last) = req.get_image().rsplit('/').next() {
|
||||||
// ':' have special meaning for umoci during upack
|
// ':' not valid for container id
|
||||||
last.replace(':', "_")
|
last.replace(':', "_")
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!("Invalid image name. {}", req.get_image()));
|
return Err(anyhow!("Invalid image name. {}", req.get_image()));
|
||||||
@ -235,9 +144,7 @@ impl ImageService {
|
|||||||
|
|
||||||
let cid = Self::cid_from_request(req)?;
|
let cid = Self::cid_from_request(req)?;
|
||||||
let image = req.get_image();
|
let image = req.get_image();
|
||||||
// Can switch to use cid directly when we remove umoci
|
if cid.starts_with("pause") {
|
||||||
let v: Vec<&str> = image.rsplit('/').collect();
|
|
||||||
if !v[0].is_empty() && v[0].starts_with("pause:") {
|
|
||||||
Self::unpack_pause_image(&cid)?;
|
Self::unpack_pause_image(&cid)?;
|
||||||
|
|
||||||
let mut sandbox = self.sandbox.lock().await;
|
let mut sandbox = self.sandbox.lock().await;
|
||||||
@ -257,17 +164,14 @@ impl ImageService {
|
|||||||
Err(_) => info!(sl!(), "Attestation Agent already running"),
|
Err(_) => info!(sl!(), "Attestation Agent already running"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If the attestation-agent is being used, then enable the authenticated credentials support
|
||||||
|
info!(
|
||||||
|
sl!(),
|
||||||
|
"image_client.config.auth set to: {}",
|
||||||
|
!aa_kbc_params.is_empty()
|
||||||
|
);
|
||||||
|
self.image_client.lock().await.config.auth = !aa_kbc_params.is_empty();
|
||||||
|
|
||||||
let source_creds = (!req.get_source_creds().is_empty()).then(|| req.get_source_creds());
|
|
||||||
|
|
||||||
if Path::new(SKOPEO_PATH).exists() {
|
|
||||||
// Read the policy path from the agent config
|
|
||||||
let config_policy_path = &AGENT_CONFIG.read().await.container_policy_path;
|
|
||||||
let policy_path =
|
|
||||||
(!config_policy_path.is_empty()).then_some(config_policy_path.as_str());
|
|
||||||
Self::pull_image_from_registry(image, &cid, source_creds, policy_path, aa_kbc_params)?;
|
|
||||||
Self::unpack_image(&cid)?;
|
|
||||||
} else {
|
|
||||||
// Read enable signature verification from the agent config and set it in the image_client
|
// Read enable signature verification from the agent config and set it in the image_client
|
||||||
let enable_signature_verification =
|
let enable_signature_verification =
|
||||||
&AGENT_CONFIG.read().await.enable_signature_verification;
|
&AGENT_CONFIG.read().await.enable_signature_verification;
|
||||||
@ -275,17 +179,9 @@ impl ImageService {
|
|||||||
sl!(),
|
sl!(),
|
||||||
"enable_signature_verification set to: {}", enable_signature_verification
|
"enable_signature_verification set to: {}", enable_signature_verification
|
||||||
);
|
);
|
||||||
self.image_client.lock().await.config.security_validate =
|
self.image_client.lock().await.config.security_validate = *enable_signature_verification;
|
||||||
*enable_signature_verification;
|
|
||||||
|
|
||||||
// If the attestation-agent is being used, then enable the authenticated credentials support
|
let source_creds = (!req.get_source_creds().is_empty()).then(|| req.get_source_creds());
|
||||||
//TODO tidy logic once skopeo is removed to combine with aa_kbc_params check above
|
|
||||||
info!(
|
|
||||||
sl!(),
|
|
||||||
"image_client.config.auth set to: {}",
|
|
||||||
!aa_kbc_params.is_empty()
|
|
||||||
);
|
|
||||||
self.image_client.lock().await.config.auth = !aa_kbc_params.is_empty();
|
|
||||||
|
|
||||||
let bundle_path = Path::new(CONTAINER_BASE).join(&cid);
|
let bundle_path = Path::new(CONTAINER_BASE).join(&cid);
|
||||||
fs::create_dir_all(&bundle_path)?;
|
fs::create_dir_all(&bundle_path)?;
|
||||||
@ -306,9 +202,7 @@ impl ImageService {
|
|||||||
Ok(image) => {
|
Ok(image) => {
|
||||||
info!(
|
info!(
|
||||||
sl!(),
|
sl!(),
|
||||||
"pull and unpack image {:?}, cid: {:?}, with image-rs succeed. ",
|
"pull and unpack image {:?}, cid: {:?}, with image-rs succeed. ", image, cid
|
||||||
image,
|
|
||||||
cid
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -322,7 +216,6 @@ impl ImageService {
|
|||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
let mut sandbox = self.sandbox.lock().await;
|
let mut sandbox = self.sandbox.lock().await;
|
||||||
sandbox.images.insert(String::from(image), cid);
|
sandbox.images.insert(String::from(image), cid);
|
||||||
|
@ -187,9 +187,3 @@ To add additional packages, use one of the following methods:
|
|||||||
|
|
||||||
Once the rootfs directory is created, you can add and remove files as
|
Once the rootfs directory is created, you can add and remove files as
|
||||||
needed. Changes affect the files included in the final guest image.
|
needed. Changes affect the files included in the final guest image.
|
||||||
|
|
||||||
#### Confidential containers support
|
|
||||||
|
|
||||||
When building the rootfs for confidential containers if `SKOPEO=yes` is set then the `skopeo`
|
|
||||||
package is built and added into the rootfs.
|
|
||||||
If `UMOCI=yes` is set then the `umoci` package is built and added into the rootfs.
|
|
@ -157,23 +157,9 @@ USE_PODMAN If set and USE_DOCKER not set, then build the rootfs inside
|
|||||||
a podman container (requires podman).
|
a podman container (requires podman).
|
||||||
Default value: <not set>
|
Default value: <not set>
|
||||||
|
|
||||||
SKOPEO If set to "yes", build Skopeo for confidential
|
|
||||||
containers guest image pull. Currently, this is only
|
|
||||||
supported for Ubuntu guests; see
|
|
||||||
https://github.com/kata-containers/kata-containers/pull/2908
|
|
||||||
for discussion.
|
|
||||||
Default value: <not set>
|
|
||||||
|
|
||||||
UMOCI If set to "yes", build and umoci for confidential
|
|
||||||
containers guest image unpack. Currently, this is only
|
|
||||||
supported for Ubuntu guests; see
|
|
||||||
https://github.com/kata-containers/kata-containers/pull/2908
|
|
||||||
for discussion.
|
|
||||||
Default value: <not set>
|
|
||||||
|
|
||||||
AA_KBC Key broker client module for attestation-agent. This is
|
AA_KBC Key broker client module for attestation-agent. This is
|
||||||
required for confidential containers. Requires UMOCI
|
required for confidential containers.
|
||||||
to be set. See https://github.com/containers/attestation-agent
|
See https://github.com/containers/attestation-agent
|
||||||
for more information on available modules.
|
for more information on available modules.
|
||||||
Default value: <not set>
|
Default value: <not set>
|
||||||
|
|
||||||
@ -402,10 +388,13 @@ build_rootfs_distro()
|
|||||||
engine_build_args+=" --build-arg IMAGE_REGISTRY=${IMAGE_REGISTRY}"
|
engine_build_args+=" --build-arg IMAGE_REGISTRY=${IMAGE_REGISTRY}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
skopeo_version="$(get_package_version_from_kata_yaml externals.skopeo.version)"
|
||||||
|
|
||||||
# setup to install rust here
|
# setup to install rust here
|
||||||
generate_dockerfile "${distro_config_dir}"
|
generate_dockerfile "${distro_config_dir}"
|
||||||
"$container_engine" build \
|
"$container_engine" build \
|
||||||
${engine_build_args} \
|
${engine_build_args} \
|
||||||
|
--build-arg SKOPEO_VERSION="${skopeo_version}" \
|
||||||
--build-arg http_proxy="${http_proxy}" \
|
--build-arg http_proxy="${http_proxy}" \
|
||||||
--build-arg https_proxy="${https_proxy}" \
|
--build-arg https_proxy="${https_proxy}" \
|
||||||
-t "${image_name}" "${distro_config_dir}"
|
-t "${image_name}" "${distro_config_dir}"
|
||||||
@ -464,8 +453,6 @@ build_rootfs_distro()
|
|||||||
--env OSBUILDER_VERSION="${OSBUILDER_VERSION}" \
|
--env OSBUILDER_VERSION="${OSBUILDER_VERSION}" \
|
||||||
--env OS_VERSION="${OS_VERSION}" \
|
--env OS_VERSION="${OS_VERSION}" \
|
||||||
--env INSIDE_CONTAINER=1 \
|
--env INSIDE_CONTAINER=1 \
|
||||||
--env SKOPEO="${SKOPEO}" \
|
|
||||||
--env UMOCI="${UMOCI}" \
|
|
||||||
--env AA_KBC="${AA_KBC}" \
|
--env AA_KBC="${AA_KBC}" \
|
||||||
--env KATA_BUILD_CC="${KATA_BUILD_CC}" \
|
--env KATA_BUILD_CC="${KATA_BUILD_CC}" \
|
||||||
--env SECCOMP="${SECCOMP}" \
|
--env SECCOMP="${SECCOMP}" \
|
||||||
@ -669,17 +656,6 @@ EOF
|
|||||||
info "Create /etc/resolv.conf file in rootfs if not exist"
|
info "Create /etc/resolv.conf file in rootfs if not exist"
|
||||||
touch "$dns_file"
|
touch "$dns_file"
|
||||||
|
|
||||||
if [ "${SKOPEO}" = "yes" ]; then
|
|
||||||
skopeo_url="$(get_package_version_from_kata_yaml externals.skopeo.url)"
|
|
||||||
skopeo_branch="$(get_package_version_from_kata_yaml externals.skopeo.branch)"
|
|
||||||
info "Install skopeo"
|
|
||||||
git clone "${skopeo_url}" --branch "${skopeo_branch}"
|
|
||||||
pushd skopeo
|
|
||||||
make bin/skopeo
|
|
||||||
install -o root -g root -m 0755 bin/skopeo "${ROOTFS_DIR}/usr/bin/"
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${AA_KBC}" ]; then
|
if [ -n "${AA_KBC}" ]; then
|
||||||
if [ "${AA_KBC}" == "offline_sev_kbc" ]; then
|
if [ "${AA_KBC}" == "offline_sev_kbc" ]; then
|
||||||
info "Adding agent config for ${AA_KBC}"
|
info "Adding agent config for ${AA_KBC}"
|
||||||
@ -715,24 +691,6 @@ EOF
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${UMOCI}" = "yes" ]; then
|
|
||||||
case "$ARCH" in
|
|
||||||
aarch64) GOARCH=arm64;;
|
|
||||||
x86_64) GOARCH=amd64;;
|
|
||||||
*) GOARCH="$ARCH"
|
|
||||||
esac
|
|
||||||
export GOARCH
|
|
||||||
|
|
||||||
umoci_url="$(get_package_version_from_kata_yaml externals.umoci.url)"
|
|
||||||
umoci_tag="$(get_package_version_from_kata_yaml externals.umoci.tag)"
|
|
||||||
info "Install umoci"
|
|
||||||
git clone "${umoci_url}" --branch "${umoci_tag}"
|
|
||||||
pushd umoci
|
|
||||||
make
|
|
||||||
install -o root -g root -m 0755 umoci "${ROOTFS_DIR}/usr/local/bin/"
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${KATA_BUILD_CC}" == "yes" ]; then
|
if [ "${KATA_BUILD_CC}" == "yes" ]; then
|
||||||
info "Integrate pause image inside rootfs for CC"
|
info "Integrate pause image inside rootfs for CC"
|
||||||
pause_repo="$(get_package_version_from_kata_yaml externals.pause.repo)"
|
pause_repo="$(get_package_version_from_kata_yaml externals.pause.repo)"
|
||||||
|
@ -9,7 +9,7 @@ ARG IMAGE_REGISTRY=docker.io
|
|||||||
FROM ${IMAGE_REGISTRY}/golang:1.18 AS skopeo
|
FROM ${IMAGE_REGISTRY}/golang:1.18 AS skopeo
|
||||||
@SET_PROXY@
|
@SET_PROXY@
|
||||||
WORKDIR /skopeo
|
WORKDIR /skopeo
|
||||||
ARG SKOPEO_VERSION="1.9.1"
|
ARG SKOPEO_VERSION
|
||||||
RUN curl -fsSL "https://github.com/containers/skopeo/archive/v${SKOPEO_VERSION}.tar.gz" \
|
RUN curl -fsSL "https://github.com/containers/skopeo/archive/v${SKOPEO_VERSION}.tar.gz" \
|
||||||
| tar -xzf - --strip-components=1
|
| tar -xzf - --strip-components=1
|
||||||
RUN CGO_ENABLED=0 DISABLE_DOCS=1 make BUILDTAGS=containers_image_openpgp GO_DYN_FLAGS=
|
RUN CGO_ENABLED=0 DISABLE_DOCS=1 make BUILDTAGS=containers_image_openpgp GO_DYN_FLAGS=
|
||||||
|
@ -9,7 +9,6 @@ PACKAGES="chrony iptables dbus kmod"
|
|||||||
[ "$AGENT_INIT" = no ] && PACKAGES+=" init"
|
[ "$AGENT_INIT" = no ] && PACKAGES+=" init"
|
||||||
[ "$KATA_BUILD_CC" = yes ] && PACKAGES+=" cryptsetup-bin e2fsprogs"
|
[ "$KATA_BUILD_CC" = yes ] && PACKAGES+=" cryptsetup-bin e2fsprogs"
|
||||||
[ "$SECCOMP" = yes ] && PACKAGES+=" libseccomp2"
|
[ "$SECCOMP" = yes ] && PACKAGES+=" libseccomp2"
|
||||||
[ "$SKOPEO" = yes ] && PACKAGES+=" libgpgme11 libdevmapper1.02.1"
|
|
||||||
REPO_URL=http://ports.ubuntu.com
|
REPO_URL=http://ports.ubuntu.com
|
||||||
|
|
||||||
case "$ARCH" in
|
case "$ARCH" in
|
||||||
|
@ -207,22 +207,6 @@ ${extra}
|
|||||||
agent-is-init-daemon: "${AGENT_INIT}"
|
agent-is-init-daemon: "${AGENT_INIT}"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if [ "${SKOPEO}" = "yes" ]; then
|
|
||||||
cat >> "${file}" <<-EOF
|
|
||||||
skopeo:
|
|
||||||
url: "${skopeo_url}"
|
|
||||||
version: "${skopeo_branch}"
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${UMOCI}" = "yes" ]; then
|
|
||||||
cat >> "${file}" <<-EOF
|
|
||||||
umoci:
|
|
||||||
url: "${umoci_url}"
|
|
||||||
version: "${umoci_tag}"
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${AA_KBC}" ]; then
|
if [ -n "${AA_KBC}" ]; then
|
||||||
cat >> "${file}" <<-EOF
|
cat >> "${file}" <<-EOF
|
||||||
attestation-agent:
|
attestation-agent:
|
||||||
|
@ -51,8 +51,6 @@ docker run \
|
|||||||
--user ${uid}:${gid} \
|
--user ${uid}:${gid} \
|
||||||
--env CI="${CI:-}" \
|
--env CI="${CI:-}" \
|
||||||
--env USER=${USER} \
|
--env USER=${USER} \
|
||||||
--env SKOPEO="${SKOPEO:-}" \
|
|
||||||
--env UMOCI="${UMOCI:-}" \
|
|
||||||
--env AA_KBC="${AA_KBC:-}" \
|
--env AA_KBC="${AA_KBC:-}" \
|
||||||
--env KATA_BUILD_CC="${KATA_BUILD_CC:-}" \
|
--env KATA_BUILD_CC="${KATA_BUILD_CC:-}" \
|
||||||
--env INCLUDE_ROOTFS="$(realpath "${INCLUDE_ROOTFS:-}" 2> /dev/null || true)" \
|
--env INCLUDE_ROOTFS="$(realpath "${INCLUDE_ROOTFS:-}" 2> /dev/null || true)" \
|
||||||
|
@ -253,14 +253,12 @@ install_cc_image() {
|
|||||||
local gperf_version="$(get_from_kata_deps "externals.gperf.version")"
|
local gperf_version="$(get_from_kata_deps "externals.gperf.version")"
|
||||||
local libseccomp_version="$(get_from_kata_deps "externals.libseccomp.version")"
|
local libseccomp_version="$(get_from_kata_deps "externals.libseccomp.version")"
|
||||||
local pause_version="$(get_from_kata_deps "externals.pause.version")"
|
local pause_version="$(get_from_kata_deps "externals.pause.version")"
|
||||||
local skopeo_version="$(get_from_kata_deps "externals.skopeo.branch")"
|
|
||||||
local umoci_version="$(get_from_kata_deps "externals.umoci.tag")"
|
|
||||||
local rust_version="$(get_from_kata_deps "languages.rust.meta.newest-version")"
|
local rust_version="$(get_from_kata_deps "languages.rust.meta.newest-version")"
|
||||||
|
|
||||||
install_cached_component \
|
install_cached_component \
|
||||||
"${component}" \
|
"${component}" \
|
||||||
"${jenkins}" \
|
"${jenkins}" \
|
||||||
"${osbuilder_last_commit}-${guest_image_last_commit}-${agent_last_commit}-${libs_last_commit}-${attestation_agent_version}-${gperf_version}-${libseccomp_version}-${pause_version}-${skopeo_version}-${umoci_version}-${rust_version}-${image_type}-${AA_KBC}" \
|
"${osbuilder_last_commit}-${guest_image_last_commit}-${agent_last_commit}-${libs_last_commit}-${attestation_agent_version}-${gperf_version}-${libseccomp_version}-${pause_version}-${rust_version}-${image_type}-${AA_KBC}" \
|
||||||
"" \
|
"" \
|
||||||
"${final_tarball_name}" \
|
"${final_tarball_name}" \
|
||||||
"${final_tarball_path}" \
|
"${final_tarball_path}" \
|
||||||
|
@ -89,8 +89,6 @@ cache_rootfs_artifacts() {
|
|||||||
local gperf_version="$(get_from_kata_deps "externals.gperf.version")"
|
local gperf_version="$(get_from_kata_deps "externals.gperf.version")"
|
||||||
local libseccomp_version="$(get_from_kata_deps "externals.libseccomp.version")"
|
local libseccomp_version="$(get_from_kata_deps "externals.libseccomp.version")"
|
||||||
local pause_version="$(get_from_kata_deps "externals.pause.version")"
|
local pause_version="$(get_from_kata_deps "externals.pause.version")"
|
||||||
local skopeo_version="$(get_from_kata_deps "externals.skopeo.branch")"
|
|
||||||
local umoci_version="$(get_from_kata_deps "externals.umoci.tag")"
|
|
||||||
local rust_version="$(get_from_kata_deps "languages.rust.meta.newest-version")"
|
local rust_version="$(get_from_kata_deps "languages.rust.meta.newest-version")"
|
||||||
local rootfs_tarball_name="kata-static-cc-rootfs-image.tar.xz"
|
local rootfs_tarball_name="kata-static-cc-rootfs-image.tar.xz"
|
||||||
local aa_kbc="offline_fs_kbc"
|
local aa_kbc="offline_fs_kbc"
|
||||||
@ -106,7 +104,7 @@ cache_rootfs_artifacts() {
|
|||||||
root_hash_tdx="${repo_root_dir}/tools/osbuilder/root_hash_tdx.txt"
|
root_hash_tdx="${repo_root_dir}/tools/osbuilder/root_hash_tdx.txt"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
local current_rootfs_version="${osbuilder_last_commit}-${guest_image_last_commit}-${agent_last_commit}-${libs_last_commit}-${attestation_agent_version}-${gperf_version}-${libseccomp_version}-${pause_version}-${skopeo_version}-${umoci_version}-${rust_version}-${image_type}-${aa_kbc}"
|
local current_rootfs_version="${osbuilder_last_commit}-${guest_image_last_commit}-${agent_last_commit}-${libs_last_commit}-${attestation_agent_version}-${gperf_version}-${libseccomp_version}-${pause_version}-${rust_version}-${image_type}-${aa_kbc}"
|
||||||
create_cache_asset "${rootfs_tarball_name}" "${current_rootfs_version}" "" "${root_hash_vanilla}" "${root_hash_tdx}"
|
create_cache_asset "${rootfs_tarball_name}" "${current_rootfs_version}" "" "${root_hash_vanilla}" "${root_hash_tdx}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,12 +273,7 @@ externals:
|
|||||||
skopeo:
|
skopeo:
|
||||||
description: "Utility for container images and image repositories"
|
description: "Utility for container images and image repositories"
|
||||||
url: "https://github.com/containers/skopeo"
|
url: "https://github.com/containers/skopeo"
|
||||||
branch: "release-1.4"
|
version: "1.9.1"
|
||||||
|
|
||||||
umoci:
|
|
||||||
description: "Utility for creating and manipulating container images"
|
|
||||||
url: "https://github.com/opencontainers/umoci"
|
|
||||||
tag: "v0.4.7"
|
|
||||||
|
|
||||||
nydus:
|
nydus:
|
||||||
description: "Nydus image acceleration service"
|
description: "Nydus image acceleration service"
|
||||||
|
Loading…
Reference in New Issue
Block a user