mirror of
https://codeberg.org/demostf/backup.git
synced 2026-06-03 09:54:18 +02:00
allow specifying access key for backing up private demos
This commit is contained in:
parent
24f9594223
commit
a1b3b598e6
6 changed files with 50 additions and 15 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -78,6 +78,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"main_error",
|
||||
"md5 0.8.0",
|
||||
"secretfile",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
|
|
@ -940,6 +941,12 @@ version = "1.0.23"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||
|
||||
[[package]]
|
||||
name = "secretfile"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e1f99fdbcc14f9d8292bd680cb6ec6c265d141e5073f61024fcddc891e405c1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ tracing = "0.1.44"
|
|||
tracing-subscriber = "0.3.23"
|
||||
futures-util = "0.3.32"
|
||||
md5 = "0.8.0"
|
||||
secretfile = "0.1.1"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
|
|||
12
README.md
12
README.md
|
|
@ -2,13 +2,19 @@
|
|||
|
||||
Backup program for demos.tf demos.
|
||||
|
||||
A simple program that incrementally backs up every demo file from demos.tf to a local directory.
|
||||
A simple program that incrementally backs up every demo file from demos.tf to a
|
||||
local directory.
|
||||
|
||||
## Usage
|
||||
|
||||
The following environment variables are required for the program
|
||||
The following environment variables are required for the program:
|
||||
|
||||
STORAGE_ROOT: The directory to store the demos in
|
||||
STATE_FILE: The textfile to store the backup progress in between runs
|
||||
|
||||
The program will look in a .env file if the variables aren't set in the environment
|
||||
The following optional environment variables can additionaly be supplied:
|
||||
|
||||
ACCESS_KEY_FILE: File containig the api access key, required to backup private demos
|
||||
|
||||
The program will look in a .env file if the variables aren't set in the
|
||||
environment
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ in {
|
|||
default = "*:0/10";
|
||||
description = "Interval to run the service";
|
||||
};
|
||||
keyFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = "access key file path";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
|
|
@ -48,15 +52,24 @@ in {
|
|||
systemd.services.demostf-backup = {
|
||||
description = "Backup demos for demos.tf";
|
||||
|
||||
environment = {
|
||||
STORAGE_ROOT = cfg.target;
|
||||
SOURCE = cfg.api;
|
||||
STATE_FILE = cfg.stateFile;
|
||||
RUST_LOG = cfg.logLevel;
|
||||
};
|
||||
environment =
|
||||
{
|
||||
STORAGE_ROOT = cfg.target;
|
||||
SOURCE = cfg.api;
|
||||
STATE_FILE = cfg.stateFile;
|
||||
RUST_LOG = cfg.logLevel;
|
||||
}
|
||||
// optionalAttrs (cfg.keyFile != null) {
|
||||
ACCESS_KEY_FILE = "$CREDENTIALS_DIRECTORY/api_key";
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/demostf-backup";
|
||||
|
||||
LoadCredential = optionals (cfg.keyFile != null) [
|
||||
"api_key:${cfg.keyFile}"
|
||||
];
|
||||
|
||||
ReadWritePaths = [cfg.target cfg.stateFile];
|
||||
Restart = "on-failure";
|
||||
User = cfg.user;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::store::Store;
|
||||
use crate::Error;
|
||||
use crate::store::Store;
|
||||
use demostf_client::{ApiClient, Demo, ListOrder, ListParams};
|
||||
use std::time::Duration;
|
||||
use tokio::time::timeout;
|
||||
|
|
@ -11,11 +11,13 @@ pub struct Backup {
|
|||
}
|
||||
|
||||
impl Backup {
|
||||
pub fn new(store: Store) -> Self {
|
||||
Backup {
|
||||
store,
|
||||
client: ApiClient::new(),
|
||||
pub fn new(store: Store, access_key: Option<String>) -> Self {
|
||||
let mut client = ApiClient::new();
|
||||
if let Some(access_key) = access_key {
|
||||
info!("using access key");
|
||||
client.set_access_key(access_key);
|
||||
}
|
||||
Backup { store, client }
|
||||
}
|
||||
|
||||
#[instrument(skip_all, fields(demo.id = demo.id, demo.name = name))]
|
||||
|
|
|
|||
|
|
@ -29,7 +29,13 @@ async fn main() -> Result<(), MainError> {
|
|||
let mut args: HashMap<_, _> = dotenvy::vars().collect();
|
||||
let store = Store::new(args.get("STORAGE_ROOT").expect("no STORAGE_ROOT set"));
|
||||
let state_path = PathBuf::from(args.remove("STATE_FILE").expect("no STATE_FILE set"));
|
||||
let backup = Backup::new(store);
|
||||
let key_file = args.remove("ACCESS_KEY_FILE");
|
||||
let access_key = key_file
|
||||
.as_deref()
|
||||
.map(secretfile::load)
|
||||
.transpose()?
|
||||
.filter(|key| !key.is_empty());
|
||||
let backup = Backup::new(store, access_key);
|
||||
|
||||
let last_page = if state_path.is_file() {
|
||||
max(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue