tag v0.155.0 Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com> Changes with 0.155.0 ---------------- * Fedora 43: add shadow-utils when LockRoot is enabled, update cloud-init service name (osbuild/images#1618) * Author: Achilleas Koutsou, Reviewers: Gianluca Zuccarelli, Michael Vogt * Update osbuild dependency commit ID to latest (osbuild/images#1609) * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger, Tomáš Hozza * Update snapshots to 20250626 (osbuild/images#1623) * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger * distro/rhel9: xz compress azure-cvm image type [HMS-8587] (osbuild/images#1620) * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza * distro/rhel: introduce new image type: Azure SAP Apps [HMS-8738] (osbuild/images#1612) * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza * distro/rhel: move ansible-core to sap_extras_pkgset (osbuild/images#1624) * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Tomáš Hozza * github/create-tag: allow passing the version when run manually (osbuild/images#1621) * Author: Achilleas Koutsou, Reviewers: Lukáš Zapletal, Tomáš Hozza * rhel9: move image-config into pure YAML (HMS-8593) (osbuild/images#1616) * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger * test: split manifest checksums into separate files (osbuild/images#1625) * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza — Somewhere on the Internet, 2025-06-30 --- tag v0.156.0 Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com> Changes with 0.156.0 ---------------- * Many: delete repositories for EOL distributions (HMS-7044) (osbuild/images#1607) * Author: Tomáš Hozza, Reviewers: Michael Vogt, Simon de Vlieger * RHSM/facts: add 'image-builder CLI' API type (osbuild/images#1640) * Author: Tomáš Hozza, Reviewers: Brian C. Lane, Simon de Vlieger * Update dependencies 2025-06-29 (osbuild/images#1628) * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza * Update osbuild dependency commit ID to latest (osbuild/images#1627) * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza * [RFC] image: drop `InstallWeakDeps` from image.DiskImage (osbuild/images#1642) * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger, Tomáš Hozza * build(deps): bump the go-deps group across 1 directory with 3 updates (osbuild/images#1632) * Author: dependabot[bot], Reviewers: SchutzBot, Tomáš Hozza * distro/rhel10: xz compress azure-cvm image type (osbuild/images#1638) * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Simon de Vlieger * distro: cleanup/refactor distro/{defs,generic} (HMS-8744) (osbuild/images#1570) * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza * distro: remove some hardcoded values from generic/images.go (osbuild/images#1636) * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza * distro: small tweaks for the YAML based imagetypes (osbuild/images#1622) * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger * fedora/wsl: packages and locale (osbuild/images#1635) * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza * image/many: make compression more generic (osbuild/images#1634) * Author: Simon de Vlieger, Reviewers: Brian C. Lane, Michael Vogt * manifest: handle content template name with spaces (osbuild/images#1641) * Author: Bryttanie, Reviewers: Brian C. Lane, Michael Vogt, Tomáš Hozza * many: implement gzip (osbuild/images#1633) * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza * rhel/azure: set GRUB_TERMINAL based on architecture [RHEL-91383] (osbuild/images#1626) * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza — Somewhere on the Internet, 2025-07-07 ---
143 lines
3.8 KiB
Go
143 lines
3.8 KiB
Go
//go:build !windows
|
|
|
|
package user
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"syscall"
|
|
)
|
|
|
|
func mkdirAs(path string, mode os.FileMode, uid, gid int, mkAll, onlyNew bool) error {
|
|
path, err := filepath.Abs(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
stat, err := os.Stat(path)
|
|
if err == nil {
|
|
if !stat.IsDir() {
|
|
return &os.PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR}
|
|
}
|
|
if onlyNew {
|
|
return nil
|
|
}
|
|
|
|
// short-circuit -- we were called with an existing directory and chown was requested
|
|
return setPermissions(path, mode, uid, gid, stat)
|
|
}
|
|
|
|
// make an array containing the original path asked for, plus (for mkAll == true)
|
|
// all path components leading up to the complete path that don't exist before we MkdirAll
|
|
// so that we can chown all of them properly at the end. If onlyNew is true, we won't
|
|
// chown the full directory path if it exists
|
|
var paths []string
|
|
if os.IsNotExist(err) {
|
|
paths = append(paths, path)
|
|
}
|
|
|
|
if mkAll {
|
|
// walk back to "/" looking for directories which do not exist
|
|
// and add them to the paths array for chown after creation
|
|
dirPath := path
|
|
for {
|
|
dirPath = filepath.Dir(dirPath)
|
|
if dirPath == "/" {
|
|
break
|
|
}
|
|
if _, err = os.Stat(dirPath); os.IsNotExist(err) {
|
|
paths = append(paths, dirPath)
|
|
}
|
|
}
|
|
if err = os.MkdirAll(path, mode); err != nil {
|
|
return err
|
|
}
|
|
} else if err = os.Mkdir(path, mode); err != nil {
|
|
return err
|
|
}
|
|
// even if it existed, we will chown the requested path + any subpaths that
|
|
// didn't exist when we called MkdirAll
|
|
for _, pathComponent := range paths {
|
|
if err = setPermissions(pathComponent, mode, uid, gid, nil); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// setPermissions performs a chown/chmod only if the uid/gid don't match what's requested
|
|
// Normally a Chown is a no-op if uid/gid match, but in some cases this can still cause an error, e.g. if the
|
|
// dir is on an NFS share, so don't call chown unless we absolutely must.
|
|
// Likewise for setting permissions.
|
|
func setPermissions(p string, mode os.FileMode, uid, gid int, stat os.FileInfo) error {
|
|
if stat == nil {
|
|
var err error
|
|
stat, err = os.Stat(p)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if stat.Mode().Perm() != mode.Perm() {
|
|
if err := os.Chmod(p, mode.Perm()); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
ssi := stat.Sys().(*syscall.Stat_t)
|
|
if ssi.Uid == uint32(uid) && ssi.Gid == uint32(gid) {
|
|
return nil
|
|
}
|
|
return os.Chown(p, uid, gid)
|
|
}
|
|
|
|
// LoadIdentityMapping takes a requested username and
|
|
// using the data from /etc/sub{uid,gid} ranges, creates the
|
|
// proper uid and gid remapping ranges for that user/group pair
|
|
func LoadIdentityMapping(name string) (IdentityMapping, error) {
|
|
// TODO: Consider adding support for calling out to "getent"
|
|
usr, err := LookupUser(name)
|
|
if err != nil {
|
|
return IdentityMapping{}, fmt.Errorf("could not get user for username %s: %w", name, err)
|
|
}
|
|
|
|
subuidRanges, err := lookupSubRangesFile("/etc/subuid", usr)
|
|
if err != nil {
|
|
return IdentityMapping{}, err
|
|
}
|
|
subgidRanges, err := lookupSubRangesFile("/etc/subgid", usr)
|
|
if err != nil {
|
|
return IdentityMapping{}, err
|
|
}
|
|
|
|
return IdentityMapping{
|
|
UIDMaps: subuidRanges,
|
|
GIDMaps: subgidRanges,
|
|
}, nil
|
|
}
|
|
|
|
func lookupSubRangesFile(path string, usr User) ([]IDMap, error) {
|
|
uidstr := strconv.Itoa(usr.Uid)
|
|
rangeList, err := ParseSubIDFileFilter(path, func(sid SubID) bool {
|
|
return sid.Name == usr.Name || sid.Name == uidstr
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(rangeList) == 0 {
|
|
return nil, fmt.Errorf("no subuid ranges found for user %q", usr.Name)
|
|
}
|
|
|
|
idMap := []IDMap{}
|
|
|
|
var containerID int64
|
|
for _, idrange := range rangeList {
|
|
idMap = append(idMap, IDMap{
|
|
ID: containerID,
|
|
ParentID: idrange.SubID,
|
|
Count: idrange.Count,
|
|
})
|
|
containerID = containerID + idrange.Count
|
|
}
|
|
return idMap, nil
|
|
}
|