athena_aegis/
args.rs

1use clap::{Args, Parser, Subcommand, ValueEnum};
2use serde::{Deserialize, Serialize};
3use std::path::PathBuf;
4
5#[derive(Debug, Parser)]
6#[command(name = "aegis-installer")]
7#[command(author=env!("CARGO_PKG_AUTHORS"))]
8#[command(version = env!("CARGO_PKG_VERSION"))]
9#[command(about = env!("CARGO_PKG_DESCRIPTION"), long_about = None)]
10
11pub struct Cli {
12    #[command(subcommand)]
13    pub command: Command,
14
15    #[arg(short, long, action = clap::ArgAction::Count)]
16    pub verbose: u8,
17}
18
19#[derive(Debug, ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
20pub enum PackageManager {
21    #[value(name = "pacman")]
22    Pacman,
23
24    #[value(name = "pacstrap")]
25    Pacstrap,
26
27    #[value(name = "None/DIY")]
28    None,
29}
30
31#[derive(Debug, Subcommand)]
32pub enum Command {
33    /// Partition the install destination
34    #[command(name = "partition")]
35    Partition(PartitionArgs),
36
37    /// Install base packages
38    #[command(name = "install-base")]
39    InstallBase,
40
41    /// Install packages, optionally define a different kernel
42    #[command(name = "install-packages")]
43    InstallPackages(InstallPackagesArgs),
44
45    /// Generate fstab file for mounting partitions
46    #[command(name = "genfstab")]
47    GenFstab,
48
49    /// Setup Snapper
50    #[command(name = "setup-snapper")]
51    SetupSnapper,
52
53    /// Install the bootloader
54    #[command(name = "bootloader")]
55    Bootloader {
56        #[clap(subcommand)]
57        subcommand: BootloaderSubcommand,
58    },
59
60    /// Set locale
61    #[command(name = "locale")]
62    Locale(LocaleArgs),
63
64    /// Set up networking
65    #[command(name = "networking")]
66    Networking(NetworkingArgs),
67
68    /// Set up zramd
69    #[command(name = "zramd")]
70    Zram,
71
72    /// Set up hardened
73    #[command(name = "hardened")]
74    Hardened,
75
76    /// Configure users and passwords
77    #[command(name = "users")]
78    Users {
79        #[command(subcommand)]
80        subcommand: UsersSubcommand,
81    },
82
83    /// Install the Nix package manager
84    #[command(name = "nix")]
85    Nix,
86
87    /// Install Flatpak and enable FlatHub
88    #[command(name = "flatpak")]
89    Flatpak,
90
91    /// Install CUDA
92    #[command(name = "cuda")]
93    Cuda,
94
95    /// Install Spotify
96    #[command(name = "spotify")]
97    Spotify,
98
99    /// Install CherryTree
100    #[command(name = "cherrytree")]
101    CherryTree,
102
103    /// Install Flameshot
104    #[command(name = "flameshot")]
105    Flameshot,
106
107    /// Install BusyBox
108    #[command(name = "busybox")]
109    BusyBox,
110
111    /// Install Toybox
112    #[command(name = "toybox")]
113    Toybox,
114
115    /// Read Aegis installation config
116    #[command(name = "config")]
117    Config {
118        /// The config file to read
119        config: PathBuf,
120    },
121
122    /// Install a graphical desktop
123    #[command(name = "desktops")]
124    Desktops {
125        /// The desktop setup to use
126        #[arg(value_enum)]
127        desktop: DesktopSetup,
128    },
129
130    /// Install a graphical theme
131    #[command(name = "themes")]
132    Themes {
133        /// The theme setup to use
134        #[arg(value_enum)]
135        theme: ThemeSetup,
136    },
137
138    /// Install a display manager
139    #[command(name = "displaymanagers")]
140    DisplayManagers {
141        /// The display manager setup to use
142        #[arg(value_enum)]
143        displaymanager: DMSetup,
144    },
145
146    /// Install a shell
147    #[command(name = "shells")]
148    Shells {
149        /// The shell setup to use
150        #[arg(value_enum)]
151        shell: ShellSetup,
152    },
153
154    /// Install a browser
155    #[command(name = "browsers")]
156    Browsers {
157        /// The browser setup to use
158        #[arg(value_enum)]
159        browser: BrowserSetup,
160    },
161
162    /// Install a terminal
163    #[command(name = "terminals")]
164    Terminals {
165        /// The terminal setup to use
166        #[arg(value_enum)]
167        terminal: TerminalSetup,
168    },
169
170    /// Enable services
171    #[command(name = "enable-services")]
172    EnableServices,
173}
174
175#[derive(Debug, Args)]
176pub struct PartitionArgs {
177    /// If aegis should automatically partition (mode = auto)
178    /// or the user manually partitioned it (mode = manual)
179    #[arg(value_enum)]
180    pub mode: PartitionMode,
181
182    /// The device to partition
183    #[arg(required_if_eq("mode", "PartitionMode::Auto"), required = false)]
184    pub device: PathBuf,
185
186    /// If the install destination should be partitioned with EFI
187    #[arg(long)]
188    pub efi: bool,
189
190    /// The partitions to use for manual partitioning
191    #[arg(required_if_eq("mode", "PartitionMode::Manual"), value_parser = parse_partitions)]
192    pub partitions: Vec<Partition>,
193}
194
195#[derive(Debug, Args)]
196pub struct InstallPackagesArgs {
197    #[clap(long)]
198    pub kernel: String,
199}
200
201#[derive(Debug, Clone)]
202pub struct Partition {
203    pub mountpoint: String,
204    pub blockdevice: String,
205    pub filesystem: String,
206}
207
208impl Partition {
209    pub fn new(mountpoint: String, blockdevice: String, filesystem: String) -> Self {
210        Self {
211            mountpoint,
212            blockdevice,
213            filesystem,
214        }
215    }
216}
217
218pub fn parse_partitions(s: &str) -> Result<Partition, &'static str> {
219    // to rewrite
220    println!("{}", s);
221    Ok(Partition::new(
222        s.split(':').collect::<Vec<&str>>()[0].to_string(),
223        s.split(':').collect::<Vec<&str>>()[1].to_string(),
224        s.split(':').collect::<Vec<&str>>()[2].to_string(),
225    ))
226}
227
228#[derive(Debug, ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
229pub enum PartitionMode {
230    #[value(name = "auto")]
231    Auto,
232    #[value(name = "manual")]
233    Manual,
234}
235
236#[derive(Debug, Subcommand)]
237pub enum BootloaderSubcommand {
238    /// Install GRUB in EFI mode
239    #[clap(name = "grub-efi")]
240    GrubEfi {
241        /// The directory to install the EFI bootloader to
242        efidir: PathBuf,
243    },
244
245    /// Install GRUB in legacy (BIOS) mode
246    #[clap(name = "grub-legacy")]
247    GrubLegacy {
248        /// The device to install the bootloader to
249        device: PathBuf,
250    },
251}
252
253#[derive(Debug, Args)]
254pub struct LocaleArgs {
255    /// The keyboard layout to use
256    pub keyboard: String,
257
258    /// The timezone to use
259    pub timezone: String,
260
261    /// The locales to set
262    pub locales: Vec<String>,
263}
264
265#[derive(Debug, Args)]
266pub struct NetworkingArgs {
267    /// The hostname to assign to the system
268    pub hostname: String,
269
270    /// Whether IPv6 loopback should be enabled
271    #[arg(long)]
272    pub ipv6: bool,
273}
274
275#[derive(Debug, Subcommand)]
276pub enum UsersSubcommand {
277    /// Create a new user
278    #[command(name="new-user", aliases=&["newUser"])]
279    NewUser(NewUserArgs),
280
281    /// Set the password of the root user
282    #[command(name="root-password", aliases=&["root-pass", "rootPass"])]
283    RootPass {
284        /// The password to set. NOTE: Takes hashed password, use `openssl passwd -1 <password>` to generate the hash.
285        password: String,
286    },
287}
288
289#[derive(Debug, Args)]
290pub struct NewUserArgs {
291    /// The name of the user to create
292    pub username: String,
293
294    /// If the user should have root privileges
295    #[arg(long, aliases=&["has-root", "sudoer", "root"])]
296    pub hasroot: bool,
297
298    /// The password to set. NOTE: Takes hashed password, use `openssl passwd -6 <password>` to generate the hash.
299    /// When not providing a password openssl jumps into an interactive masked input mode allowing you to hide your password
300    /// from the terminal history.
301    pub password: String,
302
303    /// The shell to use for the user. The current options are bash, csh, fish, tcsh, and zsh.
304    /// If a shell is not specified or unknown, it defaults to fish.
305    pub shell: String,
306}
307
308#[derive(Debug, ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
309pub enum DesktopSetup {
310    #[value(name = "onyx")]
311    Onyx,
312
313    #[value(name = "gnome")]
314    Gnome,
315
316    #[value(name = "kde", aliases = ["plasma"])]
317    Kde,
318
319    #[value(name = "budgie")]
320    Budgie,
321
322    #[value(name = "cinnamon")]
323    Cinnamon,
324
325    #[value(name = "mate")]
326    Mate,
327
328    #[value(name = "xfce-well")]
329    XfceWell,
330
331    #[value(name = "xfce-picom")]
332    XfcePicom,
333
334    #[value(name = "enlightenment")]
335    Enlightenment,
336
337    #[value(name = "lxqt")]
338    Lxqt,
339
340    #[value(name = "sway")]
341    Sway,
342
343    #[value(name = "i3")]
344    I3,
345
346    #[value(name = "herbstluftwm")]
347    Herbstluftwm,
348
349    #[value(name = "awesome")]
350    Awesome,
351
352    #[value(name = "bspwm")]
353    Bspwm,
354
355    #[value(name = "hyprland")]
356    Hyprland,
357
358    #[value(name = "None/DIY")]
359    None,
360}
361
362#[derive(Debug, ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
363pub enum ThemeSetup {
364    #[value(name = "akame")]
365    Akame,
366
367    #[value(name = "cyborg")]
368    Cyborg,
369
370    #[value(name = "everblush")]
371    Everblush,
372
373    #[value(name = "graphite")]
374    Graphite,
375
376    #[value(name = "hackthebox")]
377    HackTheBox,
378
379    #[value(name = "samurai")]
380    Samurai,
381
382    #[value(name = "sweet")]
383    Sweet,
384
385    #[value(name = "xxe")]
386    Xxe,
387
388    #[value(name = "None/DIY")]
389    None,
390}
391
392#[derive(Debug, ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
393pub enum DMSetup {
394    #[value(name = "gdm")]
395    Gdm,
396
397    #[value(name = "lightdm-neon")]
398    LightDMNeon,
399
400    #[value(name = "lightdm-everblush")]
401    LightDMEverblush,
402
403    #[value(name = "sddm")]
404    Sddm,
405
406    #[value(name = "None/DIY")]
407    None,
408}
409
410#[derive(Debug, ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
411pub enum ShellSetup {
412    #[value(name = "bash")]
413    Bash,
414
415    #[value(name = "fish")]
416    Fish,
417
418    #[value(name = "zsh")]
419    Zsh,
420
421    #[value(name = "None/DIY")]
422    None,
423}
424
425#[derive(Debug, ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
426pub enum BrowserSetup {
427    #[value(name = "firefox")]
428    Firefox,
429
430    #[value(name = "brave")]
431    Brave,
432
433    #[value(name = "mullvad")]
434    Mullvad,
435
436    #[value(name = "None/DIY")]
437    None,
438}
439
440#[derive(Debug, ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
441pub enum TerminalSetup {
442    #[value(name = "alacritty")]
443    Alacritty,
444
445    #[value(name = "cool-retro-term")]
446    CoolRetroTerm,
447
448    #[value(name = "foot")]
449    Foot,
450
451    #[value(name = "gnome-terminal")]
452    GnomeTerminal,
453
454    #[value(name = "kitty")]
455    Kitty,
456
457    #[value(name = "konsole")]
458    Konsole,
459
460    #[value(name = "terminator")]
461    Terminator,
462
463    #[value(name = "terminology")]
464    Terminology,
465
466    #[value(name = "urxvt")]
467    Urxvt,
468
469    #[value(name = "xfce4-terminal")]
470    Xfce,
471
472    #[value(name = "xterm")]
473    Xterm,
474
475    #[value(name = "None/DIY")]
476    None,
477}