DevOps:Puppet,Docker,and Kubernetes
上QQ阅读APP看书,第一时间看更新

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:

  1. Create the admin_user defined type (define admin_user) in the modules/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"]
        }
      }
    }
  2. Modify the file modules/user/manifests/sysadmins.pp as follows:
    class user::sysadmins {
      realize(Admin_user['thomas'])
    }
  3. Alter the definition of thomas in modules/user/manifests/virtual.pp as follows:
    @ssh_user { 'thomas':
      key => 'AAAAB3NzaC1yc2E...XaWM5sX0z',
      keytype => 'ssh-rsa',
      dotfiles => true
    }
  4. Create a subdirectory in the admin_user module for the file of user thomas:
    $ mkdir -p modules/admin_user/files/thomas
    
  5. 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
    
  6. Make sure your site.pp file reads as follows:
    node 'cookbook' {
      include user::virtual
      include user::sysadmins
    }
  7. 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