| Crates.io | sherpack-core |
| lib.rs | sherpack-core |
| version | 0.3.0 |
| created_at | 2025-12-20 12:36:05.667643+00 |
| updated_at | 2025-12-23 13:24:28.552526+00 |
| description | Core types and utilities for Sherpack - the Kubernetes package manager |
| homepage | https://alegeay.github.io/Sherpack/ |
| repository | https://github.com/alegeay/sherpack |
| max_upload_size | |
| id | 1996459 |
| size | 199,455 |
Core types and utilities for Sherpack - the Kubernetes package manager with Jinja2 templates.
sherpack-core provides the foundational data structures and utilities used throughout the Sherpack ecosystem. This crate is dependency-free from Kubernetes APIs, making it suitable for offline operations like templating, packaging, and validation.
.tgz packagespack - Package DefinitionThe core Pack structure represents a Sherpack package (equivalent to a Helm Chart).
use sherpack_core::{Pack, PackMetadata, PackKind, Dependency, ResolvePolicy, LoadedPack};
// Load a pack from disk
let pack = LoadedPack::load("./my-pack")?;
println!("Pack: {} v{}", pack.pack.metadata.name, pack.pack.metadata.version);
// Access dependencies
for dep in &pack.pack.dependencies {
println!(" Depends on: {} @ {}", dep.name, dep.version);
}
apiVersion: sherpack/v1
kind: application # or 'library'
metadata:
name: my-app
version: 1.0.0
description: My application
appVersion: "2.0"
keywords:
- web
- api
maintainers:
- name: John Doe
email: john@example.com
dependencies:
- name: redis
version: "^17.0.0"
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled # Evaluated against values.yaml
enabled: true # Static enable/disable
resolve: when-enabled # always | when-enabled | never
alias: cache # Optional rename
use sherpack_core::{Dependency, ResolvePolicy};
let dep = Dependency {
name: "redis".to_string(),
version: "^17.0.0".to_string(),
repository: "https://example.com".to_string(),
enabled: true, // Static flag
condition: Some("redis.enabled".into()), // Dynamic condition
resolve: ResolvePolicy::WhenEnabled, // Resolution policy
tags: vec![],
alias: None,
};
// Check if dependency should be resolved
let values = serde_json::json!({ "redis": { "enabled": true } });
assert!(dep.should_resolve(&values));
values - Configuration ValuesDeep merge support for layered configuration.
use sherpack_core::{Values, parse_set_values};
// Load from file
let mut values = Values::from_file("values.yaml")?;
// Parse CLI --set arguments
let overrides = parse_set_values(&[
"image.tag=v2.0".to_string(),
"replicas=5".to_string(),
"debug=true".to_string(),
])?;
// Deep merge (overrides win)
values.merge(&overrides);
// Access nested values
let tag = values.get("image.tag"); // Some("v2.0")
| Base | Overlay | Result |
|---|---|---|
{ a: 1 } |
{ a: 2 } |
{ a: 2 } (scalar: replace) |
{ a: { b: 1 } } |
{ a: { c: 2 } } |
{ a: { b: 1, c: 2 } } (object: merge) |
[1, 2] |
[3, 4] |
[3, 4] (array: replace, not append) |
schema - Values ValidationDual-format schema support for validating configuration.
use sherpack_core::{Schema, SchemaValidator};
// Load schema (auto-detects format)
let schema = Schema::load("values.schema.yaml")?;
let validator = SchemaValidator::new(&schema)?;
// Validate values
let values = serde_json::json!({
"replicas": 3,
"image": { "tag": "latest" }
});
match validator.validate(&values) {
Ok(result) if result.is_valid() => println!("Valid!"),
Ok(result) => {
for error in result.errors {
println!("Error at {}: {}", error.path, error.message);
}
}
Err(e) => println!("Schema error: {}", e),
}
// Extract defaults from schema
let defaults = schema.extract_defaults();
JSON Schema (standard)
$schema: "https://json-schema.org/draft/2020-12/schema"
type: object
properties:
replicas:
type: integer
minimum: 1
default: 1
required:
- replicas
Sherpack Simplified Format
schemaVersion: "1"
properties:
replicas:
type: int
required: true
default: 1
min: 1
description: Number of pod replicas
image.tag:
type: string
default: latest
release - Deployment StateTrack deployment lifecycle.
use sherpack_core::{Release, ReleaseStatus, ReleaseInfo};
use chrono::Utc;
let release = Release {
name: "my-app".to_string(),
namespace: "production".to_string(),
revision: 5,
status: ReleaseStatus::Deployed,
info: ReleaseInfo {
first_deployed: Utc::now(),
last_deployed: Utc::now(),
description: "Upgrade to v2.0".to_string(),
},
};
| Status | Description |
|---|---|
Pending |
Installation/upgrade in progress |
Deployed |
Successfully deployed |
Failed |
Deployment failed |
Superseded |
Replaced by newer revision |
Uninstalling |
Uninstall in progress |
Uninstalled |
Successfully uninstalled |
context - Template ContextBuild the context passed to templates.
use sherpack_core::{TemplateContext, Release, Values, Pack};
let context = TemplateContext::new(
&values,
&release,
&pack,
"1.28.0", // Kubernetes version
);
// Serialize for template engine
let ctx_value = context.to_value()?;
// Contains: values, release, pack, capabilities
archive - Package ArchivesCreate and manage .tgz packages with integrity verification.
use sherpack_core::{create_archive, extract_archive, verify_archive, list_archive};
use std::path::Path;
// Create archive
create_archive(
Path::new("./my-pack"),
Path::new("./my-pack-1.0.0.tgz"),
)?;
// List contents
for entry in list_archive(Path::new("./my-pack-1.0.0.tgz"))? {
println!("{}: {} bytes", entry.path, entry.size);
}
// Extract
extract_archive(
Path::new("./my-pack-1.0.0.tgz"),
Path::new("./extracted/"),
)?;
// Verify integrity
let result = verify_archive(Path::new("./my-pack-1.0.0.tgz"))?;
if result.is_valid {
println!("Archive integrity verified");
} else {
for mismatch in result.mismatched {
println!("Corrupted: {}", mismatch.path);
}
}
manifest - Integrity ManifestsSHA256 checksums for all pack files.
use sherpack_core::{Manifest, FileEntry};
use std::path::Path;
// Generate manifest for a directory
let manifest = Manifest::generate(Path::new("./my-pack"))?;
// Manifest format (YAML)
// sherpack-manifest-version: "1"
// files:
// Pack.yaml: sha256:abc123...
// values.yaml: sha256:def456...
// templates/deployment.yaml: sha256:...
// Verify against manifest
let result = manifest.verify(Path::new("./my-pack"))?;
match result {
VerificationResult::Valid => println!("All files match"),
VerificationResult::Mismatch(files) => {
for f in files {
println!("Modified: {}", f.path);
}
}
}
All errors are strongly typed using thiserror:
use sherpack_core::{CoreError, ValidationErrorInfo};
match pack_operation() {
Err(CoreError::PackNotFound { path }) => {
println!("Pack not found: {}", path.display());
}
Err(CoreError::ValidationFailed { errors }) => {
for error in errors {
println!("Validation error at {}: {}", error.path, error.message);
}
}
Err(e) => println!("Error: {}", e),
Ok(_) => {}
}
serde / serde_yaml / serde_json - Serializationsemver - Semantic versioningjsonschema - JSON Schema validationsha2 - SHA256 checksumstar / flate2 - Archive operationschrono - Timestampsthiserror - Error handlingMIT OR Apache-2.0