FAQ
I have a home directory being created and not removed as a user is
added/removed. That is desired behavior. However, there are certain
files/dirs in that home directory that I want to always remove if the user
gets marked absent. Unfortunately, the dependencies lead back to the home
directory, which leads to the user, and since the user is removed first,
the removal of files/dirs in the homedir always gets skipped because of
failed dependencies. The files are always referred to as
${homedir}/${username}/<file_to_be_removed>. Does anyone have an elegant
solution to this problem?

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/6A-0i7X5p3IJ.
To post to this group, send email to puppet-users@googlegroups.com.
To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.

Search Discussions

  • Keiran Sweet at Dec 17, 2012 at 5:21 pm
    Hi,
    I have found when working with user accounts it is very beneficial to
    create a defined type that allows you to wrap alot of functionality into
    one definition, thus reducing manual work and being more explicit with your
    requirements for user data and account configuration when they are defined
    as being present or absent.

    The Puppet documentation about defined types can be found here:
    http://docs.puppetlabs.com/learning/definedtypes.html , and it has a couple
    of examples that should get you going.

    In my environment I have a type similar to the below:

    class tg_accounts {

    tg_accounts::setup_user_account { 'sweetk' :
    user => 'sweetk',
    uid => 12345,
    gid => 12345,
    ssh_key_type => 'ssh-dss',
    actual_name => 'Keiran S',
    shell => '/bin/bash',
    ssh_key => 'THE-LONG-SSH-PUBLIC-KEY-GOES-HERE',
    }
    }

    Within this type the following things are done based on the above input:
    * Create a group and user with the uid/gid/actual_name/shell/ values passed
    to the type and ensure the user is a member of the group.
    * Setup a home directory for the user and enforce the permissions on it to
    be as per the sites standard
    * Setup a .ssh directory in the users home directory and enforce its
    required permissions for security with SSH keys
    * Populate the users authorized_keys file with the key defined in ssh_key
    of the type defined in ssh_key_type so they can login with key based auth
    from their workstations
    * Copy the /etc/skel/ files such as .bash_profile & .bashrc into the home
    directory if they are found to be absent as the User type doesnt currently
    support the skeleton framework at this stage.
    * There is also an optional md5_password_hash option you can pass to the
    type that will set a users password hash to a particular string if you feel
    this is required for some accounts

    Once you have your logic in place, the user configuration will then be
    validated to be correct every puppet run which for me has been a godsend.

    One thing worth noting however with user accounts is that when you start
    managing large numbers of users in this fashion your puppet runs are likely
    to slow down , and that a central user repository would then be more ideal
    (ie LDAP).

    Cheers,

    K








    On Monday, December 17, 2012 4:12:05 PM UTC, j wrote:

    I have a home directory being created and not removed as a user is
    added/removed. That is desired behavior. However, there are certain
    files/dirs in that home directory that I want to always remove if the user
    gets marked absent. Unfortunately, the dependencies lead back to the home
    directory, which leads to the user, and since the user is removed first,
    the removal of files/dirs in the homedir always gets skipped because of
    failed dependencies. The files are always referred to as
    ${homedir}/${username}/<file_to_be_removed>. Does anyone have an elegant
    solution to this problem?
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/atu52IsRFs8J.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • J at Dec 18, 2012 at 1:12 am
    Thank you for the reply, however I do not see where that resolves the
    dependency problem. Let me paste what I've been playing with as maybe that
    will clarify my problem:

    class admins($username, $ensure='present') {
    if $ensure == 'present' {
    $dirensure = 'directory'
    }
    elsif $ensure == 'absent' {
    $dirensure = "$ensure"
    }
    file { "${homedir}/${username}":
    owner => "$username",
    group => "$username",
    ensure => directory,
    mode => 700,
    }
    file { "${homedir}/${username}/somedir":
    owner => "$username",
    group => "$username",
    ensure => "$dirensure",
    mode => 700,
    }
    user { "$username":
    ensure => "$ensure",
    home => "${homedir}/${username}",
    shell => "$shell",
    }
    }

    Puppet apply does as expected when called as
    class { 'users': username => 'testuser', ensure => 'present' }

    but when removing a user with:
    class { 'users': username => 'testuser', ensure => 'absent' }

    I get the following error:

    debug: User[testuser](provider=useradd): Executing '/usr/sbin/userdel
    testuser'
    notice: /Stage[main]/Users/User[testuser]/ensure: removed
    err: /Stage[main]/Users/File[/home/testuser]: Could not evaluate: Could not
    find user testuser
    notice: /Stage[main]/Users/File[/home/testuser/somedir]: Dependency
    File[/home/testuser] has failures: true
    warning: /Stage[main]/Users/File[/home/testuser/somedir]: Skipping because
    of failed dependencies

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/w913Sj-Bv5IJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Keiran Sweet at Dec 18, 2012 at 9:54 am
    Hi There,
    Thanks for the additional information it actually helps me understand what
    you are trying to achieve a bit better.

    As per the types documentation, this line is quite important to understand:
    "Classes are good for modelling singleton aspects of a system, but to model
    repeatable chunks of configuration — like a Git repository or an Apache
    vhost — you should use defined resource types."

    In your case, its ideal because you are likely to want to manage a few
    admin accounts I am guessing.
    In addition to this, you likely need to understand resource dependency,
    there is a good section on resource ordering here:

    http://docs.puppetlabs.com/learning/ordering.html

    Based on your logic, I am assuming you wish to have
    the following functionality

    * When an admin account is present
    - Have a user created
    - The new user has a home directory that needs to have certain permissions
    and ownership enforced
    - We also create a dir called 'somedir' under the users home directory

    * When an admin account is marked as absent
    - The directories are removed
    - The user account is removed
    (In that order)

    Here is a defined type that should help you out a little with how this can
    function:

    ---------------SNIP------------------

    # Defined type called setup_admin_account that allows us to wrap admin tasks
    # into a logical grouping

    define setup_admin_account ($username , $ensure=present, $homedirpath =
    '/home') {

    case $ensure {

    present : {


    user { $username :
    ensure => present,
    home => "${homedirpath}/${username}",
    shell => '/bin/bash',
    }


    file { "${homedirpath}/${username}" :
    ensure => directory,
    owner => $username,
    group => $username,
    mode => 0700,
    require => User[$username],
    }


    file { "${homedirpath}/${username}/somedir/" :
    ensure => directory,
    owner => $username,
    group => $username,
    mode => 0700,
    require => File["${homedirpath}/${username}"],
    }



    }



    absent : {



    user { $username :
    ensure => absent,
    require => File["${homedirpath}/${username}"],
    }


    file { "${homedirpath}/${username}" :
    ensure => absent,
    force => true,
    require =>
    File["${homedirpath}/${username}/somedir/"],
    }

    file { "${homedirpath}/${username}/somedir/":
    ensure => absent,
    force => true,
    }


    }
    }

    }

    #
    # Using the type to manage a user called test user
    # Change present to absent as required.
    # Note we can have as many of these user definitions as required.
    #
    setup_admin_account { 'testuser' :
    username => 'testuser',
    ensure => present,
    }



    ---------------SNIP------------------

    Example output:

    When we have:

    setup_admin_account { 'testuser' :
    username => 'testuser',
    ensure => present,
    }


    # puppet apply setup_admin_user.pp
    notice: /Stage[main]//Setup_admin_account[testuser]/User[testuser]/ensure:
    created
    notice:
    /Stage[main]//Setup_admin_account[testuser]/File[/home/testuser]/ensure:
    created
    notice:
    /Stage[main]//Setup_admin_account[testuser]/File[/home/testuser/somedir/]/ensure:
    created
    notice: Finished catalog run in 0.35 seconds

    When we have:

    setup_admin_account { 'testuser' :
    username => 'testuser',
    ensure => absent,
    }



    # puppet apply setup_admin_user.pp
    notice:
    /Stage[main]//Setup_admin_account[testuser]/File[/home/testuser/somedir/]/ensure:
    removed
    notice:
    /Stage[main]//Setup_admin_account[testuser]/File[/home/testuser]/ensure:
    removed
    notice: /Stage[main]//Setup_admin_account[testuser]/User[testuser]/ensure:
    removed
    notice: Finished catalog run in 0.31 seconds
    [root@lg2infra01 tmp]#


    I hope this answers your question a little.

    Cheers,

    K

    Extra note:
    It is also worth noting that if you are doing destructive tasks, such as
    recursive directory removal that you validate you data.
    Ie, check that the home directory your removing hasnt somehow been
    evaluated to / or /home due to bad variables, etc.

    On Tuesday, December 18, 2012 1:12:22 AM UTC, j wrote:

    Thank you for the reply, however I do not see where that resolves the
    dependency problem. Let me paste what I've been playing with as maybe that
    will clarify my problem:

    class admins($username, $ensure='present') {
    if $ensure == 'present' {
    $dirensure = 'directory'
    }
    elsif $ensure == 'absent' {
    $dirensure = "$ensure"
    }
    file { "${homedir}/${username}":
    owner => "$username",
    group => "$username",
    ensure => directory,
    mode => 700,
    }
    file { "${homedir}/${username}/somedir":
    owner => "$username",
    group => "$username",
    ensure => "$dirensure",
    mode => 700,
    }
    user { "$username":
    ensure => "$ensure",
    home => "${homedir}/${username}",
    shell => "$shell",
    }
    }

    Puppet apply does as expected when called as
    class { 'users': username => 'testuser', ensure => 'present' }

    but when removing a user with:
    class { 'users': username => 'testuser', ensure => 'absent' }

    I get the following error:

    debug: User[testuser](provider=useradd): Executing '/usr/sbin/userdel
    testuser'
    notice: /Stage[main]/Users/User[testuser]/ensure: removed
    err: /Stage[main]/Users/File[/home/testuser]: Could not evaluate: Could
    not find user testuser
    notice: /Stage[main]/Users/File[/home/testuser/somedir]: Dependency
    File[/home/testuser] has failures: true
    warning: /Stage[main]/Users/File[/home/testuser/somedir]: Skipping because
    of failed dependencies
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/MwPWMAjdbXwJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • J at Dec 31, 2012 at 2:37 am
    I'm sorry for the late reply. I've been on holiday. Your suggestion was
    exactly what I needed and has helped me in more ways than just the users
    module. Thank you so much!

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/hq6yEyyEEoQJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Stuart Cracraft at Dec 31, 2012 at 3:54 am
    J slavetonagios:

    Can you give the group more detail about how it helped you?

    Stuart
    On Dec 30, 2012, at 6:36 PM, j wrote:

    I'm sorry for the late reply. I've been on holiday. Your suggestion was exactly what I needed and has helped me in more ways than just the users module. Thank you so much!

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/hq6yEyyEEoQJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • J at Jan 1, 2013 at 3:59 pm
    Sure. My mistake came from thinking that a class whose resources all had
    variable titles, like file { "/path/$varname":, could be called multiple
    times as long as each call had a unique value for the variable. Once that
    bit was sorted I wrote my users type nearly identically to Keiran's
    example. Eventually I made it a sub-type (terminology?) in that it went
    from being just users to users::adduser because I found a need for a
    singleton file in the users class and I could call the class indirectly
    from inside the type with include users.

    On Sunday, December 30, 2012 10:54:36 PM UTC-5, Stuart Cracraft wrote:

    J slavetonagios:

    Can you give the group more detail about how it helped you?

    Stuart
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/0xaHPDmlVcwJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppuppet-users @
categoriespuppet
postedDec 17, '12 at 4:13p
activeJan 1, '13 at 3:59p
posts7
users3
websitepuppetlabs.com

People

Translate

site design / logo © 2022 Grokbase