Skip to content

Commit

Permalink
Added support for systemwide flake config
Browse files Browse the repository at this point in the history
Let podman and firecracker pilots read /etc/flakes.yml if present
to allow configuration of several general settings. Proper defaults
are encoded in case no data is provided
  • Loading branch information
schaefi committed Sep 3, 2023
1 parent 0e91df2 commit f1b51d0
Show file tree
Hide file tree
Showing 14 changed files with 198 additions and 27 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sourcetar:
rm -rf package/flake-pilot
mkdir package/flake-pilot
cp Makefile package/flake-pilot
cp flakes.yml package/flake-pilot
cp -a common package/flake-pilot/
cp -a podman-pilot package/flake-pilot/
cp -a flake-ctl package/flake-pilot/
Expand Down
2 changes: 2 additions & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", optional = true }
log = { version = "0.4" }
thiserror = { version = "1.0" }
serde_yaml = { version = "0.9" }
lazy_static = { version = "1.4" }

[features]
json = ["serde_json"]
93 changes: 93 additions & 0 deletions common/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// Copyright (c) 2023 SUSE Software Solutions Germany GmbH
//
// This file is part of flake-pilot
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
use serde::Deserialize;
use std::path::Path;
use lazy_static::lazy_static;

use crate::defaults;

lazy_static! {
static ref FLAKES_CONFIG: FlakesConfig = read_flakes_config();
}

pub fn get_flakes_dir() -> String {
let GenericData { flakes_dir, .. } = &flakes_config().generic;
flakes_dir.clone().unwrap_or(defaults::FLAKES_DIR.to_string())
}

pub fn get_podman_ids_dir() -> String {
let GenericData { podman_ids_dir, .. } = &flakes_config().generic;
podman_ids_dir.clone().unwrap_or(defaults::PODMAN_IDS_DIR.to_string())
}

pub fn get_firecracker_ids_dir() -> String {
let GenericData { firecracker_ids_dir, .. } = &flakes_config().generic;
firecracker_ids_dir.clone().unwrap_or(defaults::FIRECRACKER_IDS_DIR.to_string())
}

fn flakes_config() -> &'static FlakesConfig {
&FLAKES_CONFIG
}

fn read_flakes_config() -> FlakesConfig {
/*!
Read systemwide flakes configuration file
generic:
flakes_dir: ~
podman_ids_dir: ~
firecracker_ids_dir: ~
!*/
if Path::new(defaults::FLAKES_CONFIG).exists() {
let flakes_file = std::fs::File::open(defaults::FLAKES_CONFIG)
.unwrap_or_else(|_| panic!("Failed to open {}", defaults::FLAKES_CONFIG));
serde_yaml::from_reader(flakes_file)
.unwrap_or_else(|error| panic!("Failed to import {}: {}", defaults::FLAKES_CONFIG, error))
} else {
FlakesConfig {
generic: GenericData {
flakes_dir: None::<String>,
podman_ids_dir: None::<String>,
firecracker_ids_dir: None::<String>
}
}
}
}

#[derive(Deserialize)]
struct FlakesConfig {
generic: GenericData,
}

#[derive(Deserialize)]
struct GenericData {
/// Flakes directory to store registrations
flakes_dir: Option<String>,

/// ID files directory for podman registrations
podman_ids_dir: Option<String>,

/// ID files directory for firecracker registrations
firecracker_ids_dir: Option<String>
}
27 changes: 27 additions & 0 deletions common/src/defaults.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// Copyright (c) 2023 SUSE Software Solutions Germany GmbH
//
// This file is part of flake-pilot
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
pub const FLAKES_CONFIG: &str = "/etc/flakes.yml";
pub const FLAKES_DIR: &str = "/usr/share/flakes";
pub const PODMAN_IDS_DIR: &str = "/tmp/flakes";
pub const FIRECRACKER_IDS_DIR: &str = "/tmp/flakes";
2 changes: 2 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ pub mod lookup;
pub mod user;
pub mod command;
pub mod error;
pub mod config;
pub mod flakelog;
pub mod defaults;
7 changes: 3 additions & 4 deletions firecracker-pilot/src/app_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ use std::process::exit;
use std::fs;
use yaml_rust::Yaml;
use yaml_rust::YamlLoader;

use crate::defaults;
use flakes::config::get_flakes_dir;

