Managing users' customization files
Users tend to customize their shell environments, terminal colors, aliases, and so forth. This is usually achieved by a number of dotfiles in their home directory, for example, .bash_profile
or .vimrc
.
You can use Puppet to synchronize and update each user's dotfiles across a number of machines by extending the virtual user setup we developed throughout this chapter. We'll start a new module, admin_user
and use the file types, recurse
attribute to copy files into each user's home directory.
How to do it...
Here's what you need to do:
- Create the
admin_user
defined type (define admin_user
) in themodules/admin_user/manifests/init.pp
file as follows:define admin_user ($key, $keytype, $dotfiles = false) { $username = $name user { $username: ensure => present, } file { "/home/${username}/.ssh": ensure => directory, mode => '0700', owner => $username, group => $username, require => File["/home/${username}"], } ssh_authorized_key { "${username}_key": key => $key, type => "$keytype", user => $username, require => File["/home/${username}/.ssh"], } # dotfiles if $dotfiles == false { # just create the directory file { "/home/${username}": ensure => 'directory', mode => '0700', owner => $username, group => $username, require => User["$username"] } } else { # copy in all the files in the subdirectory file { "/home/${username}": recurse => true, mode => '0700', owner => $username, group => $username, source => "puppet:///modules/admin_user/${username}", require => User["$username"] } } }
- Modify the file
modules/user/manifests/sysadmins.pp
as follows:class user::sysadmins { realize(Admin_user['thomas']) }
- Alter the definition of
thomas
inmodules/user/manifests/virtual.pp
as follows:@ssh_user { 'thomas': key => 'AAAAB3NzaC1yc2E...XaWM5sX0z', keytype => 'ssh-rsa', dotfiles => true }
- Create a subdirectory in the
admin_user
module for the file of userthomas
:$ mkdir -p modules/admin_user/files/thomas
- Create dotfiles for the user
thomas
in the directory you just created:$ echo "alias vi=vim" > modules/admin_user/files/thomas/.bashrc $ echo "set tabstop=2" > modules/admin_user/files/thomas/.vimrc
- Make sure your
site.pp
file reads as follows:node 'cookbook' { include user::virtual include user::sysadmins }
- Run Puppet:
cookbook# puppet agent -t Info: Caching catalog for cookbook.example.com Info: Applying configuration version '1413266235' Notice: /Stage[main]/User::Virtual/Admin_user[thomas]/User[thomas]/ensure: created Notice: /Stage[main]/User::Virtual/Admin_user[thomas]/File[/home/thomas]/ensure: created Notice: /Stage[main]/User::Virtual/Admin_user[thomas]/File[/home/thomas/.vimrc]/ensure: defined content as '{md5}cb2af2d35b18b5ac2539057bd429d3ae' Notice: /Stage[main]/User::Virtual/Admin_user[thomas]/File[/home/thomas/.bashrc]/ensure: defined content as '{md5}033c3484e4b276e0641becc3aa268a3a' Notice: /Stage[main]/User::Virtual/Admin_user[thomas]/File[/home/thomas/.ssh]/ensure: created Notice: /Stage[main]/User::Virtual/Admin_user[thomas]/Ssh_authorized_key[thomas_key]/ensure: created Notice: Finished catalog run in 0.36 seconds
How it works...
We created a new admin_user
definition, which defines the home directory recursively if $dotfiles
is not false
(the default value):
if $dotfiles == 'false' { # just create the directory file { "/home/${username}": ensure => 'directory', mode => '0700', owner => $username, group => $username, require => User["$username"] } } else { # copy in all the files in the subdirectory file { "/home/${username}": recurse => true, mode => '0700', owner => $username, group => $username, source => "puppet:///modules/admin_user/${username}", require => User["$username"] } }
We created a directory to hold the user's dotfiles within the admin_user
module; all the files within that directory will be copied into the user's home directory, as shown in the puppet run output in the following command line:
Notice: /Stage[main]/User::Virtual/Admin_user[thomas]/File[/home/thomas/.vimrc]/ensure: defined content as '{md5}cb2af2d35b18b5ac2539057bd429d3ae' Notice: /Stage[main]/User::Virtual/Admin_user[thomas]/File[/home/thomas/.bashrc]/ensure: defined content as '{md5}033c3484e4b276e0641becc3aa268a3a'
Using the recurse
option allows us to add as many dotfiles as we wish for each user without having to modify the definition of the user.
There's more...
We could specify that the source
attribute of the home directory is a directory where users can place their own dotfiles. This way, each user could modify their own dotfiles and have them transferred to all the nodes in the network without our involvement.
See also
- The Managing users with virtual resources recipe in this chapter