The Puppet Labs Issue Tracker has Moved: https://tickets.puppetlabs.com

Bug #9337

OS X Lion group membership not updated

Added by David Thompson over 2 years ago. Updated about 1 month ago.

Status:InvestigatingStart date:09/06/2011
Priority:HighDue date:
Assignee:Nigel Kersten% Done:

0%

Category:OSX
Target version:-
Affected Puppet version:2.7.3 Branch:
Keywords:

We've Moved!

Ticket tracking is now hosted in JIRA: https://tickets.puppetlabs.com

This ticket is now tracked at: https://tickets.puppetlabs.com/browse/PUP-1728


Description

Switching to puppet (2.7.3) for managing my OS X Lion systems, I’m finding group membership not being updated. Couldn’t find a dup for this, hope the information helps…

Starting out, user dt is not a member of group dt-grp:

# dscl . read /groups/dt-grp | grep GroupMembership
GroupMembership:

…Run puppet, says it adds to the group:

# puppet agent --test --environment production
info: Caching catalog for cypress.keck.waisman.wisc.edu
info: Applying configuration version '1315332406'
notice: /Stage[main]/Users_test/User[dt]/groups: groups changed '' to 'dt-grp'
notice: Finished catalog run in 0.89 seconds

…but the user still isn’t part of the group:

# dscl . read /groups/dt-grp | grep GroupMembership
GroupMembership:

…Hrm, let’s add the user manually…just like the puppet code does…

# dseditgroup -o edit -n . -a dt dt-grp
# dscl . read /groups/dt-grp | grep GroupMembership
GroupMembership: dt

…But puppet still tries to add the user to the group…

# puppet agent --test --environment production
info: Caching catalog for cypress.keck.waisman.wisc.edu
info: Applying configuration version '1315332406'
notice: /Stage[main]/Users_test/User[dt]/groups: groups changed '' to 'dt-grp'
notice: Finished catalog run in 0.83 seconds

init.pp (369 Bytes) David Thompson, 09/08/2011 10:14 am

puppet-users-mac.pp (253 KB) David Thompson, 09/09/2011 10:52 am

History

#1 Updated by James Turnbull over 2 years ago

  • Description updated (diff)
  • Affected Puppet version set to 2.7.3

#2 Updated by James Turnbull over 2 years ago

  • Status changed from Unreviewed to Needs Decision
  • Assignee set to Nigel Kersten

Nigel – does this look like any of the other Lion issues?

#3 Updated by Nigel Kersten over 2 years ago

  • Status changed from Needs Decision to Needs More Information

I can’t reproduce this at all on Lion.

(note you should query the GroupMembership attribute directly rather than grepping for it.)

First I start with an empty group:

kripke:root root# cat /tmp/dt-group.pp 
group { 'dt-group':
  ensure  => 'present',
  gid     => '800',
  members => [],
}

then apply it:

kripke:root root# puppet apply -v /tmp/dt-group.pp 
info: /Group[dt-group]: Provider directoryservice does not support features manages_aix_lam; not managing attribute ia_load_module
info: Applying configuration version '1315498529'
notice: /Group[dt-group]/ensure: created
notice: Finished catalog run in 0.47 seconds

then check it:

kripke:root root# dscl . -read /Groups/dt-group GroupMembership
No such key: GroupMembership

Now I try adding one account to the group:

kripke:root root# cat /tmp/dt-group.pp 
group { 'dt-group':
  ensure  => 'present',
  gid     => '800',
  members => ['nbk'],
}

Apply it:

kripke:root root# puppet apply -v /tmp/dt-group.pp 
info: /Group[dt-group]: Provider directoryservice does not support features manages_aix_lam; not managing attribute ia_load_module
info: Applying configuration version '1315498613'
notice: /Group[dt-group]/members: defined 'members' as 'nbk'
notice: Finished catalog run in 0.15 seconds

Check it:

kripke:root root# dscl . -read /Groups/dt-group GroupMembership
GroupMembership: nbk

And then another account, same cycle:

kripke:root root# cat /tmp/dt-group.pp 
group { 'dt-group':
  ensure  => 'present',
  gid     => '800',
  members => ['nbk','demo'],
}
kripke:root root# puppet apply -v /tmp/dt-group.pp 
info: /Group[dt-group]: Provider directoryservice does not support features manages_aix_lam; not managing attribute ia_load_module
info: Applying configuration version '1315498667'
notice: /Group[dt-group]/members: members changed 'nbk' to 'nbk,demo'
notice: Finished catalog run in 0.15 seconds
kripke:root root# dscl . -read /Groups/dt-group GroupMembership
GroupMembership: nbk demo

System:

kripke:root root# dscl . -read /Groups/dt-group GroupMembership
GroupMembership: nbk demo
kripke:root root# puppet --version
2.7.3
kripke:root root# sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.7.1
BuildVersion:   11B26

