Tuesday, March 30, 2010

MySQL 5.1 Bug Zap: Bug day result

Today was targeted at looking through the mysql-dfsg-5.1 bugs to triage them. We ended up with all bugs having their importance set and their status set to Triaged or Incomplete.

Tomorrow will be dedicated to fixing most of them as well as some upgrade testing. I'll also have a look at the new mysql upstart job that has replaced the mysld_safe script.

Looking at the bugs today I've found a couple of bugs that look easy to fix:

  • Bug 552053:  mysqld_safe should be available in mysql-server

  • Bug 498939: mysql- packages section on synaptic


To get started grab a copy of the package branch:
bzr init-repo mysql-dfsg-5.1/
cd mysql-dfsg-5.1/
bzr branch lp:ubuntu/mysql-dfsg-5.1

Fix a bug and push the branch to launchpad:
bzr push lp:~YOUR-LOGIN/ubuntu/mysql-dfsg-5.1/zap-bug-XXXXXX

And finish up by creating a merge proposal for the Lucid package branch. I'll take a look at the list of merge proposal throughout the day and include them in the upload schedule for tomorrow.

Monday, March 29, 2010

Ubuntu Server Bug Zap: MySQL 5.1

Following up on the kvm and samba bug zap days I'm organizing a two day bug
zap around MySQL.



First phase: bug triaging


First in line is triaging all the bugs related to mysql-dfsg-5.1 package. As
of Tue Mar 30 00:23:04 UTC 2010 there are 27 bugs waiting to be looked at.


The goal is to have the importance set for all bugs and have as many bugs
status moved to either Triaged or Invalid/Won't Fix.


A few resources are available to help out:








Objective: get the list of bugs to zero.


Thursday, March 25, 2010

Using puppet in UEC/EC2: Automating the signing process

I outlined in the previous article how to setup a puppetmaster instance on UEC/EC2 and how to start instances that will automatically register with the puppetmaster. We're going to look at automating the process of signing puppet client certificate requests.



Overview


Our puppet infrastructure on the cloud can be broken down into three components:



  • The Cloud conductor responsible for starting new instances in our cloud.

  • A Puppetmaster responsible for configuring all the instances running in our cloud.

  • Instances acting as puppet clients asking to be setup correctly.


The idea is to have the Cloud conductor start instances and notify the puppetmaster that these new instances are coming up. The puppetmaster can then automatically sign their certificate requests.


We'll use S3 as the way to communicate between the Cloud conductor and the puppetmaster. The Cloud conductor will also assign a random certificate to each instance it starts.


The Cloud conductor will be located on a sysadmin workstation while the puppetmaster and instances will be running in the cloud. The bzr branch contains all the scripts necessary to setup such a solution.




The Cloud conductor: start_instance.py



  1. Get the tutorial2 bzr on the Cloud conductor (an admin workstation):



    bzr branch lp:~mathiaz/+junk/uec-ec2-puppet-config-tut2



    In the scripts/ directory start_instance.py plays the role of the Cloud conductor. It creates new instances and stores their certname in S3. The start_instance.yaml configuration file provides almost the same information as the user-data.yaml file we used in the previous article.



  2. Edit the start_instance.yaml file and update each setting:



    • Choose a unique S3 bucket name.

    • Use the private DNS hostname of the instance running the puppetmaster.

    • Add the puppetmaster ca certificate found on the puppetmaster.



  3. Make sure your AWS/UEC credentials are available in the environment. The start_instance.py uses these to access EC2 to start new instances and S3 to store the instance certificate names.



  4. Start a new instance of the Lucid Beta1 AMI:



    ./start_instance.py -c ./start_instance.yaml ami-ad09e6c4



    start_instance.py starts a new instance using the AMI specified on the command line. The instance user data holds a random UUID for the puppet client certificate name. start_instance.py also creates a new file in its S3 bucket named after the puppet client certificate name.



  5. On the puppetmater looking at the puppetmaster log you should see a certificate request show up after some time:



    Mar 19 19:09:33 ip-10-245-197-226 puppetmasterd[20273]: a83b0057-ab8d-426e-b2ab-175729742adb has a waiting certificate request







Automating the signing process on the puppetmaster


