feat: add basic functionality

This commit is contained in:
Jan Christian Grünhage 2017-12-12 19:27:51 +01:00
parent d8983e5d63
commit 5c09e4fea5
Signed by: jcgruenhage
GPG Key ID: 6594C449C633D10C
6 changed files with 543 additions and 12 deletions

11
.gitignore vendored
View File

@ -1,12 +1,3 @@
# ---> Rust
# Generated by Cargo
# will have compiled files and executables
/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
.idea

275
Cargo.lock generated Normal file
View File

@ -0,0 +1,275 @@
[[package]]
name = "ansi_term"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "atty"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chrono"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clap"
version = "2.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fern"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.2.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-iter"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_syscall"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "run-parts-gen-rs"
version = "0.1.0"
dependencies = [
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fern 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive_internals"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "strsim"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synom"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "termion"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "toml"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-width"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9"
"checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f"
"checksum fern 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f0297637852905c7ce4cefd8d8a6719f6e3cfb22e2e9f0aa0650f4804a6f360"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca"
"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1"
"checksum serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "02c92ea07b6e49b959c1481804ebc9bfd92d3c459f1274c9a9546829e42a66ce"
"checksum serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75c6aac7b99801a16db5b40b7bf0d7e4ba16e76fbf231e32a4677f271cac0603"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520"
"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"

17
Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "run-parts-gen-rs"
version = "0.1.0"
authors = ["Jan Christian Grünhage <jan.christian@gruenhage.xyz>"]
description = """A little tool to write scripts to folders for usage with run-parts,
based on definitions in a toml file. Written mostly for educational purposes,
it would probably be easier to write the scripts themselves,
than to take care of a config file where they are defined."""
[dependencies]
serde = "1.0"
serde_derive = "1.0"
toml = "0.4"
log = "0.3"
fern = "0.4"
chrono = "0.4"
clap = "2"

View File

@ -1,3 +1,74 @@
# run-parts-gen-rs
# run-parts generator
Little Rust tool that generates scripts for run-parts from a central config file
A little tool to write scripts to folders for usage with run-parts,
based on definitions in a toml file. Written mostly for educational purposes,
it would probably be easier to write the scripts themselves,
than to take care of a config file where they are defined.
### Usage:
Assuming you have a config file `config.toml` in the directory you are currently in,
generating the scripts from it is as easy as running
```bash
run-parts-gen-rs config.toml
```
If something doesn't work, you should see output complaining.
If something went wrong but you see no output, try adding `-v` to the command,
and again if that didn't help (but not more than four `-v`'s).
This will enable more verbose logging.
#### Config file:
There is an example config file in this repository, called config.example.toml,
you can orient yourself on that.
The most basic valid config file only contains the line
```toml
reduce_to_config = true
```
To then add actual functionality, add a folder block:
```toml
[[folders]]
path = ''
```
And to that folder block add a script block for each script you want to add to that folder:
```toml
[[folders.scripts]]
name = ''
commands = ['']
```
You can add as many folder blocks as you want, and to those folder blocks as many script blocks as you want.
This should be enough to get you going, gl hf!
### Dependencies:
You're going to need ..
- cargo
- ~/.cargo/bin/ in your $PATH
- Internet access
I'll assume the third thing is already present, to get the first two, head over to [rustup](https://rustup.rs).
### Installation
Clone the source code to rpg-rs
```bash
git clone https://git.jcg.re/jcgruenhage/run-parts-gen-rs.git rpg-rs
```
Enter the just cloned source directory
```bash
cd rpg-rs
```
Compile a release build
```bash
cargo install
```
You should now have the binary in `~/.cargo/bin`

12
config.example.toml Normal file
View File

@ -0,0 +1,12 @@
# If true, the folders defined in the config are deleted and recreated with only the scripts contained in the config.
reduce_to_config = true
[[folders]]
path = '/etc/periodic/15min'
[[folders.scripts]]
name = 'dyndns'
commands = [
'IP=`curl -s https://icanhazip.com/`',
'updateip $IP'
]

165
src/main.rs Normal file
View File