pub fn program_abs_path() -> String {
/*!
Expand Down Expand Up @@ -60,7 +59,7 @@ pub fn program_config_file(program_basename: &String) -> String {
Provide expected config file path for the given program_basename
!*/
let config_file = &format!(
"{}/{}.yaml", defaults::FIRECRACKER_FLAKE_DIR, program_basename
"{}/{}.yaml", get_flakes_dir(), program_basename
);
config_file.to_string()
}
Expand All @@ -70,7 +69,7 @@ pub fn program_config_dir(program_basename: &String) -> String {
Provide expected config directory for the given program_basename
!*/
let config_dir = &format!(
"{}/{}.d", defaults::FIRECRACKER_FLAKE_DIR, program_basename
"{}/{}.d", get_flakes_dir(), program_basename
);
config_dir.to_string()
}
Expand Down
31 changes: 26 additions & 5 deletions firecracker-pilot/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
//
// Copyright (c) 2023 SUSE Software Solutions Germany GmbH
//
// This file is part of flake-pilot
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
use flakes::user::User;
use lazy_static::lazy_static;
use serde::Deserialize;
use strum::Display;

use std::{env, fs, path::PathBuf};

use crate::defaults;
use flakes::config::get_flakes_dir;

lazy_static! {
static ref CONFIG: Config<'static> = load_config();
Expand Down Expand Up @@ -72,11 +93,11 @@ fn config_from_str(input: &str) -> Config<'static> {
}

fn config_file(program: &str) -> String {
format!("{}/{}.yaml", defaults::FIRECRACKER_FLAKE_DIR, program)
format!("{}/{}.yaml", get_flakes_dir(), program)
}

fn config_dir(program: &str) -> String {
format!("{}/{}.d", defaults::FIRECRACKER_FLAKE_DIR, program)
format!("{}/{}.d", get_flakes_dir(), program)
}

#[derive(Deserialize)]
Expand Down
4 changes: 0 additions & 4 deletions firecracker-pilot/src/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ pub const FIRECRACKER_OVERLAY_DIR:&str =
"/var/lib/firecracker/storage";
pub const FIRECRACKER_TEMPLATE:&str =
"/etc/flakes/firecracker.json";
pub const FIRECRACKER_FLAKE_DIR: &str =
"/usr/share/flakes";
pub const FIRECRACKER_VMID_DIR: &str =
"/var/lib/firecracker/storage/tmp/flakes";
pub const FIRECRACKER_VSOCK_PREFIX: &str =
"/run/sci_cmd_";
pub const FIRECRACKER_VSOCK_PORT_START: u32 = 49200;
Expand Down
7 changes: 4 additions & 3 deletions firecracker-pilot/src/firecracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use std::io::{Write, SeekFrom, Seek};
use std::fs::File;
use serde::{Serialize, Deserialize};
use serde_json::{self};
use flakes::config::get_firecracker_ids_dir;

use crate::defaults;

Expand Down Expand Up @@ -163,7 +164,7 @@ pub fn create(program_name: &String) -> Result<(String, String), FlakeError> {
}
// setup VM ID file name
let vm_id_file_path = get_meta_file_name(
program_name, defaults::FIRECRACKER_VMID_DIR, "vmid"
program_name, &get_firecracker_ids_dir(), "vmid"
);

// get flake config sections
Expand Down Expand Up @@ -663,7 +664,7 @@ pub fn get_target_app_path(
}

