@@ -515,6 +515,56 @@ fn check_var_tmpfiles(_root: &Dir) -> LintResult {
515
515
lint_err ( msg)
516
516
}
517
517
518
+ #[ distributed_slice( LINTS ) ]
519
+ static LINT_SYSUSERS : Lint = Lint {
520
+ name : "sysusers" ,
521
+ ty : LintType :: Warning ,
522
+ description : indoc ! { r#"
523
+ Check for users in /etc/passwd and groups in /etc/group that do not have corresponding
524
+ systemd sysusers.d entries in /usr/lib/sysusers.d.
525
+ This can cause a problem across upgrades because if /etc is not transient and is locally
526
+ modified (commonly due to local user additions), then the contents of /etc/passwd in the new container
527
+ image may not be visible.
528
+
529
+ Using systemd-sysusers to allocate users and groups will ensure that these are allocated
530
+ on system startup alongside other users.
531
+
532
+ More on this topic in <https://containers.github.io/bootc/building/users-and-groups.html>
533
+ "# } ,
534
+ f : check_sysusers,
535
+ root_type : None ,
536
+ } ;
537
+ fn check_sysusers ( rootfs : & Dir ) -> LintResult {
538
+ let r = bootc_sysusers:: analyze ( rootfs) ?;
539
+ if r. is_empty ( ) {
540
+ return lint_ok ( ) ;
541
+ }
542
+ let mut msg = String :: new ( ) ;
543
+ if let Some ( ( samples, rest) ) =
544
+ bootc_utils:: iterator_split_nonempty_rest_count ( r. missing_users . iter ( ) , 5 )
545
+ {
546
+ msg. push_str ( "Found /etc/passwd entry without corresponding systemd sysusers.d:\n " ) ;
547
+ for elt in samples {
548
+ writeln ! ( msg, " {elt}" ) ?;
549
+ }
550
+ if rest > 0 {
551
+ writeln ! ( msg, " ...and {} more" , rest) ?;
552
+ }
553
+ }
554
+ if let Some ( ( samples, rest) ) =
555
+ bootc_utils:: iterator_split_nonempty_rest_count ( r. missing_groups . iter ( ) , 5 )
556
+ {
557
+ msg. push_str ( "Found /etc/group entry without corresponding systemd sysusers.d:\n " ) ;
558
+ for elt in samples {
559
+ writeln ! ( msg, " {elt}" ) ?;
560
+ }
561
+ if rest > 0 {
562
+ writeln ! ( msg, " ...and {} more" , rest) ?;
563
+ }
564
+ }
565
+ lint_err ( msg)
566
+ }
567
+
518
568
#[ distributed_slice( LINTS ) ]
519
569
static LINT_NONEMPTY_BOOT : Lint = Lint :: new_warning (
520
570
"nonempty-boot" ,
0 commit comments