mirror of
https://github.com/lxc/distrobuilder.git
synced 2026-02-05 06:45:19 +01:00
Add user/group ID mapping from passwd and group files
Introduce functionality to parse `/etc/passwd` and `/etc/group` files to map symbolic user/group names to numeric IDs. This ensures consistency in file definitions by replacing symbolic references with their corresponding numeric IDs in the global configuration. An environment override for logger colors was also added. Signed-off-by: Arthur <git@arthur.pro>
This commit is contained in:
@@ -265,11 +265,35 @@ func (c *cmdIncus) run(cmd *cobra.Command, args []string, overlayDir string) err
|
||||
imageTargets |= shared.ImageTargetContainer
|
||||
}
|
||||
|
||||
for _, file := range c.global.definition.Files {
|
||||
// Maps symbolic user/group names to their numeric IDs using information from passwd and group files.
|
||||
userMap, groupMap, err := parsePasswdAndGroupFiles(overlayDir)
|
||||
if err != nil {
|
||||
c.global.logger.WithField("overlay", overlayDir).Warn("Could not parse passwd/group file: %w", err)
|
||||
}
|
||||
|
||||
for i, file := range c.global.definition.Files {
|
||||
if !shared.ApplyFilter(&file, c.global.definition.Image.Release, c.global.definition.Image.ArchitectureMapped, c.global.definition.Image.Variant, c.global.definition.Targets.Type, imageTargets) {
|
||||
continue
|
||||
}
|
||||
|
||||
if file.UID != "" && !isNumeric(file.UID) {
|
||||
uid, exists := userMap[file.UID]
|
||||
if exists {
|
||||
c.global.definition.Files[i].UID = uid
|
||||
} else {
|
||||
c.global.logger.WithField("generator", file.Generator).Warnf("Could not find UID for user %q", file.UID)
|
||||
}
|
||||
}
|
||||
|
||||
if file.UID != "" && !isNumeric(file.GID) {
|
||||
gid, exists := groupMap[file.GID]
|
||||
if exists {
|
||||
c.global.definition.Files[i].GID = gid
|
||||
} else {
|
||||
c.global.logger.WithField("generator", file.Generator).Warnf("Could not find GID for group %q", file.GID)
|
||||
}
|
||||
}
|
||||
|
||||
generator, err := generators.Load(file.Generator, c.global.logger, c.global.flagCacheDir, overlayDir, file, *c.global.definition)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to load generator %q: %w", file.Generator, err)
|
||||
|
||||
56
distrobuilder/passwd.go
Normal file
56
distrobuilder/passwd.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// parsePasswdAndGroupFiles reads passwd and group files from the given root directory
|
||||
// and returns mappings of names to IDs for both users and groups.
|
||||
func parsePasswdAndGroupFiles(rootDir string) (map[string]string, map[string]string, error) {
|
||||
userMap, err := parsePasswdFile(filepath.Join(rootDir, "/etc/passwd"))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("parsing passwd file: %w", err)
|
||||
}
|
||||
|
||||
groupMap, err := parsePasswdFile(filepath.Join(rootDir, "/etc/group"))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("parsing group file: %w", err)
|
||||
}
|
||||
|
||||
return userMap, groupMap, nil
|
||||
}
|
||||
|
||||
// parsePasswdFile reads a passwd-format file and returns a map of names to IDs.
|
||||
func parsePasswdFile(path string) (map[string]string, error) {
|
||||
idMap := make(map[string]string)
|
||||
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading file %s: %w", path, err)
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
fields := strings.Split(line, ":")
|
||||
if len(fields) < 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
idMap[fields[0]] = fields[2]
|
||||
}
|
||||
|
||||
return idMap, nil
|
||||
}
|
||||
|
||||
// isNumeric is a helper function to check if a string is numeric.
|
||||
func isNumeric(s string) bool {
|
||||
_, err := strconv.Atoi(s)
|
||||
return err == nil
|
||||
}
|
||||
@@ -17,6 +17,8 @@ func GetLogger(debug bool) (*logrus.Logger, error) {
|
||||
PadLevelText: true,
|
||||
}
|
||||
|
||||
formatter.EnvironmentOverrideColors = true
|
||||
|
||||
logger.Formatter = &formatter
|
||||
|
||||
if debug {
|
||||
|
||||
Reference in New Issue
Block a user