pub fn init_meta_dirs() -> Result<(), CommandError> {
[defaults::FIRECRACKER_OVERLAY_DIR, defaults::FIRECRACKER_VMID_DIR].iter()
[defaults::FIRECRACKER_OVERLAY_DIR, &get_firecracker_ids_dir()].iter()
.filter(|path| !Path::new(path).is_dir())
.try_for_each(|path| mkdir(path, "777", User::ROOT))
}
Expand Down Expand Up @@ -783,7 +784,7 @@ pub fn gc(user: User, program_name: &String) -> Result<(), FlakeError> {
/*!
Garbage collect VMID files for which no VM exists anymore
!*/
let vmid_file_names: Vec<_> = fs::read_dir(defaults::FIRECRACKER_VMID_DIR)?
let vmid_file_names: Vec<_> = fs::read_dir(get_firecracker_ids_dir())?
.filter_map(|entry| entry.ok())
.filter_map(|x| x.path()
.to_str()
Expand Down
4 changes: 4 additions & 0 deletions flakes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
generic:
flakes_dir: /usr/share/flakes
podman_ids_dir: /tmp
firecracker_ids_dir: /tmp
4 changes: 4 additions & 0 deletions package/flake-pilot.spec
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,14 @@ install -m 644 firecracker-pilot/dracut/etc/dracut.conf.d/extramodules.conf \
install -m 755 %{buildroot}/usr/sbin/sci \
%{buildroot}/usr/lib/flake-pilot/sci

mkdir -p %{buildroot}/etc
install -m 644 flakes.yml %{buildroot}/etc/flakes.yml

%files
%defattr(-,root,root)
%dir /usr/share/flakes
%dir /etc/flakes
%config /etc/flakes.yml
/usr/bin/flake-ctl
%doc /usr/share/man/man8/flake-ctl.8.gz
%doc /usr/share/man/man8/flake-ctl-list.8.gz
Expand Down
30 changes: 26 additions & 4 deletions podman-pilot/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
//
// Copyright (c) 2023 SUSE Software Solutions Germany GmbH
//
// This file is part of flake-pilot
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
use flakes::user::User;
use lazy_static::lazy_static;
use serde::Deserialize;
use std::{env, path::PathBuf, fs};

use crate::defaults;
use flakes::config::get_flakes_dir;

lazy_static! {
static ref CONFIG: Config<'static> = load_config();
Expand Down Expand Up @@ -68,11 +90,11 @@ fn config_from_str(input: &str) -> Config<'static> {
}

fn config_file(program: &str) -> String {
format!("{}/{}.yaml", defaults::CONTAINER_FLAKE_DIR, program)
format!("{}/{}.yaml", get_flakes_dir(), program)
}

fn config_dir(program: &str) -> String {
format!("{}/{}.d", defaults::CONTAINER_FLAKE_DIR, program)
format!("{}/{}.d", get_flakes_dir(), program)
}

#[derive(Deserialize)]
Expand Down
2 changes: 0 additions & 2 deletions podman-pilot/src/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
pub const CONTAINER_FLAKE_DIR: &str = "/usr/share/flakes";
pub const CONTAINER_DIR: &str = "/var/lib/containers";
pub const CONTAINER_CID_DIR: &str = "/var/lib/containers/storage/tmp/flakes";
pub const GC_THRESHOLD: i32 = 20;
pub const HOST_DEPENDENCIES: &str = "removed";
11 changes: 6 additions & 5 deletions podman-pilot/src/podman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use std::io::{Write, Read};
use std::fs::File;
use std::io::Seek;
use std::io::SeekFrom;
use flakes::config::get_podman_ids_dir;

use crate::defaults;

Expand Down Expand Up @@ -120,7 +121,7 @@ pub fn create(
// setup container ID file name
let suffix = name.first().map(String::as_str).unwrap_or("");

let container_cid_file = format!("{}/{}{suffix}.cid", defaults::CONTAINER_CID_DIR, program_name);
let container_cid_file = format!("{}/{}{suffix}.cid", get_podman_ids_dir(), program_name);

// setup app command path name to call
let target_app_path = get_target_app_path(program_name);
Expand Down Expand Up @@ -494,9 +495,9 @@ pub fn init_cid_dir() -> Result<(), FlakeError> {
/*!
Create meta data directory structure
!*/
if ! Path::new(defaults::CONTAINER_CID_DIR).is_dir() {
if ! Path::new(&get_podman_ids_dir()).is_dir() {
chmod(defaults::CONTAINER_DIR, "755", User::ROOT)?;
mkdir(defaults::CONTAINER_CID_DIR, "777", User::ROOT)?;
mkdir(&get_podman_ids_dir(), "777", User::ROOT)?;
}
Ok(())
}
Expand Down Expand Up @@ -607,13 +608,13 @@ pub fn gc(user: User) -> Result<(), FlakeError> {
let mut cid_file_names: Vec<String> = Vec::new();
let mut cid_file_count: i32 = 0;
let paths;
match fs::read_dir(defaults::CONTAINER_CID_DIR) {
match fs::read_dir(get_podman_ids_dir()) {
Ok(result) => { paths = result },
Err(error) => {
return Err(FlakeError::IOError {
kind: format!("{:?}", error.kind()),
message: format!("fs::read_dir failed on {}: {}",
defaults::CONTAINER_CID_DIR, error
get_podman_ids_dir(), error
)
})
}
Expand Down

0 comments on commit f1b51d0

Please sign in to comment.