1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
extern crate base64;
extern crate libc;
extern crate nereon;
#[macro_use]
extern crate nereon_derive;
#[macro_use]
extern crate log;
mod file;
mod distro;
use nereon::{FromValue, Value};
use std::env;
use std::fs;
const VERSION: &str = env!("CARGO_PKG_VERSION");
const AUTHORS: &str = env!("CARGO_PKG_AUTHORS");
const LICENSE: &str = "BSD-2-Clause";
const APPNAME: &str = env!("CARGO_PKG_NAME");
#[derive(Debug, FromValue)]
struct Config {
packages: Vec<String>,
fileset_file: Option<String>,
fileset_env: Option<String>,
}
pub fn nereond() -> Result<(), String> {
let nos = format!(
r#"
authors ["{}"]
license "{}"
name "{}"
version {}
option fileset_file {{
flags [takesvalue]
short f
long fileset
env NEREON_FILESET_FILE
hint FILE
usage "File containing a nereon fileset"
key [fileset_file]
}},
option fileset {{
flags [takesvalue]
long fileset-env
env NEREON_FILESET
hint FILESET
usage "Fileset as environment variable"
key [fileset_env]
}},
option packages {{
flags [takesvalue, multiple]
long package
short p
hint PACKAGE
usage "Install package using apt, yum etc."
key [packages]
}}"#,
AUTHORS, LICENSE, APPNAME, VERSION
);
let config = nereon::configure::<Config, _, _>(&nos, env::args()).unwrap();
distro::install_packages(&config.packages)?;
config
.fileset_file
.as_ref()
.map_or_else(
|| {
config.fileset_env.as_ref().map_or_else(
|| Err("No fileset from args or environment.".to_owned()),
|s| {
base64::decode(&s)
.map_err(|_| "Invalid base64 data in env[NEREON_FILESET]".to_owned())
.and_then(|bs| {
String::from_utf8(bs).map_err(|_| {
"Invalid utf8 data in env[NEREON_FILESET]".to_owned()
})
})
},
)
},
|file| {
fs::read_to_string(&file)
.map_err(|e| format!("Failed to read fileset file {}: {:?}.", file, e))
},
).and_then(|fileset| file::parse_fileset(&mut fileset.as_bytes()))
.map(|fileset| {
fileset.iter().for_each(|(id, (f, decoded_content))| {
f.update(decoded_content)
.map_err(|e| warn!("Failed to update {}: {}", id, e))
.ok();
})
})
}