Jira (PUP-9465) group resource type should support lgroupadd provider on Linux

2 views
Skip to first unread message

James Ralston (JIRA)

unread,
Jan 24, 2019, 5:16:03 PM1/24/19
to puppe...@googlegroups.com
James Ralston created an issue
 
Puppet / New Feature PUP-9465
group resource type should support lgroupadd provider on Linux
Issue Type: New Feature New Feature
Affects Versions: PUP 6.1.0
Assignee: Unassigned
Components: Types and Providers
Created: 2019/01/24 2:15 PM
Priority: Normal Normal
Reporter: James Ralston

Puppet Version: 6.1.0
Puppet Server Version: 6.1.0
OS Name/Version: Red Hat Enterprise Linux 7

The group resource type supports the groupadd provider, but not the lgroupadd provider.

lgroupadd (and lgroupmod and lgroupdel) are part of the libuser library/package. While libuser is essentially a rewrite of the groupadd, groupmod, and groupdel programs from the shadow-utils package (because Red Hat tends toward NIH syndrome), lgroupmod has one important advantage over groupmod: lgroupmod can manipulate group members directly.

E.g., you can do this:

$ lgroupmod --member-add user1,user2,user3 somegroup

In contrast, groupmod cannot do this. Instead, you have to do this:

$ usermod -a -G somegroup user1
$ usermod -a -G somegroup user2
$ usermod -a -G somegroup user3

This is why the groupadd provider for the group resource type lacks the manages_members feature.

The implication of this is that in Puppet, if you want to have a class manage the contents of a group, the only way to do it (using default resource types) is to manage user resources for each user who should be a member of the group. But this doesn't scale, because if any other module is attempting to manage a user resource type for the same user, the resources will clash.

In contrast, if support were added for the lgroupadd provider, the manages_members feature could be enabled for it. This would permit managing the membership of an arbitrary group by managing a single group resource for the group, instead of managing individual user resources.

Granted, this could create the state where a Puppet user resource using the useradd provider could "fight" with a Puppet group resource using the lgroupadd provider. But this potential for conflict already exists in other places in Puppet (e.g., augeas resources can cheerfully fight with file resources). So I don't think the potential for conflict is a reason to avoid adding the lgroupadd provider.

So, in summary, I think Puppet should add support for the lgroupadd provider (and company) for the group resource type on platforms where the libuser library/package is available: Fedora, Red Hat, CentOS, and potentially others.

Yay or nay?

(I may be able to work on adding this provider myself, but I don't want to spend the time on a merge request if Puppet is philosophically opposed to adding support for the lgroupadd provider.)

Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v7.7.1#77002-sha1:e75ca93)
Atlassian logo

Melissa Stone (JIRA)

unread,
Jan 28, 2019, 1:57:03 PM1/28/19
to puppe...@googlegroups.com
Melissa Stone commented on New Feature PUP-9465
 
Re: group resource type should support lgroupadd provider on Linux

Hi James Ralston! We actually already have support for the local group utilities.

 

If you check out the group resource, you'll see the add, modify, and delete methods all have this little block

    if @resource.forcelocal?
      cmd = [command(:localmodify)]
      @custom_environment = Puppet::Util::Libuser.getenv
    else
      cmd = [command(:modify)]
    end

 In this case, `command(:modify)` will resolve to `groupmod` and `command(:localmodify)` will resolve to `lgroupmod`.

 

You have to set `forcelocal => true` for any group resource that you want to use the local commands. Check out the docs for more details https://puppet.com/docs/puppet/latest/types/group.html#group-attribute-forcelocal

 

Rob Braden (JIRA)

unread,
Feb 4, 2019, 5:04:03 PM2/4/19
to puppe...@googlegroups.com

James Ralston (JIRA)

unread,
Jul 30, 2019, 6:08:04 PM7/30/19
to puppe...@googlegroups.com
James Ralston commented on New Feature PUP-9465
 
Re: group resource type should support lgroupadd provider on Linux

Hi Melissa Stone, Branan Riley,

I apologize for taking so long to get back to this. I've reopened this ticket, because I believe there is a fundamental mis-engineering here that should be addressed.

Both the Puppet code and the responses to this ticket imply that the Puppet devs believe that lgroupmod is the "local" version of groupmod. But this is not the case.

The (groupadd, groupmod, groupdel) programs belong to the shadow project. These utilities explicitly operate on local files (/etc/passwd, /etc/shadow, /etc/group, /etc/gshadow) only.

The (lgroupadd, lgroupmod, lgroupdel) programs belong to the libuser project. Per its documentation, libuser is a library that implements a standardized interface for manipulating and administering user and group accounts, using pluggable back-ends to interface to data sources. Currently, local files and LDAP backends are supported. In essence, it's a more capable replacement for shadow-utils, designed to easier to maintain (because it's not carrying around 20+ years of warts).

It is not the case that the "l" in lgroupmod et. al. means local; it means libuser.

The model that Puppet resource types use is that when there are multiple methods that can accomplish a backend task, each method is enumerated as a separate provider, and Puppet chooses the best provider on a per-platform basis. That is a clean, beautiful, easy-to-understand model; it's one of the clear design wins of Puppet. It is what Puppet administrators and developers are used to.

This is why the forcelocal parameter is so egregiously wrong and offensive. If Puppet understood how to use the (lgroupadd, lgroupmod, lgroupdel) programs, I fully expected to see Puppet's usage of those programs encapsulated by a separate libuser provider. Seeing no such provider, and searching the documentation in vain for any explicit mention of the (lgroupadd, lgroupmod, lgroupdel) programs, I concluded Puppet did not understand how to use the (lgroupadd, lgroupmod, lgroupdel) programs.

(Yes, the documentation does mention libuser. But it does so in a way that has no relation to what libuser actually is and what it actually does.)

Fortunately, there is an easy path out of this mess for the group resource:

  • Turn the libuser provider feature into a provider proper, which uses the (lgroupadd, lgroupmod, lgroupdel) programs. The libuser provider should have the manages_members and system_groups features.
  • If both the libuser provider and the groupadd provider are available, prefer the libuser provider.
  • Deprecate the forcelocal parameter, and emit a warning if it is set to true.
  • As a special case, for backwards compatibility, if the groupadd provider was specified and the forcelocal parameter was true, use the libuser provider instead of the groupadd provider.

Taking the above steps will correct the long-standing mis-engineering of the group resource, aligning it with the proper Puppet provider model.

Reply all
Reply to author
Forward
0 new messages