???

#4 Updated by David Thompson over 2 years ago

Hi Nigel, thanks for looking at this.

Yes, I’m a puppet noob. I was following the information at

http://docs.puppetlabs.com/references/stable/type.html#group-2

…which seemed to indicate that group memberships should be specified via the groups attribute of the user type, not the members attribute of the group type (see attachment). If I specify the group membership as you have, yes, membership is updated properly.

So the rest of this becomes a (gentle) rant. If the OS X provider can’t update groups based on User => groups information, providing it there should either be ignored or cause an error. OTOH, it breaks the abstraction to say that for some architectures/providers the information must be in the Group => members attribute and for others it must be provided via User => groups.

Is there a way out of this so that I only have to have a single Users/Groups definition for all my architectures?

#5 Updated by Nigel Kersten over 2 years ago

Yes, this isn’t ideal, and I’m sorry, as the initial design decision was actually mine, so I created this crappy situation.

It’s much more difficult for us to model group membership as an attribute of the user, but we need to do it.

In the meantime we do need to throw an error, and I’ll get those bugs characterized soon.

It definitely breaks the abstraction, and in the past I’ve considered ideas such as a ‘groupmembership’ type so that you can express intent like:

  • Ensure “nigel” is in group “admin”
  • Ensure “nigel” is not in group “admin”

without having to actually manage “nigel” or “admin”.

I think this is a good move, primarily because it actually enforces a higher degree of abstraction, allowing us to work more easily with both kinds of systems, the ones that consider group membership to be an attribute of the user, and those that consider it to be an attribute of a group.

Input much appreciated :)

#6 Updated by David Thompson over 2 years ago

Nigel, I like you. Thanks for being so forthcoming. And don’t get me wrong. I like puppet (alot!).

Yes, group memberships may best be abstracted as a separate entity from either users or groups. That’s how they’re represented in my database :)

In the mean time, since I’m dumping the information from a database, I can reasonably dump it in multiple formats.

Cheers. Feel free to close this bug, or whatever, at your convenience.

#7 Updated by Nigel Kersten over 2 years ago

  • Status changed from Needs More Information to Closed
  • Keywords set to lion

thanks :)

#8 Updated by David Thompson over 2 years ago

On second thought, there is still a bug here. I can’t apply the following class on Lion:

class users_test {

  group { 'dt-grp' :
    ensure => present,
    gid    => 1539,
    members => [ 'dt' ],
  }

  user { 'dt' :
    ensure     => present,
    managehome => false,
    membership => inclusive,
    uid        => 1539,
    gid        => 1539,
    shell      => '/bin/bash',
    home       => '/home/dt',
    comment    => 'David Thompson',
  }

}

The user auto-requires the group. The group add fails because the user doesn’t exist, and the user doesn’t add because the group dependency had failures. Would I guess correctly that this is why the group memberships are specified in the User records (usually)? What’s the solution here?

#9 Updated by Nigel Kersten over 2 years ago

The user won’t actually auto-require the group, because we’re just setting gid numerically.

This does kind of suck, but you can solve this like this:

  group { 'dt-grp' :
    ensure => present,
    gid    => 1539,
    members => [ 'dt' ],
    require => User['dt'],
  }

  user { 'dt' :
    ensure     => present,
    uid        => 1539,
    gid        => 1539,
    shell      => '/bin/bash',
    home       => '/home/dt',
    comment    => 'David Thompson',
  }

We should probably have the mac group provider auto-require any users who are specified as members.

Note another thing we don’t support is the fact OS X can support nested groups, where groups are members of groups.

There are lots of conceptual problems here, but it does work once you get your head around it ;)

#10 Updated by David Thompson over 2 years ago

I’m getting a dependency cycle when I run this with my full user list:

err: Could not apply complete catalog: Found 1 dependency cycle: (Group[dusers] => User[law] => Group[nccamgrp] => User[nondahl] => Group[dusers]) Try the ‘—graph’ option and opening the resulting ‘.dot’ file in OmniGraffle or GraphViz

I’ve attached the whole user list if you really want to try applying it…

#11 Updated by Nigel Kersten over 2 years ago

  • Status changed from Closed to Investigating
  • Priority changed from Normal to High
  • Keywords deleted (lion)

Argh. This is why you’re having that problem…

https://github.com/puppetlabs/puppet/blob/master/lib/puppet/type/user.rb#L17

Autorequires: If Puppet is managing the user’s primary group (as provided in the gid attribute), the user resource will autorequire that group. If Puppet is managing any role accounts corresponding to the user’s roles, the user resource will autorequire those role accounts.”

This clearly isn’t ideal for a world where group membership is defined by the group…

#12 Updated by Jesse Endahl about 1 month ago

Redmine Issue #9337 has been migrated to JIRA:

https://tickets.puppetlabs.com/browse/PUP-1728

Also available in: Atom PDF