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

Pushing code around with Git

As we have already seen in the decentralized model, Git can be used to transfer files between machines using a combination of ssh and ssh keys. It can also be useful to have a Git hook do the same on each successful commit to the repository.

There exists a hook called post-commit that can be run after a successful commit to the repository. In this recipe, we'll create a hook that updates the code on our Puppet master with code from our Git repository on the Git server.

Getting ready

Follow these steps to get started:

  1. Create an ssh key that can access your Puppet user on your Puppet master and install this key into the Git user's account on git.example.com:
    [git@git ~]$ ssh-keygen -f ~/.ssh/puppet_rsa
    Generating public/private rsa key pair.
    Your identification has been saved in /home/git/.ssh/puppet_rsa.
    Your public key has been saved in /home/git/.ssh/puppet_rsa.pub.
    Copy the public key into the authorized_keys file of the puppet user on your puppetmaster
    puppet@puppet:~/.ssh$ cat puppet_rsa.pub >>authorized_keys
    
  2. Modify the Puppet account to allow the Git user to log in as follows:
    root@puppet:~# chsh puppet -s /bin/bash
    

How to do it...

Perform the following steps:

  1. Now that the Git user can log in to the Puppet master as the Puppet user, modify the Git user's ssh configuration to use the newly created ssh key by default:
    [git@git ~]$ vim .ssh/config
    Host puppet.example.com
     IdentityFile ~/.ssh/puppet_rsa
    
  2. Add the Puppet master as a remote location for the Puppet repository on the Git server with the following command:
    [git@git puppet.git]$ git remote add puppetmaster puppet@puppet.example.com:/etc/puppet/environments/puppet.git
    
  3. On the Puppet master, move the production directory out of the way and check out your Puppet repository:
    root@puppet:~# chown -R puppet:puppet /etc/puppet/environments
    root@puppet:~# sudo -iu puppet
    puppet@puppet:~$ cd /etc/puppet/environments/
    puppet@puppet:/etc/puppet/environments$ mv production production.orig
    puppet@puppet:/etc/puppet/environments$ git clone git@git.example.com:repos/puppet.git
    Cloning into 'puppet.git'...
    remote: Counting objects: 63, done.
    remote: Compressing objects: 100% (52/52), done.
    remote: Total 63 (delta 10), reused 0 (delta 0)
    Receiving objects: 100% (63/63), 9.51 KiB, done.
    Resolving deltas: 100% (10/10), done.
    
  4. Now we have a local bare repository on the Puppet server that we can push to, to remotely clone this into the production directory:
    puppet@puppet:/etc/puppet/environments$ git clone puppet.git production
    Cloning into 'production'...
    done.
    
  5. Now perform a Git push from the Git server to the Puppet master:
    [git@git ~]$ cd repos/puppet.git/
    [git@git puppet.git]$ git push puppetmaster
    Everything up-to-date
    
  6. Create a post-commit file in the hooks directory of the repository on the Git server with the following contents:
    [git@git puppet.git]$ vim hooks/post-commit
    #!/bin/sh
    git push puppetmaster
    ssh puppet@puppet.example.com "cd /etc/puppet/environments/production && git pull"
    [git@git puppet.git]$ chmod 755 hooks/post-commit
    
  7. Commit a change to the repository from your laptop and verify that the change is propagated to the Puppet master as follows:
    t@mylaptop puppet$ vim README
    t@mylaptop puppet$ git add README
    t@mylaptop puppet$ git commit -m "Adding README"
    [master 8148902] Adding README
     1 file changed, 4 deletions(-)
    t@mylaptop puppet$ git push
    X11 forwarding request failed on channel 0
    Counting objects: 5, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 371 bytes | 0 bytes/s, done.
    Total 3 (delta 1), reused 0 (delta 0)
    remote: To puppet@puppet.example.com:/etc/puppet/environments/puppet.git
    remote: 377ed44..8148902 master -> master
    remote: From /etc/puppet/environments/puppet
    remote: 377ed44..8148902 master -> origin/master
    remote: Updating 377ed44..8148902
    remote: Fast-forward
    remote: README | 4 ----
    remote: 1 file changed, 4 deletions(-)
    To git@git.example.com:repos/puppet.git
     377ed44..8148902 master -> master
    

How it works...

We created a bare repository on the Puppet master that we then use as a remote for the repository on git.example.com (remote repositories must be bare). We then clone that bare repository into the production directory. We add the bare repository on puppet.example.com as a remote to the bare repository on git.example.com. We then create a post-receive hook in the repository on git.example.com.

The hook issues a Git push to the Puppet master bare repository. We then update the production directory from the updated bare repository on the Puppet master. In the next section, we'll modify the hook to use branches.