@ -0,0 +1,165 @@
#[macro_use]
extern crate serde_derive;
extern crate toml;
extern crate fern;
extern crate chrono;
#[macro_use]
extern crate clap;
#[macro_use]
extern crate log;
use std::fs::File;
use std::fs;
use std::io::prelude::*;
use std::fs::Permissions;
use std::os::unix::fs::PermissionsExt;
#[derive(Serialize, Deserialize)]
pub struct Config {
pub folders: Vec<Folder>,
pub reduce_to_config: bool,
}
#[derive(Serialize, Deserialize)]
pub struct Folder {
pub path: String,
pub scripts: Vec<Script>,
}
#[derive(Serialize, Deserialize)]
pub struct Script {
pub name: String,
pub commands: Vec<String>,
}
fn main() {
let clap = setup_clap();
let mut verbosity : usize = 0;
setup_fern(match clap.occurrences_of("v") {
0 => log::LogLevelFilter::Error,
1 => log::LogLevelFilter::Warn,
2 => log::LogLevelFilter::Info,
3 => log::LogLevelFilter::Debug,
4 => log::LogLevelFilter::Trace,
n => {
verbosity = n as usize;
log::LogLevelFilter::Trace
}
});
check_verbosity(verbosity);
let mut file = match File::open("foo.txt") {
Ok(file) => file,
Err(_) => {
error!("error opening file");
return;
}
};
let mut contents = String::new();
match file.read_to_string(&mut contents) {
Ok(_) => info!("read file to string successfully"),
Err(_) => {
error!("couldn't read file to string");
return;
}
};
let config: Config = match toml::from_str(&contents) {
Ok(config) => {
info!("successfully deserialized config file");
config
}
Err(_) => {
error!("couldn't deserialize config file");
return;
}
};
for folder in config.folders {
if config.reduce_to_config {
match fs::remove_dir_all(&folder.path) {
Ok(_) => info!("cleared folder {}", folder.path),
Err(_) => warn!("couldn't clear folder {}", folder.path),
};
}
match fs::DirBuilder::new().recursive(true).create(&folder.path) {
Err(_) => warn!("couldn't make sure folder {} existed", folder.path),
_ => {}
}
for script in folder.scripts {
let mut script_string = String::new();
script_string.push_str("#!/bin/sh\n");
script_string.push_str("# DO NOT EDIT THIS MANUALLY\n");
script_string.push_str("# THIS HAS BEEN GENERATED BY run-parts-gen-rs\n");
for command in script.commands {
script_string.push_str(&command);
script_string.push_str("\n");
}
let mut script_file = match File::create(&format!(
"{}{}{}",
folder.path,
std::path::MAIN_SEPARATOR,
script.name
)) {
Ok(file) => file,
Err(_) => {
warn!(
"couldn't open script {}{}{} for writing",
folder.path,
std::path::MAIN_SEPARATOR,
script.name
);
continue;
}
};
match script_file.write_all(script_string.as_bytes()) {
Ok(_) => info!("script {} written successfully", script.name),
Err(_) => warn!("error writing script {}", script.name),
};
match script_file.set_permissions(Permissions::from_mode(0o755)) {
Ok(_) => info!("made script {} executable", script.name),
Err(_) => warn!("couldn't make script {} executable", script.name),
}
}
}
}
fn check_verbosity(verbosity: usize) {
if verbosity > 4 {
trace!("specifying more than 4 doesn't do anything");
trace!("did you really expect {} different levels?!", verbosity)
}
}
fn setup_fern(level: log::LogLevelFilter) {
match fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"[{}][{}] {}",
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
record.level(),
message
))
})
.level(level)
.chain(std::io::stdout())
.apply() {
Err(_) => {
eprintln!("error setting up logging!");
}
_ => info!("logging set up properly"),
}
}
fn setup_clap() -> (clap::ArgMatches<'static>) {
clap_app!(myapp =>
(name: crate_name!())
(version: crate_version!())
(author: crate_authors!())
(about: crate_description!())
(@arg CONFIG: +required "Set config file to use")
(@arg v: -v --verbose ... "Be verbose (you can add this up to 4 times for more logs)")
).get_matches()
}