mirror of
https://github.com/containers/podman.git
synced 2025-10-16 10:43:52 +08:00
create: add support for --group-entry
* add test * update documentation Signed-off-by: danishprakash <danish.prakash@suse.com>
This commit is contained in:
@ -604,6 +604,10 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
|
||||
createFlags.StringVar(&cf.PasswdEntry, passwdEntryName, "", "Entry to write to /etc/passwd")
|
||||
_ = cmd.RegisterFlagCompletionFunc(passwdEntryName, completion.AutocompleteNone)
|
||||
|
||||
groupEntryName := "group-entry"
|
||||
createFlags.StringVar(&cf.GroupEntry, groupEntryName, "", "Entry to write to /etc/group")
|
||||
_ = cmd.RegisterFlagCompletionFunc(groupEntryName, completion.AutocompleteNone)
|
||||
|
||||
decryptionKeysFlagName := "decryption-key"
|
||||
createFlags.StringSliceVar(
|
||||
&cf.DecryptionKeys,
|
||||
|
9
docs/source/markdown/options/group-entry.md
Normal file
9
docs/source/markdown/options/group-entry.md
Normal file
@ -0,0 +1,9 @@
|
||||
####> This option file is used in:
|
||||
####> podman create, run
|
||||
####> If file is edited, make sure the changes
|
||||
####> are applicable to all of those.
|
||||
#### **--group-entry**=*ENTRY*
|
||||
|
||||
Customize the entry that is written to the `/etc/group` file within the container when `--user` is used.
|
||||
|
||||
The variables $GROUPNAME, $GID, and $USERLIST are automatically replaced with their value at runtime if present.
|
@ -161,6 +161,8 @@ See [**Environment**](#environment) note below for precedence and examples.
|
||||
|
||||
@@option group-add
|
||||
|
||||
@@option group-entry
|
||||
|
||||
@@option health-cmd
|
||||
|
||||
@@option health-interval
|
||||
|
@ -194,6 +194,8 @@ See [**Environment**](#environment) note below for precedence and examples.
|
||||
|
||||
@@option group-add
|
||||
|
||||
@@option group-entry
|
||||
|
||||
@@option health-cmd
|
||||
|
||||
@@option health-interval
|
||||
|
@ -354,6 +354,8 @@ type ContainerMiscConfig struct {
|
||||
CgroupsMode string `json:"cgroupsMode,omitempty"`
|
||||
// Cgroup parent of the container.
|
||||
CgroupParent string `json:"cgroupParent"`
|
||||
// GroupEntry specifies arbitrary data to append to a file.
|
||||
GroupEntry string `json:"group_entry,omitempty"`
|
||||
// LogPath log location
|
||||
LogPath string `json:"logPath"`
|
||||
// LogTag is the tag used for logging
|
||||
|
@ -2226,7 +2226,7 @@ func (c *Container) generateGroupEntry() (string, error) {
|
||||
groupString += entry
|
||||
addedGID = gid
|
||||
}
|
||||
if c.config.User != "" {
|
||||
if c.config.User != "" || c.config.GroupEntry != "" {
|
||||
entry, err := c.generateUserGroupEntry(addedGID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -2281,7 +2281,7 @@ func (c *Container) generateCurrentUserGroupEntry() (string, int, error) {
|
||||
// Make an entry in /etc/group for the group the container was specified to run
|
||||
// as.
|
||||
func (c *Container) generateUserGroupEntry(addedGID int) (string, error) {
|
||||
if c.config.User == "" {
|
||||
if c.config.User == "" && c.config.GroupEntry == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
@ -2301,14 +2301,26 @@ func (c *Container) generateUserGroupEntry(addedGID int) (string, error) {
|
||||
}
|
||||
|
||||
// Check if the group already exists
|
||||
_, err = lookup.GetGroup(c.state.Mountpoint, group)
|
||||
g, err := lookup.GetGroup(c.state.Mountpoint, group)
|
||||
if err != runcuser.ErrNoGroupEntries {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if c.config.GroupEntry != "" {
|
||||
return c.groupEntry(g.Name, strconv.Itoa(g.Gid), g.List), nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%d:x:%d:%s\n", gid, gid, splitUser[0]), nil
|
||||
}
|
||||
|
||||
func (c *Container) groupEntry(groupname, gid string, list []string) string {
|
||||
s := c.config.GroupEntry
|
||||
s = strings.ReplaceAll(s, "$GROUPNAME", groupname)
|
||||
s = strings.ReplaceAll(s, "$GID", gid)
|
||||
s = strings.ReplaceAll(s, "$USERLIST", strings.Join(list, ","))
|
||||
return s + "\n"
|
||||
}
|
||||
|
||||
// generatePasswdEntry generates an entry or entries into /etc/passwd as
|
||||
// required by container configuration.
|
||||
// Generally speaking, we will make an entry under two circumstances:
|
||||
@ -2488,7 +2500,7 @@ func (c *Container) generateUserPasswdEntry(addedUID int) (string, error) {
|
||||
return fmt.Sprintf("%d:*:%d:%d:container user:%s:/bin/sh\n", uid, uid, gid, c.WorkingDir()), nil
|
||||
}
|
||||
|
||||
func (c *Container) passwdEntry(username string, uid, gid, name, homeDir string) string {
|
||||
func (c *Container) passwdEntry(username, uid, gid, name, homeDir string) string {
|
||||
s := c.config.PasswdEntry
|
||||
s = strings.ReplaceAll(s, "$USERNAME", username)
|
||||
s = strings.ReplaceAll(s, "$UID", uid)
|
||||
@ -2512,7 +2524,7 @@ func (c *Container) passwdEntry(username string, uid, gid, name, homeDir string)
|
||||
// read-only. In this case, the function will return nothing ("", "", nil).
|
||||
func (c *Container) generatePasswdAndGroup() (string, string, error) {
|
||||
if !c.config.AddCurrentUserPasswdEntry && c.config.User == "" &&
|
||||
len(c.config.HostUsers) == 0 {
|
||||
len(c.config.HostUsers) == 0 && c.config.GroupEntry == "" {
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
|
@ -2277,6 +2277,19 @@ func WithPasswdEntry(passwdEntry string) CtrCreateOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithGroupEntry sets the entry to write to the /etc/group file.
|
||||
func WithGroupEntry(groupEntry string) CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return define.ErrCtrFinalized
|
||||
}
|
||||
|
||||
ctr.config.GroupEntry = groupEntry
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithMountAllDevices sets the option to mount all of a privileged container's
|
||||
// host devices
|
||||
func WithMountAllDevices() CtrCreateOption {
|
||||
|
@ -301,6 +301,7 @@ type ContainerCreateOptions struct {
|
||||
|
||||
CgroupConf []string
|
||||
|
||||
GroupEntry string
|
||||
PasswdEntry string
|
||||
}
|
||||
|
||||
|
@ -312,6 +312,9 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
|
||||
if s.PasswdEntry != "" {
|
||||
options = append(options, libpod.WithPasswdEntry(s.PasswdEntry))
|
||||
}
|
||||
if s.GroupEntry != "" {
|
||||
options = append(options, libpod.WithGroupEntry(s.GroupEntry))
|
||||
}
|
||||
|
||||
if s.Privileged {
|
||||
options = append(options, libpod.WithMountAllDevices())
|
||||
|
@ -160,7 +160,7 @@ type ContainerBasicConfig struct {
|
||||
// Conflicts with UtsNS if UtsNS is not set to private.
|
||||
// Optional.
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
// HostUses is a list of host usernames or UIDs to add to the container
|
||||
// HostUsers is a list of host usernames or UIDs to add to the container
|
||||
// /etc/passwd file
|
||||
HostUsers []string `json:"hostusers,omitempty"`
|
||||
// Sysctl sets kernel parameters for the container
|
||||
@ -219,6 +219,8 @@ type ContainerBasicConfig struct {
|
||||
Passwd *bool `json:"manage_password,omitempty"`
|
||||
// PasswdEntry specifies arbitrary data to append to a file.
|
||||
PasswdEntry string `json:"passwd_entry,omitempty"`
|
||||
// GroupEntry specifies arbitrary data to append to a file.
|
||||
GroupEntry string `json:"group_entry,omitempty"`
|
||||
}
|
||||
|
||||
// ContainerStorageConfig contains information on the storage configuration of a
|
||||
|
@ -848,6 +848,10 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
|
||||
s.PasswdEntry = c.PasswdEntry
|
||||
}
|
||||
|
||||
if len(s.GroupEntry) == 0 || len(c.GroupEntry) != 0 {
|
||||
s.GroupEntry = c.GroupEntry
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -153,4 +153,16 @@ USER 1000`, ALPINE)
|
||||
Expect(run).Should(Exit(0))
|
||||
Expect(run.OutputToString()).To(ContainSubstring("12345-12346-container user-/etc-12345"))
|
||||
})
|
||||
|
||||
It("podman run --group-entry flag", func() {
|
||||
// Test that the line we add doesn't contain anything else than what is specified
|
||||
run := podmanTest.Podman([]string{"run", "--user", "1234:1234", "--group-entry=FOO", ALPINE, "grep", "^FOO$", "/etc/group"})
|
||||
run.WaitWithDefaultTimeout()
|
||||
Expect(run).Should(Exit(0))
|
||||
|
||||
run = podmanTest.Podman([]string{"run", "--user", "12345:12346", "--group-entry=$GID", ALPINE, "tail", "/etc/group"})
|
||||
run.WaitWithDefaultTimeout()
|
||||
Expect(run).Should(Exit(0))
|
||||
Expect(run.OutputToString()).To(ContainSubstring("12346"))
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user