It's time to setup the puppetmaster to check if there are any certificate requests waiting and signs only the ones started by the Cloud conductor. We'll use the check_csr.py cron job that will get the list of waiting certificate requests via puppetca --list and checks whether there is a corresponding file in the S3 bucket.



  1. On the puppetmaster get the tutorial2 bzr branch:



    bzr pull --remember lp:~mathiaz/+junk/uec-ec2-config/tut2 /etc/puppet/




  2. The puppetmaster.pp manifest has been updated to setup the check_csr.py cron job to run every 2 minutes. You need to update the cron job command line in /etc/puppet/manifests/puppetmaster.pp with your own S3 bucket name.



  3. Update the puppetmaster configuration:



    sudo puppet /etc/puppet/manifests/puppetmaster.pp




  4. Watching /var/log/syslog you should see check_csr being run by cron every other minute:



    Mar 19 19:10:01 ip-10-245-197-226 CRON[21858]: (root) CMD (/usr/local/bin/check_csr --log-level=debug https://mathiaz-puppet-nodes-1.s3.amazonaws.com)



    check_csr gets the list of waiting certificate requests and checks if there is a corresponding file in its S3 bucket:



    Mar 19 19:10:03 ip-10-245-197-226 check_csr[21859]: DEBUG: List of waiting csr: a83b0057-ab8d-426e-b2ab-175729742adb
    Mar 19 19:10:03 ip-10-245-197-226 check_csr[21859]: DEBUG: Checking a83b0057-ab8d-426e-b2ab-175729742adb
    Mar 19 19:10:03 ip-10-245-197-226 check_csr[21859]: DEBUG: Checking url https://mathiaz-puppet-nodes-1.s3.amazonaws.com/a83b0057-ab8d-426e-b2ab-175729742adb



    If so it will sign the certificate request:



    Mar 19 19:10:03 ip-10-245-197-226 check_csr[21859]: INFO: Signing request: a83b0057-ab8d-426e-b2ab-175729742adb







S3 bucket ACL


For now the S3 bucket ACL is set so that anyone can get the list files available in the bucket. However only authenticated requests can create new files in the bucket. Given that the filename are just random UUID this is not a big issue.




Using SQS instead of S3


Another implementation of the same idea is to use SQS to handle the notification of the puppetmaster by the Cloud conductor about new instances. While SQS would seem to be the best tool to provide that functionality it is not available in UEC in Lucid.




Conclusion


We end up with a puppet infrastructure where legitimate instances are automatically accepted. Now that instances can easily show up and be automatically enrolled what should these be configured as? We'll dive into this issue in the next article.


Wednesday, March 24, 2010

Using puppet in UEC/EC2: puppet support in Ubuntu images

One of the focus for the Lucid release cycle in the Ubuntu Server team is to improve the integration between puppet and UEC/EC2. I'll discuss in a series of articles how to setup a puppet infrastructure to manage Ubuntu Lucid instances running on UEC/EC2. I'll focus on the bootstrapping process rather than writing puppet recipes.


Today we'll look at configuring a puppetmaster into an instance and how to start instances that will register automatically with the puppetmaster.


We'll work with the Lucid Beta1 image on EC2. All the instances started through out this article will be based on this AMI.



Puppetmaster setup


Let's start by creating a puppetmaster running on EC2. We'll setup all the puppet configuration via ssh using a bzr branch on Launchpad: lp:~mathiaz/+junk/uec-ec2-puppet-config-tut1.


Start an instance of the Lucid Beta1 AMI using an ssh key. Once it's running write down its public and private DNS addresses. The public DNS address will be used to setup the puppetmaster via ssh. The private DNS address will be used as the puppetmaster hostname given out to puppet clients.


We'll actually install the puppetmaster using puppet itself.


Log on the started instance via ssh to install and setup the puppet master:



  1. Update apt files:



    sudo apt-get update




  2. Install the puppet and bzr packages:



    sudo apt-get install puppet bzr




  3. Change the ownership of the puppet directory so that the ubuntu user can directly edit the puppet configuration files:



    sudo chown ubuntu:ubuntu /etc/puppet/




  4. Get the puppet configuration branch:



    bzr branch --use-existing-directory lp:~mathiaz/+junk/uec-ec2-puppet-config-tut1 /etc/puppet/



    Before doing the actual configuration let's have a look at the content of the /etc/puppet/ directory created from the bzr branch.


    The layout follows the recommended puppet practices. The puppet module available in the modules directory defines a puppet::master class. The class makes sure that the puppetmaster package is installed and that the puppetmaster service is running. The manifests/puppetmaster.pp file defines the default node to be configured as a puppetmaster.



  5. We'll now run the puppet client to setup the instance as a puppetmaster:



    sudo puppet /etc/puppet/manifests/puppetmaster.pp







Starting a new instance


Now that we have puppetmaster available in our cloud we'll have look at how a new instances of the Lucid Beta1 AMI can be started and automatically setup to register with the puppetmaster.


We're going to use the cloud-config puppet syntax to boot an instance and have it configure itself to connect to the puppetmaster using its user data information:



  1. On the puppetmaster instance create a user-data.yaml file to include the relevant puppetmaster configuration:



    cp /usr/share/doc/cloud-init/examples/cloud-config-puppet.txt user-data.yaml




  2. Update the server setting to point to the puppetmaster private dns hostname. I also strongly recommend to include the puppmaster ca certificate as the ca_cert setting.


    The example certname setting uses a string extrapolation to make each puppet client certificate unique: for now %i is replace by the instance Id while %f is replaced by the FQDN of the instance.


    The sample file has extensive comments about the format of the file. One of the key point is that you can set any of the puppet configuration options via the user data passed to the instance.


    Note that you can remove all the comments to make the user-data.yaml file easier to copy and paste. However don't remove the first line (#cloud-config) as this is used by the instance boot process to start the puppet installation.



  3. Launch a new instance using the content of the user-data.yaml file you've just created as the user-data option passed to the new instance.



  4. You can watch the puppetmaster log on the puppetmaster instance to see when the new instance will request a new certificate:



    tail -f /var/log/syslog




  5. After some time you should see a request coming in:



    puppetmasterd[2637]: i-fdb31b96.ip-10-195-18-227.ec2.internal has a waiting certificate request



    During the boot process of the new instance the puppet cloud-config plugin used the user-data information to automatically install the puppet package, generate the /etc/puppet/puppet.conf file and start the puppetd daemon.



  6. You can then approve the new instance:



    sudo puppetca -s i-fdb31b96.ip-10-195-18-227.ec2.internal




  7. Watching the puppetmaster log you'll see that after some time the new instance will connect and get its new manifest compiled and sent:



    puppetmasterd[2637]: Compiled catalog for i-fdb31b96.ip-10-195-18-227.ec2.internal in 0.03 seconds





In conclusion we now have an instance acting as a puppetmaster and have a single user-data configuration for the whole puppet infrastructure. That user data can be passed to new instances which will automatically register with our puppetmaster.


Even though we're able to make all our instances automatically register with our puppetmaster we still need to manually sign each request as outlined in step 6 above. We'll have a look at automating this step in the next article.