cargo_prosa/package/
deb.rs1use std::{
2 fs, io,
3 path::{Path, PathBuf},
4};
5
6use tera::Tera;
7
8use crate::{cargo::CargoMetadata, package::ASSETS_SYSTEMD_J2};
9
10pub struct DebPkg {
12 path: PathBuf,
13 ctx: tera::Context,
14}
15
16impl DebPkg {
17 const DEB_DATA_TARGET: &'static str = "prosa-deb";
18
19 pub fn new(path: PathBuf) -> io::Result<DebPkg> {
21 let package_metadata = CargoMetadata::load_package_metadata()?;
22 let mut ctx = tera::Context::new();
23 package_metadata.j2_context(&mut ctx);
24
25 ctx.insert(
27 "config",
28 &format!("/etc/ProSA/{}.yml", package_metadata.name),
29 );
30 ctx.insert("bin", &format!("/usr/bin/{}", package_metadata.name));
31
32 Ok(DebPkg { path, ctx })
33 }
34
35 fn get_binary_assets(name: &str) -> toml_edit::Array {
36 let mut binary_assets = toml_edit::Array::new();
37 binary_assets.push(format!("target/release/{name}"));
38 binary_assets.push("usr/bin/");
39 binary_assets.push("755");
40 binary_assets
41 }
42
43 fn get_config_assets(name: &str) -> toml_edit::Array {
44 let mut config_assets = toml_edit::Array::new();
45 config_assets.push(format!("target/{}/{}.yml", Self::DEB_DATA_TARGET, name));
46 config_assets.push("etc/ProSA/");
47 config_assets.push("644");
48 config_assets
49 }
50
51 fn get_readme_assets(name: &str) -> toml_edit::Array {
52 let mut readme_assets = toml_edit::Array::new();
53 readme_assets.push("README.md");
54 readme_assets.push(format!("usr/share/doc/{name}/README"));
55 readme_assets.push("644");
56 readme_assets
57 }
58
59 pub fn add_deb_pkg_metadata(deb_table: &mut toml_edit::Table, name: &str) {
61 if !deb_table.contains_key("depends") {
62 deb_table.insert(
63 "depends",
64 toml_edit::Item::Value(toml_edit::Value::String(toml_edit::Formatted::new(
65 "$auto, libssl3".to_string(),
66 ))),
67 );
68 }
69
70 if !deb_table.contains_key("maintainer-scripts") {
71 deb_table.insert(
72 "maintainer-scripts",
73 toml_edit::Item::Value(format!("target/{}/", Self::DEB_DATA_TARGET).into()),
74 );
75 }
76
77 if !deb_table.contains_key("assets") {
78 let mut assets = toml_edit::Array::new();
80
81 assets.push(Self::get_binary_assets(name));
82 assets.push(Self::get_config_assets(name));
83
84 if Path::new("README.md").is_file() {
85 assets.push(Self::get_readme_assets(name));
86 }
87
88 deb_table.insert("assets", toml_edit::Item::Value(assets.into()));
89 }
90
91 if let Some(toml_edit::Item::Value(toml_edit::Value::InlineTable(systemd_units))) =
92 deb_table.get_mut("systemd-units")
93 {
94 if !systemd_units.contains_key("enable") {
95 systemd_units.insert(
96 "enable",
97 toml_edit::Value::Boolean(toml_edit::Formatted::new(true)),
98 );
99 }
100 } else {
101 let mut inline_table = toml_edit::InlineTable::new();
102
103 inline_table.insert(
104 "enable",
105 toml_edit::Value::Boolean(toml_edit::Formatted::new(true)),
106 );
107
108 deb_table.insert(
109 "systemd-units",
110 toml_edit::Item::Value(toml_edit::Value::InlineTable(inline_table)),
111 );
112 }
113 }
114
115 pub fn write_package_data(&self) -> io::Result<()> {
117 let name = self
118 .ctx
119 .get("name")
120 .and_then(|n| n.as_str())
121 .ok_or(io::Error::new(
122 io::ErrorKind::InvalidData,
123 "Missing package name",
124 ))?;
125 let pkg_data_path = self.path.join(Self::DEB_DATA_TARGET);
126 fs::create_dir_all(&pkg_data_path)?;
127
128 fs::copy(
130 self.path.join("config.yml"),
131 pkg_data_path.join(format!("{name}.yml")),
132 )?;
133
134 let mut tera_build = Tera::default();
136 tera_build
137 .add_raw_template("prosa.service", ASSETS_SYSTEMD_J2)
138 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
139
140 let main_file = fs::File::create(pkg_data_path.join("service"))?;
141 tera_build
142 .render_to("prosa.service", &self.ctx, main_file)
143 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
144 }
145}