11use preflight:: {
2- CheckGroup ,
2+ CheckGroup , CheckGroupResult ,
33 CheckResultValue :: { Errored , Failed , Passed } ,
4+ hardware:: HardwareChecks ,
45 kernel:: KernelChecks ,
56 script:: ScriptChecks ,
67 system:: SystemChecks ,
7- hardware:: HardwareChecks ,
88} ;
99
10- use anyhow:: { Result , anyhow, bail} ;
10+ use anyhow:: { Context , Result , anyhow, bail} ;
11+ use chrono:: Utc ;
12+ use flate2:: Compression ;
13+ use flate2:: write:: GzEncoder ;
1114use log:: info;
1215use std:: env;
16+ use std:: fs;
17+ use std:: fs:: File ;
1318use std:: os:: unix;
19+ use std:: path:: { Path , PathBuf } ;
1420
1521// Skip certain groups. List is separated by ;
1622fn skip_groups ( ) -> Vec < String > {
1723 let skips = env:: var ( "EDERA_PREFLIGHT_SKIP_GROUPS" ) . unwrap_or_default ( ) ;
1824 skips. split ( ";" ) . map ( |s| s. to_string ( ) ) . collect ( )
1925}
2026
27+ fn create_gzip_from ( base_path : PathBuf ) -> Result < ( ) > {
28+ let mut archive_path = base_path. clone ( ) ;
29+ archive_path. set_extension ( "tar.gz" ) ;
30+ let tar_gz = File :: create ( & archive_path)
31+ . with_context ( || format ! ( "failed to create {}" , archive_path. display( ) ) ) ?;
32+ let enc = GzEncoder :: new ( tar_gz, Compression :: default ( ) ) ;
33+ let mut tar = tar:: Builder :: new ( enc) ;
34+ tar. append_dir_all ( "." , base_path)
35+ . context ( "failed to append to tar {}" ) ?;
36+ info ! ( "Wrote to: {}" , archive_path. to_string_lossy( ) ) ;
37+ Ok ( ( ) )
38+ }
39+
40+ fn create_base_path ( ) -> Result < PathBuf > {
41+ let now = Utc :: now ( ) ;
42+
43+ let base = env:: var ( "EDERA_PREFLIGHT_REPORT_DIR" )
44+ . map ( PathBuf :: from)
45+ . unwrap_or ( env:: temp_dir ( ) ) ;
46+
47+ let base_path = base. join ( format ! (
48+ "protect-preflight-bundle-{}" ,
49+ now. format( "%Y%m%d-%H%M%S" )
50+ ) ) ;
51+ fs:: create_dir_all ( & base_path)
52+ . with_context ( || format ! ( "could not create {}" , base_path. display( ) ) ) ?;
53+ info ! ( "Writing all files to {}" , base_path. to_string_lossy( ) ) ;
54+ Ok ( base_path)
55+ }
56+
57+ fn write_group_report (
58+ group : Box < dyn CheckGroup > ,
59+ result : & CheckGroupResult ,
60+ path : & Path ,
61+ ) -> Result < ( ) > {
62+ let path = path. join ( group. id ( ) ) ;
63+ fs:: create_dir_all ( & path) . with_context ( || format ! ( "could not create {}" , path. display( ) ) ) ?;
64+
65+ for check in result. results . iter ( ) {
66+ // Sanitize the name of the check into a flat file. Script Checks default to the path of
67+ // the script as the name so we need to sanitize.
68+ let name = check
69+ . name
70+ . replace ( " " , "_" )
71+ . replace ( "/" , "_" )
72+ . replace ( "." , "" ) ;
73+
74+ let path = path. join ( name) ;
75+ match check. output_to_record . as_ref ( ) {
76+ Some ( text) => fs:: write ( & path, text) ,
77+ None => fs:: write ( & path, format ! ( "{}" , check. result) ) ,
78+ }
79+ . with_context ( || format ! ( "failed to write to {}" , path. display( ) ) ) ?;
80+ }
81+ Ok ( ( ) )
82+ }
83+
2184fn main ( ) -> Result < ( ) > {
2285 env_logger:: init ( ) ;
2386
@@ -36,6 +99,9 @@ fn main() -> Result<()> {
3699 . map_err ( |e| anyhow ! ( "failed to chroot to {target_dir}: {e}" ) ) ?;
37100 }
38101
102+ let base_path =
103+ create_base_path ( ) . map_err ( |e| anyhow ! ( "failed to create bundle base path: {e}" ) ) ?;
104+
39105 // Run each check group
40106 for group in groups {
41107 // Check if we need to explicity skip this group
@@ -61,8 +127,12 @@ fn main() -> Result<()> {
61127 if matches ! ( check_group_result. result, Errored ( _) ) {
62128 final_result = Errored ( String :: from ( "group errored" ) ) ;
63129 }
130+
131+ write_group_report ( group, & check_group_result, & base_path) ?;
64132 }
65133
134+ create_gzip_from ( base_path) ?;
135+
66136 match final_result {
67137 Errored ( _) | Failed ( _) => bail ! ( "Preflight checks did not pass" ) ,
68138 _ => Ok ( ( ) ) ,
0 commit comments