Skip to content

Commit

Permalink
internal/exec/*: preserve special mode bits for a given file/dir
Browse files Browse the repository at this point in the history
This allows Ignition to preserve the special mode bits for specs >=
3.4.0

Fixes: coreos#1301
  • Loading branch information
sohankunkerkar committed Apr 10, 2022
1 parent 682101e commit 7fbf89e
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions internal/exec/util/file.go
Expand Up @@ -25,6 +25,7 @@ import (
"os"
"path/filepath"
"strconv"
"syscall"

cutil "github.com/coreos/ignition/v2/config/util"
"github.com/coreos/ignition/v2/config/v3_4_experimental/types"
Expand Down Expand Up @@ -129,7 +130,7 @@ func (u Util) WriteLink(s types.Link) error {
path := s.Path

if err := MkdirForFile(path); err != nil {
return fmt.Errorf("Could not create leading directories: %v", err)
return fmt.Errorf("could not create leading directories: %v", err)
}

if cutil.IsTrue(s.Hard) {
Expand All @@ -141,7 +142,7 @@ func (u Util) WriteLink(s types.Link) error {
}

if err := os.Symlink(*s.Target, path); err != nil {
return fmt.Errorf("Could not create symlink: %v", err)
return fmt.Errorf("could not create symlink: %v", err)
}

if err := u.SetPermissions(nil, s.Node); err != nil {
Expand All @@ -152,8 +153,7 @@ func (u Util) WriteLink(s types.Link) error {

func (u Util) SetPermissions(mode *int, node types.Node) error {
if mode != nil {
mode := os.FileMode(*mode)
if err := os.Chmod(node.Path, mode); err != nil {
if err := os.Chmod(node.Path, toFileMode(*mode)); err != nil {
return fmt.Errorf("failed to change mode of %s: %v", node.Path, err)
}
}
Expand All @@ -169,6 +169,23 @@ func (u Util) SetPermissions(mode *int, node types.Node) error {
return nil
}

// toFileMode converts Go permission bits to POSIX permission bits.
func toFileMode(m int) os.FileMode {
mode := uint32(m)
res := os.FileMode(mode & 0777)

if mode&syscall.S_ISGID != 0 {
res |= os.ModeSetgid
}
if mode&syscall.S_ISUID != 0 {
res |= os.ModeSetuid
}
if mode&syscall.S_ISVTX != 0 {
res |= os.ModeSticky
}
return res
}

// PerformFetch performs a fetch operation generated by PrepareFetch, retrieving
// the file and writing it to disk. Any encountered errors are returned.
func (u Util) PerformFetch(f FetchOp) error {
Expand Down Expand Up @@ -337,23 +354,23 @@ func (u Util) ResolveNodeUidAndGid(n types.Node, defaultUid, defaultGid int) (in
func (u Util) getUserID(name string) (int, error) {
usr, err := u.userLookup(name)
if err != nil {
return 0, fmt.Errorf("No such user %q: %v", name, err)
return 0, fmt.Errorf("no such user %q: %v", name, err)
}
uid, err := strconv.ParseInt(usr.Uid, 0, 0)
if err != nil {
return 0, fmt.Errorf("Couldn't parse uid %q: %v", usr.Uid, err)
return 0, fmt.Errorf("couldn't parse uid %q: %v", usr.Uid, err)
}
return int(uid), nil
}

func (u Util) getGroupID(name string) (int, error) {
g, err := u.groupLookup(name)
if err != nil {
return 0, fmt.Errorf("No such group %q: %v", name, err)
return 0, fmt.Errorf("no such group %q: %v", name, err)
}
gid, err := strconv.ParseInt(g.Gid, 0, 0)
if err != nil {
return 0, fmt.Errorf("Couldn't parse gid %q: %v", g.Gid, err)
return 0, fmt.Errorf("couldn't parse gid %q: %v", g.Gid, err)
}
return int(gid), nil
}

0 comments on commit 7fbf89e

Please sign in to comment.