Skip to content

Commit

Permalink
tools: add script to check kata hashes match (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
csegarragonz authored Dec 9, 2024
1 parent edb5d05 commit 9024ab8
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 10 deletions.
23 changes: 14 additions & 9 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,31 @@ concurrency:
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
code-format:
checks:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: "Checkout code"
uses: actions/checkout@v4
# Formatting checks
- name: "Python formatting check"
run: ./bin/inv_wrapper.sh format-code --check
# Rust formatting checks
- name: "Run cargo fmt check"
run: cargo fmt --all -- --check
working-directory: ./vm-cache
- name: "Run cargo clippy"
run: cargo clippy -- -D warnings
working-directory: ./vm-cache
- name: "Run cargo lints"
run: |
for dir in "./vm-cache/" "./tools/check-kata-hashes"; do
pushd ${dir} >> /dev/null
cargo fmt --all -- --check
cargo clippy -- -D warnings
popd >> /dev/null
done
- name: "Check Kata hashes match"
run: cargo run --release
working-directory: ./tools/check-kata-hashes

setup-cluster:
if: github.event.pull_request.draft == false
runs-on: self-hosted
runs-on: [self-hosted, snp]
env:
KUBECONFIG: .config/kubeadm_kubeconfig
steps:
Expand Down
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
ansible>=8.4.0
black>=23.9.1
flake8>=7.1.1
invoke>=2.1.0
Jinja2>=3.1.2
jinja2-ansible-filters>=1.3.2
matplotlib>=3.8.0
pandas>=2.1.1
psutil>=5.9.6
pymysql>=1.1.0
python-language-server[all]
python-lsp-server[all]>=1.12.0
toml>=0.10.2
sev-snp-measure>=0.0.7
1 change: 1 addition & 0 deletions tools/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
96 changes: 96 additions & 0 deletions tools/check-kata-hashes/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions tools/check-kata-hashes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "check-kata-hashes"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = "1.0"
serde_json = "1.0"
5 changes: 5 additions & 0 deletions tools/check-kata-hashes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Check Kata Hashes

This script checks that the branches in `https://github.com/sc2-sys/kata-containers`
and in the kata-containers check-out in `ghcr.io/sc2-sys/kata-containers:${KATA_VERSION}`
are in sync.
154 changes: 154 additions & 0 deletions tools/check-kata-hashes/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
use std::{
fs,
io::{self, BufRead},
process::{exit, Command, Stdio},
};

const SCRIPT_NAME: &str = "sc2-deploy(check-kata-hash)";

fn get_kata_version() -> Result<String, String> {
// Work-out the versions file path from the binary's real path
let mut file_path =
std::env::current_exe().expect("sc2-deploy: failed to get current exe path");
file_path = file_path.parent().unwrap().to_path_buf();
file_path = file_path.parent().unwrap().to_path_buf();
file_path = file_path.parent().unwrap().to_path_buf();
file_path = file_path.parent().unwrap().to_path_buf();
file_path = file_path.parent().unwrap().to_path_buf();
file_path.push("tasks/util/versions.py");

let file = fs::File::open(file_path.clone()).map_err(|e| {
format!(
"{SCRIPT_NAME}: failed to open file '{}': {e}",
file_path.to_string_lossy()
)
})?;
let reader = io::BufReader::new(file);

for line in reader.lines() {
let line = line.map_err(|e| format!("{SCRIPT_NAME}: failed to read line: {e}"))?;
if line.starts_with("KATA_VERSION") {
let parts: Vec<&str> = line.split('=').collect();
if parts.len() == 2 {
return Ok(parts[1].trim().trim_matches('"').to_string());
}
}
}

Err(format!(
"KATA_VERSION not found in file '{}'",
file_path.to_string_lossy()
))
}

fn get_upstream_hash(repo: &str, branch: &str) -> Result<String, String> {
let url = format!("https://api.github.com/repos/{repo}/branches/{branch}");
let output = Command::new("curl")
.arg("-s")
.arg(&url)
.output()
.map_err(|e| format!("{SCRIPT_NAME}: failed to execute curl: {e}"))?;

if !output.status.success() {
return Err(format!(
"{SCRIPT_NAME}: failed to fetch branch data: {}",
String::from_utf8_lossy(&output.stderr)
));
}

let json: serde_json::Value = serde_json::from_slice(&output.stdout)
.map_err(|e| format!("{SCRIPT_NAME}: failed to parse JSON: {e}"))?;

json["commit"]["sha"]
.as_str()
.map(|s| s.to_string())
.ok_or_else(|| "upstream commit hash not found".to_string())
}

fn get_local_hash(container: &str, path: &str, branch: &str) -> Result<String, String> {
let output = Command::new("docker")
.arg("run")
.arg("--rm")
.arg("--workdir")
.arg(path)
.arg(container)
.arg("git")
.arg("rev-parse")
.arg(branch)
.output()
.map_err(|e| format!("{SCRIPT_NAME}: failed to execute git rev-parse: {e}"))?;

if !output.status.success() {
return Err(format!(
"{SCRIPT_NAME}: failed to fetch container branch hash: {}",
String::from_utf8_lossy(&output.stderr)
));
}

Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}

/// This script checks that the branches in `https://github.com/sc2-sys/kata-containers`
/// and in the kata-containers check-out in `ghcr.io/sc2-sys/kata-containers:${KATA_VERSION}`
/// are in sync.
fn main() {
let repo = "sc2-sys/kata-containers";
let container = format!(
"ghcr.io/sc2-sys/kata-containers:{}",
get_kata_version().unwrap()
);
let branches = ["sc2-main", "sc2-baseline"];
let mut all_match = true;

// Pull docker image first
let output = Command::new("docker")
.arg("pull")
.arg(container.clone())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.unwrap();

if !output.success() {
eprintln!("{SCRIPT_NAME}: failed to fetch container image");
exit(1);
}

for branch in &branches {
let upstream_hash = match get_upstream_hash(repo, branch) {
Ok(hash) => hash,
Err(e) => {
eprintln!("{SCRIPT_NAME}: error fetching upstream hash for {branch}: {e}");
all_match = false;
continue;
}
};

let mut path = "/go/src/github.com/kata-containers/kata-containers-sc2";
if *branch == "sc2-baseline" {
path = "/go/src/github.com/kata-containers/kata-containers-baseline";
}

let local_hash = match get_local_hash(&container, path, branch) {
Ok(hash) => hash,
Err(e) => {
eprintln!("{SCRIPT_NAME}: error fetching container hash for {branch}: {e}");
all_match = false;
continue;
}
};

if upstream_hash == local_hash {
println!("{SCRIPT_NAME}: {branch} is up to date");
} else {
println!("{SCRIPT_NAME}: {branch} is NOT up to date");
all_match = false;
}
}

if all_match {
exit(0);
} else {
exit(1);
}
}

0 comments on commit 9024ab8

Please sign in to comment.