difftreelog
refactor nix secret module
in: trunk
17 files changed
Cargo.tomldiffbeforeafterboth1[workspace]1[workspace]2members = ["crates/*", "cmds/*"]2members = ["crates/*", "cmds/*"]3resolver = "2"3resolver = "2"4package.version = "0.1.0"455[workspace.dependencies]6[workspace.dependencies]6nixlike = { path = "./crates/nixlike" }7nixlike = { path = "./crates/nixlike" }cmds/fleet/src/cmds/secrets/mod.rsdiffbeforeafterboth1use crate::{1use crate::{2 better_nix_eval::Field,2 better_nix_eval::Field,3 command::MyCommand,4 fleetdata::{FleetSecret, FleetSharedSecret, SecretData},3 fleetdata::{FleetSecret, FleetSharedSecret, SecretData},5 host::Config,4 host::Config,6 nix_go, nix_go_json,5 nix_go, nix_go_json,9use chrono::{DateTime, Utc};8use chrono::{DateTime, Utc};10use clap::Parser;9use clap::Parser;11use owo_colors::OwoColorize;10use owo_colors::OwoColorize;12use serde::{de::DeserializeOwned, Deserialize};11use serde::Deserialize;13use std::{12use std::{14 collections::{BTreeSet, HashSet},13 collections::{BTreeSet, HashSet},15 io::{self, Cursor, Read},14 io::{self, Cursor, Read},16 path::{Path, PathBuf},15 path::PathBuf,17 str::FromStr,18};16};19use tabled::{Table, Tabled};17use tabled::{Table, Tabled};20use tempfile::tempdir;21use tokio::fs::{self, read_to_string};18use tokio::fs::read_to_string;22use tracing::{error, info, info_span, warn, Instrument};19use tracing::{error, info, info_span, warn, Instrument};232024#[derive(Parser)]21#[derive(Parser)]162}159}163160164async fn generate_pure(161async fn generate_pure(165 config: &Config,162 _config: &Config,166 _display_name: &str,163 _display_name: &str,167 secret: Field,164 _secret: Field,168 default_generator: Field,165 _default_generator: Field,169 owners: &[String],166 _owners: &[String],170) -> Result<FleetSecret> {167) -> Result<FleetSecret> {171 // TODO: pure secrets are supposed to be generated by nix daemon itself,172 // inside of a sandbox... But we aren't here yet.173 let config_field = &config.config_unchecked_field;174 let generator = nix_go!(secret.generator);175 let default_pkgs = &config.default_pkgs;176177 let call_package = nix_go!(default_pkgs.callPackage);178179 let generator = nix_go!(call_package(generator)(Obj {}));180 let generator = generator.build().await?;181 let generator = generator182 .get("out")183 .ok_or_else(|| anyhow!("missing generate out"))?;184185 let mut recipients = String::new();186 for owner in owners {187 let key = config.key(owner).await?;188 recipients.push_str(&format!("-r \"{key}\" "));189 }190 recipients.push_str("-e");191192 let out = tempdir()?;193194 let mut gen = MyCommand::new(generator);195 gen.env("rageArgs", recipients);196 gen.env(197 "out",198 out.path().to_str().expect("sane tempdir should be utf-8"),199 );200 gen.run().await.context("impure generator")?;201202 {203 let mut marker_path = out.path().to_owned();204 marker_path.push("marker");205 let marker = fs::read_to_string(&marker_path).await?;206 ensure!(marker == "SUCCESS", "generation not succeeded");168 bail!("pure generators are broken for now")207 }208209 let mut public_path = out.path().to_owned();210 public_path.push("public");211 let mut secret_path = out.path().to_owned();212 secret_path.push("secret");213 let public = fs::read_to_string(&public_path).await.ok();214 let secret = fs::read(&secret_path).await.ok();215 if let Some(secret) = &secret {216 ensure!(217 age::Decryptor::new(Cursor::new(&secret)).is_ok(),218 "builder produced non-encrypted value as secret, this is highly insecure, and not allowed."219 );220 }221222 let mut created_at_path = out.path().to_owned();223 created_at_path.push("created_at");224 let mut expires_at_path = out.path().to_owned();225 expires_at_path.push("expires_at");226227 async fn read_value<T: FromStr>(path: &Path) -> Result<T> {228 dbg!(path);229 let raw = fs::read(path).await?;230 let raw = String::from_utf8(raw)?;231 raw.parse().map_err(|_| anyhow!("fromStr failed"))232 }233234 let created_at = read_value(&created_at_path).await?;235 let expires_at = read_value(&expires_at_path).await.ok();236237 Ok(FleetSecret {238 created_at,239 expires_at,240 public,241 secret: secret.map(SecretData),242 })243}169}244async fn generate_impure(170async fn generate_impure(245 config: &Config,171 config: &Config,248 default_generator: Field,174 default_generator: Field,249 owners: &[String],175 owners: &[String],250) -> Result<FleetSecret> {176) -> Result<FleetSecret> {251 let config_field = &config.config_unchecked_field;252 let generator = nix_go!(secret.generator);177 let generator = nix_go!(secret.generator);253254 let on: String = nix_go_json!(default_generator.impureOn);178 let on: Option<String> = nix_go_json!(default_generator.impureOn);179180 let host = if let Some(on) = &on {181 config.host(on).await?182 } else {183 config.local_host()184 };185 let on_pkgs = host.pkgs().await?;255 let call_package = nix_go!(186 let call_package = nix_go!(on_pkgs.callPackage);256 config_field.hosts[{ on }]187 let mk_encrypt_secret = nix_go!(on_pkgs.mkEncryptSecret);257 .nixosSystem188258 .config189 let mut recipients = Vec::new();259 .nixpkgs190 for owner in owners {260 .resolvedPkgs261 .callPackage262 );263264 let host = config.host(&on).await?;191 let key = config.key(owner).await?;192 recipients.push(key);193 }194 let encrypt = nix_go!(mk_encrypt_secret(Obj {195 recipients: { recipients },196 }));265197266 let generator = nix_go!(call_package(generator)(Obj {}));198 let generator = nix_go!(call_package(generator)(Obj {199 encrypt,200 rustfmt_please_newline: { true },201 }));202267 let generator = generator.build().await?;203 let generator = generator.build().await?;268 let generator = generator204 let generator = generator269 .get("out")205 .get("out")270 .ok_or_else(|| anyhow!("missing generateImpure out"))?;206 .ok_or_else(|| anyhow!("missing generateImpure out"))?;271 let generator = host.remote_derivation(generator).await?;207 let generator = host.remote_derivation(generator).await?;272208273 let mut recipients = String::new();274 for owner in owners {275 let key = config.key(owner).await?;209 let out_parent = host.mktemp_dir().await?;276 recipients.push_str(&format!("-r \"{key}\" "));277 }278 recipients.push_str("-e");279280 let out = host.mktemp_dir().await?;210 let out = format!("{out_parent}/out");281211282 let mut gen = host.cmd(generator).await?;212 let mut gen = host.cmd(generator).await?;283 gen.env("rageArgs", recipients).env("out", &out);213 gen.env("out", &out);214 if on.is_none() {215 // This path is local, thus we can feed `OsString` directly to env var... But I don't think that's necessary to handle.216 let project_path: String = config217 .directory218 .clone()219 .into_os_string()220 .into_string()221 .map_err(|s| anyhow!("fleet project path is not utf-8: {s:?}"))?;222 gen.env("FLEET_PROJECT", project_path);223 }284 gen.run().await.context("impure generator")?;224 gen.run().await.context("impure generator")?;285225286 {226 {551 }491 }552 Secret::ReadPublic {492 Secret::ReadPublic { name, machine } => {553 name,554 machine,555 } => {556 let secret = config.host_secret(&machine, &name)?;493 let secret = config.host_secret(&machine, &name)?;557 let Some(public) = secret.public else {494 let Some(public) = secret.public else {cmds/fleet/src/host.rsdiffbeforeafterboth54 pub local: bool,54 pub local: bool,55 pub session: OnceLock<Arc<openssh::Session>>,55 pub session: OnceLock<Arc<openssh::Session>>,565657 pub nixos_config: Field,57 pub nixos_config: Option<Field>,58}58}59impl ConfigHost {59impl ConfigHost {60 async fn open_session(&self) -> Result<Arc<openssh::Session>> {60 async fn open_session(&self) -> Result<Arc<openssh::Session>> {169 }169 }170170171 pub async fn list_configured_secrets(&self) -> Result<Vec<String>> {171 pub async fn list_configured_secrets(&self) -> Result<Vec<String>> {172 let nixos = &self.nixos_config;172 let Some(nixos) = &self.nixos_config else {173 return Ok(vec![]);174 };173 let secrets = nix_go!(nixos.secrets);175 let secrets = nix_go!(nixos.secrets);174 let mut out = Vec::new();176 let mut out = Vec::new();175 for name in secrets.list_fields().await? {177 for name in secrets.list_fields().await? {183 Ok(out)185 Ok(out)184 }186 }185 pub async fn secret_field(&self, name: &str) -> Result<Field> {187 pub async fn secret_field(&self, name: &str) -> Result<Field> {186 let nixos = &self.nixos_config;188 let Some(nixos) = &self.nixos_config else {189 bail!("host is virtual and has no secrets");190 };187 Ok(nix_go!(nixos.secrets[{ name }]))191 Ok(nix_go!(nixos.secrets[{ name }]))188 }192 }193194 /// Packages for this host, resolved with nixpkgs overlays195 pub async fn pkgs(&self) -> Result<Field> {196 let Some(nixos) = &self.nixos_config else {197 return Ok(self.config.default_pkgs.clone());198 };199 Ok(nix_go!(nixos.nixpkgs.resolvedPkgs))200 }189}201}190202191impl Config {203impl Config {202 self.opts.localhost.as_ref().map(|s| s as &str) == Some(host)214 self.opts.localhost.as_ref().map(|s| s as &str) == Some(host)203 }215 }216217 pub fn local_host(&self) -> ConfigHost {218 ConfigHost {219 config: self.clone(),220 name: "<virtual localhost>".to_owned(),221 local: true,222 session: OnceLock::new(),223 nixos_config: None,224 }225 }204226205 pub async fn host(&self, name: &str) -> Result<ConfigHost> {227 pub async fn host(&self, name: &str) -> Result<ConfigHost> {206 let config = &self.config_unchecked_field;228 let config = &self.config_unchecked_field;210 name: name.to_owned(),232 name: name.to_owned(),211 local: self.is_local(name),233 local: self.is_local(name),212 session: OnceLock::new(),234 session: OnceLock::new(),213 nixos_config,235 nixos_config: Some(nixos_config),214 })236 })215 }237 }216 pub async fn list_hosts(&self) -> Result<Vec<ConfigHost>> {238 pub async fn list_hosts(&self) -> Result<Vec<ConfigHost>> {cmds/fleet/src/main.rsdiffbeforeafterboth111112mod fleetdata;12mod fleetdata;131314use std::time::Duration;15use std::{ffi::OsString, process::ExitCode};14use std::{ffi::OsString, process::ExitCode};161517use anyhow::{bail, Result};16use anyhow::{bail, Result};158 let reg = tracing_subscriber::registry().with({157 let reg = tracing_subscriber::registry().with({159 let sub = tracing_subscriber::fmt::layer()158 let sub = tracing_subscriber::fmt::layer()160 .without_time()159 .without_time()161 .with_target(true);160 .with_target(false);162 #[cfg(feature = "indicatif")]161 #[cfg(feature = "indicatif")]163 let sub = sub.with_writer(indicatif_layer.get_stdout_writer());162 let sub = sub.with_writer(indicatif_layer.get_stdout_writer());164 sub.with_filter(filter) // .withou,163 sub.with_filter(filter) // .withou,cmds/install-secrets/src/main.rsdiffbeforeafterboth13use std::path::Path;13use std::path::Path;14use std::str::{from_utf8, FromStr};14use std::str::{from_utf8, FromStr};15use std::{collections::HashMap, path::PathBuf};15use std::{collections::HashMap, path::PathBuf};16use tracing::{error, info, warn};16use tracing::{error, info, info_span, warn};17use tracing_subscriber::filter::LevelFilter;17use tracing_subscriber::filter::LevelFilter;18use tracing_subscriber::EnvFilter;18use tracing_subscriber::EnvFilter;1919213213214 let mut failed = false;214 let mut failed = false;215 for (name, value) in data {215 for (name, value) in data {216 info!("initializing secret {name}");216 let _span = info_span!("init", name = name);217 if let Err(e) = init_secret(&identity, value) {217 if let Err(e) = init_secret(&identity, value) {218 error!(218 error!("{e}");219 "{:?}",220 e.context(format!("failed to initialize secret {}", name))221 );222 failed = true;219 failed = true;223 }220 }237 .from_env_lossy(),234 .from_env_lossy(),238 )235 )239 .without_time()236 .without_time()237 .with_target(false)240 .init();238 .init();241239242 let opts = Opts::parse();240 let opts = Opts::parse();crates/better-command/src/handler.rsdiffbeforeafterboth274 #[cfg(feature = "indicatif")]274 #[cfg(feature = "indicatif")]275 span.pb_set_message(&process_message(s.trim()));275 span.pb_set_message(&process_message(s.trim()));276 #[cfg(not(feature = "indicatif"))]276 #[cfg(not(feature = "indicatif"))]277 {278 let _span = span.enter();277 info!("{}", process_message(s));279 info!("{}", process_message(s));280 }278 } else {281 } else {279 warn!("bad fields: {fields:?}");282 warn!("bad fields: {fields:?}");280 }283 }crates/better-command/src/lib.rsdiffbeforeafterboth1mod handler;1mod handler;2pub use handler::{Handler, PlainHandler, NoopHandler, NixHandler, ClonableHandler};2pub use handler::{ClonableHandler, Handler, NixHandler, NoopHandler, PlainHandler};334pub fn add(left: usize, right: usize) -> usize {4pub fn add(left: usize, right: usize) -> usize {5 left + right5 left + rightflake.lockdiffbeforeafterboth1{1{2 "nodes": {2 "nodes": {3 "crane": {4 "inputs": {5 "nixpkgs": [6 "nixpkgs"7 ]8 },9 "locked": {10 "lastModified": 1712681629,11 "narHash": "sha256-bMDXn4AkTXLCpoZbII6pDGoSeSe9gI87jxPsHRXgu/E=",12 "owner": "ipetkov",13 "repo": "crane",14 "rev": "220387ac8e99cbee0ca4c95b621c4bc782b6a235",15 "type": "github"16 },17 "original": {18 "owner": "ipetkov",19 "repo": "crane",20 "type": "github"21 }22 },3 "flake-utils": {23 "flake-utils": {4 "inputs": {24 "inputs": {5 "systems": "systems"25 "systems": "systems"18 "type": "github"38 "type": "github"19 }39 }20 },40 },21 "flake-utils_2": {22 "inputs": {23 "systems": "systems_2"24 },25 "locked": {26 "lastModified": 1705309234,27 "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",28 "owner": "numtide",29 "repo": "flake-utils",30 "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",31 "type": "github"32 },33 "original": {34 "owner": "numtide",35 "repo": "flake-utils",36 "type": "github"37 }38 },39 "nixpkgs": {41 "nixpkgs": {40 "locked": {42 "locked": {41 "lastModified": 1708177587,43 "lastModified": 1708177587,54 },56 },55 "root": {57 "root": {56 "inputs": {58 "inputs": {59 "crane": "crane",57 "flake-utils": "flake-utils",60 "flake-utils": "flake-utils",58 "nixpkgs": "nixpkgs",61 "nixpkgs": "nixpkgs",59 "rust-overlay": "rust-overlay"62 "rust-overlay": "rust-overlay"60 }63 }61 },64 },62 "rust-overlay": {65 "rust-overlay": {63 "inputs": {66 "inputs": {64 "flake-utils": "flake-utils_2",67 "flake-utils": [68 "flake-utils"69 ],65 "nixpkgs": [70 "nixpkgs": [66 "nixpkgs"71 "nixpkgs"67 ]72 ]94 "repo": "default",99 "repo": "default",95 "type": "github"100 "type": "github"96 }101 }97 },102 }98 "systems_2": {99 "locked": {100 "lastModified": 1681028828,101 "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",102 "owner": "nix-systems",103 "repo": "default",104 "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",105 "type": "github"106 },107 "original": {108 "owner": "nix-systems",109 "repo": "default",110 "type": "github"111 }112 }113 },103 },114 "root": "root",104 "root": "root",115 "version": 7105 "version": 7flake.nixdiffbeforeafterboth5 nixpkgs.url = "github:nixos/nixpkgs/master";5 nixpkgs.url = "github:nixos/nixpkgs/master";6 rust-overlay = {6 rust-overlay = {7 url = "github:oxalica/rust-overlay";7 url = "github:oxalica/rust-overlay";8 inputs.nixpkgs.follows = "nixpkgs";8 inputs = {9 nixpkgs.follows = "nixpkgs";10 flake-utils.follows = "flake-utils";11 };9 };12 };10 flake-utils = {url = "github:numtide/flake-utils";};13 flake-utils.url = "github:numtide/flake-utils";14 crane = {15 url = "github:ipetkov/crane";16 inputs.nixpkgs.follows = "nixpkgs";17 };11 };18 };12 outputs = {19 outputs = {13 self,20 self,14 rust-overlay,21 rust-overlay,15 flake-utils,22 flake-utils,16 nixpkgs,23 nixpkgs,24 crane,17 }:25 }:18 with nixpkgs.lib;26 with nixpkgs.lib;19 {27 {26 inherit system;34 inherit system;27 overlays = [(import rust-overlay)];35 overlays = [(import rust-overlay)];28 };36 };29 llvmPkgs = pkgs.buildPackages.llvmPackages_11;37 rust = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;30 rust =38 craneLib = (crane.mkLib pkgs).overrideToolchain rust;31 (pkgs.rustChannelOf {32 date = "2024-02-10";33 channel = "nightly";34 })35 .default36 .override {extensions = ["rust-src" "rust-analyzer"];};37 in {39 in {38 packages = (import ./pkgs) pkgs pkgs;40 packages = import ./pkgs {41 inherit (pkgs) callPackage;42 inherit craneLib;43 };39 devShell = (pkgs.mkShell.override {stdenv = llvmPkgs.stdenv;}) {44 devShell = craneLib.devShell {40 nativeBuildInputs = with pkgs; [45 nativeBuildInputs = with pkgs; [41 alejandra46 alejandra42 rust43 lld47 lld44 cargo-edit48 cargo-edit45 cargo-udeps49 cargo-udepslib/default.nixdiffbeforeafterboth10 hosts,10 hosts,11 modules,11 modules,12 globalModules ? [],12 globalModules ? [],13 extraFleetLib ? {},13 }: let14 }: let14 hostNames = nixpkgs.lib.attrNames hosts;15 hostNames = nixpkgs.lib.attrNames hosts;15 fleetLib = import ./fleetLib.nix {16 fleetLib =17 (import ./fleetLib.nix {16 inherit nixpkgs hostNames;18 inherit nixpkgs hostNames;17 };19 })20 // extraFleetLib;18 in let21 in let19 root = nixpkgs.lib.evalModules {22 root = nixpkgs.lib.evalModules {20 modules =23 modules =lib/fleetLib.nixdiffbeforeafterboth40 # Some generators use mkDefault, but optionDefault is set by nixpkgs.40 # Some generators use mkDefault, but optionDefault is set by nixpkgs.41 mkFleetGeneratorDefault = mkOverride 1001;41 mkFleetGeneratorDefault = mkOverride 1001;4243 mkPassword = {size ? 32}: {44 coreutils,45 encrypt,46 mkSecretGenerator,47 }:48 mkSecretGenerator {49 script = ''50 ${coreutils}/bin/tr -dc 'A-Za-z0-9!?%=' < /dev/random \51 | ${coreutils}/bin/head -c ${toString size} \52 | ${encrypt} > $out/secret53 '';54 };5556 mkRsa = {size ? 4096}: {57 openssl,58 encrypt,59 mkSecretGenerator,60 }:61 mkSecretGenerator {62 script = ''63 ${openssl}/bin/openssl genrsa -out rsa_private.key ${toString size}64 ${openssl}/bin/openssl rsa -in rsa_private.key -pubout -out rsa_public.key6566 sudo cat rsa_private.key | ${encrypt} > $out/secret67 sudo cat rsa_public.key > $out/public68 '';69 };42}70}4371modules/fleet/secrets.nixdiffbeforeafterboth8with fleetLib; let8with fleetLib; let9 sharedSecret = with types; ({config, ...}: {9 sharedSecret = with types; ({config, ...}: {10 options = {10 options = {11 managed = mkOption {12 type = bool;13 description = ''14 Is this secret managed by configuration (I.e will work with reencrypt/etc), or it is configured by user15 '';16 };1711 expectedOwners = mkOption {18 expectedOwners = mkOption {12 type = nullOr (listOf str);19 type = nullOr (listOf str);146 overlays = [153 overlays = [147 (final: prev: let154 (final: prev: let148 lib = final.lib;155 lib = final.lib;156 inherit (lib) strings;157 inherit (strings) escapeShellArgs;149 in {158 in {150 mkPassword = {size ? 32}:159 mkEncryptSecret = {160 rage ? prev.rage,161 recipients,162 }:151 final.mkSecretGenerator ''163 prev.writeShellScript "encryptor" ''152 ${final.coreutils}/bin/tr -dc 'A-Za-z0-9!?%=' < /dev/random \164 #!/bin/sh153 | ${final.coreutils}/bin/head -c ${toString size} \165 exec ${rage}/bin/rage ${escapeShellArgs recipients} -e "$@"154 | encrypt > $out/secret155 '';166 '';156 mkRsa = {size ? 4096}:157 final.mkSecretGenerator ''158 ${final.openssl}/bin/openssl genrsa -out rsa_private.key ${toString size}159 ${final.openssl}/bin/openssl rsa -in rsa_private.key -pubout -out rsa_public.key160161 sudo cat rsa_private.key | encrypt > $out/secret162 sudo cat rsa_public.key > $out/public163 '';164 # TODO: Move to fleet167 # TODO: Move to fleet165 # TODO: Merge both generators to one with consistent options syntax?168 # TODO: Merge both generators to one with consistent options syntax?166 # Impure generator is built on local machine, then built closure is copied to remote machine,169 # Impure generator is built on local machine, then built closure is copied to remote machine,167 # and then it is ran in inpure context, so that this generator may access HSMs and other things.170 # and then it is ran in inpure context, so that this generator may access HSMs and other things.168 mkImpureSecretGenerator = generatorText: machine:171 mkImpureSecretGenerator = {169 (prev.writeShellScript "impureGenerator.sh" ''172 script,170 #!/bin/sh173 # If set - script will be run on remote machine, otherwise it will be run with fleet project in CWD171 set -eu174 # (Some secrets-encryption-in-git/managed PKI solution is expected)172175 impureOn ? null,173 # TODO: Provide encryption function as script passed to `callPackage generator {encrypt = ...;}`176 }:174 function encrypt() {177 (prev.writeShellScript "impureGenerator.sh" ''175 eval ${final.rage}/bin/rage $rageArgs178 #!/bin/sh176 }179 set -eu177180 cd /var/empty178 created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")181179 echo -n $created_at > $out/created_at182 created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")180183181 ${generatorText}184 ${script}182185183 echo -n SUCCESS > $out/marker186 if ! test -d $out; then184 '')187 echo "impure generator script did not produce expected \$out output"188 exit 1189 fi190191 echo -n $created_at > $out/created_at192 echo -n SUCCESS > $out/marker193 '')185 .overrideAttrs (old: {194 .overrideAttrs (old: {186 passthru = {195 passthru = {196 inherit impureOn;187 generatorKind = "impure";197 generatorKind = "impure";188 impureOn = machine;189 };198 };190 });199 });191 # TODO: Implement consistent naming200 # Pure generators are disabled for now192 # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...193 # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.194 mkSecretGenerator = generatorText:201 mkSecretGenerator = {script}: final.mkImpureSecretGenerator {inherit script;};195 (prev.writeShellScript "generator.sh" ''202196 #!/bin/sh203 # TODO: Implement consistent naming197 set -eu204 # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...193 # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.194 mkSecretGenerator = generatorText:201 mkSecretGenerator = {script}: final.mkImpureSecretGenerator {inherit script;};195 (prev.writeShellScript "generator.sh" ''202196 #!/bin/sh203 # TODO: Implement consistent naming197 set -eu204 # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...198 # TODO: User should create output directory by themselves.205 # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.199 cd $out206 # mkSecretGenerator = {script}:200207 # (prev.writeShellScript "generator.sh" ''201 # TODO: Provide encryption function as script passed to `callPackage generator {encrypt = ...;}`208 # #!/bin/sh202 function encrypt() {209 # set -eu203 eval ${final.rage}/bin/rage $rageArgs210 # # TODO: make nix daemon build secret, not just the script.204 }211 # cd /var/empty205212 #206 created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")213 # created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")207 echo -n $created_at > $out/created_at214 #208215 # ${script}209 ${generatorText}216 # if ! test -d $out; then210217 # echo "impure generator script did not produce expected \$out output"211 echo -n SUCCESS > $out/marker218 # exit 1212 '')219 # fi213 .overrideAttrs (old: {220 #214 passthru = {221 # echo -n $created_at > $out/created_at215 generatorKind = "pure";222 # echo -n SUCCESS > $out/marker216 };223 # '')217 # TODO: make nix daemon build secret, not just the script.224 # .overrideAttrs (old: {218 # __impure = true;225 # passthru = {219 });226 # generatorKind = "pure";227 # };228 # # TODO: make nix daemon build secret, not just the script.229 # # __impure = true;230 # });220 })231 })221 ];232 ];222 };233 };nixos/fleetPkgs.nixdiffbeforeafterboth1{ ... }: {1{...}: {2 nixpkgs.overlays = [ (import ../pkgs) ];2 nixpkgs.overlays = [3 # Not using craneLib here, because we don't want to have two different rust versions for some platforms.4 (final: prev: {5 fleet-install-secrets = prev.callPackage ({rustPlatform}:6 rustPlatform.buildRustPackage rec {7 pname = "fleet-install-secrets";8 name = "${pname}";910 src = ../.;11 strictDeps = true;1213 buildAndTestSubdir = "cmds/install-secrets";1415 cargoLock = {16 lockFile = ../Cargo.lock;17 outputHashes = {18 "alejandra-3.0.0" = "sha256-lStDIPizbJipd1JpNKX1olBKzyIosyC2U/mVFwJPcZE=";19 };20 };21 }) {};22 })23 ];3}24}425pkgs/default.nixdiffbeforeafterboth1{2 callPackage,3 craneLib,1pkgs: super:4}: rec {2with pkgs;5 default = fleet;3{64 fleet-install-secrets = callPackage ./fleet-install-secrets.nix { };7 fleet-install-secrets = callPackage ./fleet-install-secrets.nix {inherit craneLib;};5 fleet = callPackage ./fleet.nix { };8 fleet = callPackage ./fleet.nix {inherit craneLib;};6}9}710pkgs/fleet-install-secrets.nixdiffbeforeafterboth1{ rustPlatform, lib }:1{craneLib}:23rustPlatform.buildRustPackage rec {2craneLib.buildPackage rec {4 pname = "fleet-install-secrets";3 pname = "fleet-install-secrets";5 version = "0.0.1";6 name = "${pname}-${version}";748 src = ../.;5 src = craneLib.cleanCargoSource (craneLib.path ../.);9 buildAndTestSubdir = "cmds/install-secrets";6 strictDeps = true;710 cargoLock = {8 cargoExtraArgs = "--locked -p ${pname}";11 lockFile = ../Cargo.lock;12 outputHashes = {13 "alejandra-3.0.0" = "sha256-lStDIPizbJipd1JpNKX1olBKzyIosyC2U/mVFwJPcZE=";14 };15 };16}9}1710pkgs/fleet.nixdiffbeforeafterboth1{ rustPlatform }:1{craneLib}:23rustPlatform.buildRustPackage rec {2craneLib.buildPackage rec {4 pname = "fleet";3 pname = "fleet";5 version = "0.0.1";6 name = "${pname}-${version}";748 src = ../.;5 src = craneLib.cleanCargoSource (craneLib.path ../.);9 cargoBuildFlags = "-p ${pname}";6 strictDeps = true;710 cargoLock = {8 cargoExtraArgs = "--locked -p ${pname}";11 lockFile = ../Cargo.lock;12 outputHashes = {13 "alejandra-3.0.0" = "sha256-YSdHsJ73G7TEFzbmpZ2peuMefIa9/vNB2g+xdiyma3U=";14 };15 };16}9}1710rust-toolchain.tomldiffbeforeafterbothno changes