Terminate all EC2 instances

The Amazon Elastic Compute Cloud (EC2) allows you to quickly launch virtual servers in the cloud. If you create an AMI (Amazon Machine Image), you can deploy many instances of this image, only limited by your instance limit (20 initially, but you can request more).

Amazon Management Console
Amazon Management Console

The instances can be manged through the AWS management console web-interface, for example to create multiple instances as shown above.

However, this console does not have a convenient method to terminate all the running instances – you have to terminate them one-by-one! This becomes a big problem if you, like me, are launching 1000s of instances for a few hours and then want to take them all down again. Since you are getting charged by the instance hour, you don’t want them running longer than necessary.

EC2 API tools

Fortunately, the EC2 API Tools provide an alternate interface to EC2. These tools rely on a Java runtime, and a few environment variables to install. They seem to work best with Linux, but I have not tested them on Windows myself. There are some guides available on how to install them, for example the Ubuntu EC2 Starters Guide. If you already have an AWS account, you should get them working within 10 minutes on Ubuntu.

Now that you have command-line access to managing the instances, you have much more power to do mass-management of them.

Terminating all instances

Assuming you’ve got EC2 API tools installed and working correctly above, you probably noticed a command that can help terminate the instances: ec2-terminate-instances. However, this command assumes the instance IDs that are to be terminated as parameters — there is no option to terminate all. Looking further at the tools, there is a command called ec2-describe-instances that returns the instance IDs of the running instances (among other things).

So our task is to get the running instance IDs from ec2-describe-instances and pass them as a parameter to ec2-terminate-instances. With some helper commands, this can be achieved as follows.

ec2-describe-instances | grep INSTANCE | awk '{print $2}' | xargs ec2-terminate-instances

Be careful: this will terminate all your running instances, so don’t run it if you don’t mean it! If you have a lot of instances to terminate, ec2-terminate-instances may report that reading from the network socket failed (due to a timeout). But the termination will nonetheless succeed, as you can confirm from the AWS management console.

This has saved me hours of one-by-one termination from the web interface, and I hope it can help you too.

Posted in Uncategorized | Tagged , , , | Leave a comment

OpenSSL for Windows

In earlier articles, we have looked at how to create a gcc build environment on Windows, and also how to compile binaries for Windows on Linux, using the MinGW-w64 suite to be able to support native 64-bit Windows builds.

But in order to build useful applications in these environments, we often need some common libraries. In this article, we will have a look at how to compile the OpenSSL library and make a small application that uses it. Compiled OpenSSL libraries are available for download (see the link at the bottom), in case you don’t want to do the compilation yourself.

 

Prerequisites

We will be cross-compiling from Linux. If you want to use Windows only, please consider downloading the compiled OpenSSL binaries near the bottom of the page, or adjust the paths accordingly when building the library.

I have my 64-bit Windows build environment installed in /opt/mingw64, and the cross-compiler prefix is x86_64-w64-mingw32. I will target (build binaries for) 64-bit Windows in this article. Please adjust these variables according to your own build environment. i686-w64-mingw32 is the prefix for the 32-bit Windows cross-compiler.

 

Compiling OpenSSL

  1. Follow the simple instructions on how to set up a Windows build environment on Linux. It is also possible to do this on Windows, but it is simpler and faster using Linux. Please leave a comment if you would like me to describe how to build on Windows.
  2. Grab the desired OpenSSL source tarball. Use OpenSSL version 1.0.0 or newer; OpenSSL versions older than v1.0.0 are a bit harder to build on Windows, but let me know if you want to see how to do this.  I’ll use OpenSSL version 1.0.0e in the following, but the steps should be identical for any version newer than 1.0.0.
  3. Put your tarball in a temporary directory, e.g. /tmp and unpack it:
    $ tar zxvf openssl-1.0.0e.tar.gz
  4. Run the configure script to use the 64-bit Windows compiler.
    $ cd openssl-1.0.0e
    $ CROSS_COMPILE="x86_64-w64-mingw32-" ./Configure mingw64 no-asm shared --prefix=/opt/mingw64


    Configured for mingw64.
  5. Compile. Make sure the the cross-compiler is in your path, or add it explicitly as show below.
    $ PATH=$PATH:/opt/mingw64/bin make
  6. Install it.
    $ sudo PATH=$PATH:/opt/mingw64/bin make install

We now have the OpenSSL libraries and headers for 64-bit Windows installed. Repeat the steps above with CROSS_COMPILE="i686-w64-mingw32-" and prefix /opt/mingw32 to build and install the 32-bit libraries for Windows.

 

A simple application

To confirm OpenSSL is working correctly, let’s create  a small C application that generates a SHA-256 digest of a character string. It reads a string given as the argument, generates the digest and shows the computed digest. The digest-generating code is shown below, while the complete code is available for download.

void SHA256Hash(unsigned char digest[EVP_MAX_MD_SIZE], char *stringToHash)
{
OpenSSL_add_all_digests();

const EVP_MD *md = EVP_get_digestbyname(“sha256″);

EVP_MD_CTX context;
EVP_MD_CTX_init(&context);
EVP_DigestInit_ex(&context, md, NULL);
EVP_DigestUpdate(&context, (unsigned char *)stringToHash, strlen(stringToHash));

unsigned int digestSz;
EVP_DigestFinal_ex(&context, digest, &digestSz);
EVP_MD_CTX_cleanup(&context);

EVP_cleanup();
}

  1. Save the file sha256.c in a working directory.
  2. Compile it.
    $ /opt/mingw64/bin/x86_64-w64-mingw32-gcc -I/opt/mingw64/include -L/opt/mingw64/lib -Wall sha256.c -lcrypto -o sha256.exe
  3. Check that the executable has the correct binary format (PE32+ is 64-bit).
    $ file sha256.exe
    sha256.exe: PE32+ executable for MS Windows (console) Mono/.Net assembly
  4. Copy our new program to a 64-bit Windows machine, and run it in the Windows Command Prompt.
    > sha256.exe 12345

The last step should generate the following dialog box, which contains the SHA-256 digest of the string “12345″.

sha256.exe sample run

 

OpenSSL Windows binaries

In case you don’t want to compile the OpenSSL library yourself, I have compiled version 1.0.0e and made it available for download below.

Just unpack each tarball to your respective MinGW-w64 installation directory. They should work both if you are running the gcc compiler on Windows, as well as cross-compiling for Windows like we have done above.

Please leave a comment if you found this interesting or have suggestions for improvements!

Posted in GCC Windows | Tagged , , , , | 4 Comments

Excluding files in CFEngine copies

I frequently encounter people trying to do a recursive copy with CFEngine, but want to ignore some subdirectories or files.

A typical example is that /var/cfengine/masterfiles is under version control on the policy server, and a lot of meta-data is copied down to the clients during policy updates. Fortunately, it is very easy to ignore certain subdirectories during copies with CFEngine. Consider the following example.

bundle agent test_copy
{
files:

“/tmp/dest”
copy_from => local_cp(“/tmp/src”),
depth_search => recurse_ignore(“inf”, “.svn”);
}

This will copy everything recursively, except the Subversion meta-directories. A self-contained example is available for download.

A sample run is shown below.

$ find /tmp/src/
/tmp/src/
/tmp/src/subdir
/tmp/src/subdir/file3
/tmp/src/subdir/.svn
/tmp/src/file2
/tmp/src/.svn
/tmp/src/file1

$ cf-agent -KIf ./nosvn.cf

-> Copying from localhost:/tmp/src/subdir/file3
-> Copying from localhost:/tmp/src/file2
-> Copying from localhost:/tmp/src/file1

$ find /tmp/dest/
/tmp/dest/
/tmp/dest/subdir
/tmp/dest/subdir/file3
/tmp/dest/file2
/tmp/dest/file1

Of course, this can be integrated into your update.cf in order to avoid getting those pesky .svn directories everywhere.

Happy hacking!

Posted in CFEngine | Tagged , , , , , | Leave a comment

CFEngine 3.2.0 extended change log

Highlights

Finally, we are ready for the CFEngine 3.2.0 release and we’ll have a look at the major changes. In 3.2.0, an exciting CFEngine Nova feature is brought into the community edition, and a set of out-of-the-box policies are released to standardise and simplify CFEngine installations. This will make bootstrapping new CFEngine’d hosts a breeze. Also, as usual, a bunch of new features and bug fixes also made it into the release.

We will cover the following items this time.

  • The brand new cf-agent bootstrap feature
  • More convenient use of ifvarclass
  • Package-promises improvements
  • Editors to support the CFEngine language

 

Bootstrapping

If you look at cf-agent --help, you will notice that a new option, --boostrap (-B), has been added to the community edition. Also note the --policy-server (-s) option – they go hand-in-hand. These options, when combined, allows you to specify the IP address of a policy server on the command line. The IP address will then be used when the bootstrapped node pulls for policy updates. So this is easier than the conventional way  to put a new node under management; manually deploying a custom policy and running cf-agent.

So say we have a policy server running at 192.168.1.1. On a fresh client, we run /var/cfengine/bin/cf-agent -Bs 192.168.1.1. Let’s break cf-agent‘s actions down into a series of steps, to see what is actually happening.

  1. Write the address from the --policy-server (-s) option to /var/cfengine/policy_server.dat
  2. Check if /var/cfengine/inputs/failsafe.cf exists, run it and exit if it does
  3. Write an embedded failsafe policy to /var/cfengine/inputs/failsafe.cf (we’ll explore this in a moment)
  4. Run the embedded failsafe policy
  5. The embedded failsafe pulls down a new policy from 192.168.1.1:/var/cfengine/masterfiles and starts cf-execd
  6. Bootstrapping is now finished and the new node is under CFEngine management!

This means that all you need to have is a policy server sharing a policy under /var/cfengine/masterfiles and then run one command at the clients to put them under management!

 

Embedded policy

So how does this embedded policy look? It is actually a very simple policy mainly consisting of a  file-copy promise and a promise to start cf-execd. You can actually see the embedded failsafe as failsafe.cf.cfsaved after a host has been successfully bootstrapped.

Since it is embedded in the CFEngine binaries, it is not very pretty with respect to indentation and Knowledge Management features, but it does the job. For your convenience and curiosity needs, I have uploaded the CFEngine embedded failsafe.cf. Also note that it cannot be changed since it is embedded (and this is why it is so simple), but the policy that gets pulled down is of course entirely up to you.

 

Bootstrapping the policy server

Until now, we have assumed that the policy server is already set up for us in advance. But, as a matter of fact, bootstrapping the policy server is almost exactly as easy. It will just use its own IP address, thus all hosts will use the exact same bootstrap command. However, /var/cfengine/masterfiles should be populated with the desired policy before bootstrapping it (otherwise, it has no policy to grab!). But CFEngine 3.2.0 also gives you a head start with the bundled policy.

 

The bundled policy

So what do you put in /var/cfengine/masterfiles on the policy server prior to doing any bootstrapping? In order to get policy updates, it should contain a promise to check for updates from the policy server, and the policy server needs to grant access to the directory with the policy updates (/var/cfengine/masterfiles by convention). But there are also a few other items users always want, like a promises.cf policy with the bundlesequence and inputs. Also, you might want to configure cf-execd‘s email functionality. And then there’s the cf-serverd access configuraion..

CFEngine 3.2.0 is distributed with a skeleton policy that allows to change these normal parameters without needing to write your own version of everything — just plug in the data in the right place. If grab a tarball, you will find the bundled policy in the masterfiles subdirectory after you unpack it. Otherwise, you can always get it from the CFEngine core subversion repository.

Before starting using it, you can look through promises.cf to adjust it to your needs. In particular, have a look at the bundle common def. The acl slist there determines the access rules for cf-serverd.

 

What about trust?

As we know, simplicity and security are often conflicting. In order to make our easy bootstrapping work, two kinds of trust are assumed.

  • Bootstrapping host trusts the policy server’s public key and the policy it holds
  • Policy server trust the new client’s public key and gives access to the policy

The first item is implicit from running the bootstrap command. We are essentially asking the client go to the given IP address for policy updates. If we do not want to assume this kind of trust for some reason, we have to revert to the old way of copying the policy and/or the policy-server’s public key manually. An automatic bootstrap procedure will not be useful to us in this case.

However, we can do something with the second item. First off, we can allow only certain time windows of client trust in the server. We can also limit the (ranges of) IP-addresses we accept. By default we allow the Class B network to access the policy server. See the acl slist in bundle common def in promises.cf to configure it.

The CFEngine 3 reference manual has some more information on key exchange and time windows.

 

 Improvements for ifvarclass

As you perhaps know, ifvarclass can be used to transform a variable into a class expression. With CFEngine 3.2.0 you can also make convenient expressions and tests directly in the ifvarclass expression using the new special functions and(), not(), or() and concat(). This can save you class definitions that you would use only once.

For example, you might want to copy down some configuration only to hosts having a certain binary. This can now be done easily with one promise, as shown below.

files:
“/etc/testservice”,
copy_from  => remote_cp(“/var/cfengine/sitefiles/etc/testservice”, “123.123.123.123″),
ifvarclass => or( fileexists(“/bin/testservice”) );

Also note that you can wrap any number of function calls, as shown by the dummy-example below.

reports:
linux::
“/tmp does exist”
ifvarclass => not( not(fileexists(“/tmp”)));

If you would like to test the two examples on your own, you can download them here.

 

A pack of bugfixes

As usual, the CFEngine developers have been working hard to check and fix bugs reported by the community. In particular, the packages-promises have gotten a facelift.

The addupdate package policy is now fully functioning when using a repository-enabled manager such as yum or aptitude. Previously this policy was only supported when specifying package_file_repositories combined with non-repository package commands such as rpm or dpkg. For example, the following promise will make sure Apache is installed with a version at least 2.2. If Apache 2.2 or newer is already installed, no action is taken.

packages:

“apache2″
package_method => generic,
package_version => “2.2.00″,
package_select => “>=”,
package_policy => “addupdate”;

Also, for efficiency reasons, CFEngine caches the list of installed packages and their version (the output from package_list_command) in WORKDIR/state/software_packages.csv. A problem encountered by some users was that CFEngine did not actually update this cache often enough, so CFEngine might actually act on stale information.  To alleviate this problem, package cache invalidation is introduced in this release. Also note that you can define the cache maximum age with the package_list_update_ifelapsed attribute. There were also a few other package-related issues that were addressed in the 3.2.0 release.

For a complete list of the reported issues/feature requests that was resolved in CFEngine 3.2.0, have a look at the Change Log at the bug tracker.

Lastly, some very good news for Emacs users! Ted Zlatanov, an active member of the CFEngine Community, has created and committed cfengine3-mode to Emacs sources. This has also been added to contrib in the CFEngine core repository.

If you are a vim-er, don’t despair! Have a look at the vim syntax highlighting script and the abbreviations and help files. Both are contributed by Neil Watson, also an important member of the CFEngine community.

 

Get it!

As usual, CFEngine 3.2.0 is provided not only as a source tarball, but also prepackaged for the most popular Linux distributions by logging into the Engine Room (free registration required). Users of the following distributions enjoy free packages, both 32- and 64-bit versions.

  • Debian 5 and 6
  • Fedora 14 and 15
  • Red Hat Enterprise Linux 4, 5 and 6
  • Suse 9, 10 and 11
  • Ubuntu 8, 9, 10 and 11

Note that most distributions also maintain a CFEngine 3 package, but this is usually older and may not be built in a uniform way.

Please do not hesitate to leave a comment if you found this useful, have suggestions for improvements, or would like to see other CFEngine-related get covered.

Go get those hosts CFEngined!

Posted in CFEngine | Tagged , , , , , , , , , , , , , , , , , | 4 Comments

Windows media in Ubuntu and Firefox

Streaming Windows media files (WMV and WMA) from Firefox in Ubuntu has been a known problem for a long time. At the same time, a lot of web media content is encoded in these formats, making it a real pain that they are not working.

There are various plugins that claim to work, but I have had some bad experiences with some not working and others creating lags and stop working after a few minutes. Now, let’s put an end to this and install a plugin that just works flawlessly.

You just need to install one package: gecko-mediaplayer. As usual, you can use the Ubuntu graphical tools, or do it on the command line:

sudo apt-get install gecko-mediaplayer

Now restart Firefox, and you should be able to play any Windows media files directly from your browser. Simple as that!

I have tested it in Ubuntu 10.4 (Lucid), but it should work on all recent versions of Ubuntu.

Posted in Software configuration | Tagged , , , , , , , | Leave a comment

cf-execd schedule

A common question from Cfengine users is how to configure how often cf-agent is being run. Setting a simple time-based schedule is very easy, but there are a few additional steps you might want to consider to ensure optimal scalability.

It is cf-execd that schedules the execution of cf-agent. In Cfengine 3, the default schedule will ensure that cf-agent is run every five minutes. To adjust this, all we need to do is add the control body for cf-execd and set the schedule body-part to our liking. For example, below we set cf-agent to run every fifteen minutes.

body executor control
{
schedule => { “Min00″, “Min15″, “Min30″, “Min45″ };
}

Splaytime

If you have a reasonable-sized environment, you might also want to have a look at the splaytime body-part. This delays the execution of cf-agent by a random amount of seconds within a bound. The purpose of this is to distribute the load on network resources evenly — to avoid that all your agents start pulling from the network at the exact same second. So, instead of saying that we want to run cf-agent the exact quarters of an hour, we can instead say we want to run it four times an hour and make our configuration more scalable as follows.

body executor control
{
schedule => { “Min00″, “Min15″, “Min30″, “Min45″ };
splaytime => “15″;
}

There are some notes on the splaytime setting in the Cfengine 3 reference manual.

Advanced schedules

Perhaps you have some specific time slot during the day you want your systems to spend all their resources on a specific task. Even though Cfengine 3 is the most lightweight configuration management system in existence, there might still be some shell commands or network transfers that are executed as part of your Cfengine policy. So let us adjust our schedule to run cf-agent every fifteen minutes, except from 12 PM to 6 PM.

body executor control
{
schedule => { “Min00.(Morning|Evening|Night)”, “Min15.(Morning|Evening|Night)”,
“Min30.(Morning|Evening|Night)”, “Min45.(Morning|Evening|Night)” };
}

As you might have noticed, each list element in schedule is actually a class expression, which makes it very flexible. Normally though, time-based class-expressions are used. Note the four hardclasses (automatically defined) that split the day into six-hour slots:

  • 00 AM – 06 AM : Night
  • 06 AM – 12 PM : Morning
  • 12 PM – 06 PM : Afternoon
  • 06 PM – 12 AM : Evening

We can create arbitrary complex class expressions to create any schedule that fits our needs (perhaps use one of Monday, Tuesday, etc.). Remember that you can always run cf-promises -v to see all the classes that are currently defined on a given host, which gives you a hint of what you have at your disposal.

Internal workings

We finish off with a short note on the steps cf-execd actually takes to do the scheduling. cf-execd sleeps one minute at the time. When it wakes up, it checks if any of the class-expressions in schedule evaluates to true. If so, it gets ready to run cf-agent (or the command in exec_command). But first, it checks the splaytime body-part, and delays the execution an arbitrary amount of seconds (based on a hash of the host’s name) according to this setting.

If you want to test your new schedule, try running cf-execd in verbose mode (cf-execd -v). You would see something similar to the following once a class-expression in your schedule evaluates to true.

cf3> Reference time set to Sun May 29 21:10:13 2011
cf3> Checking schedule Min00…
cf3> Checking schedule Min05…
cf3> Checking schedule Min10…
cf3> Waking up the agent at Sun May 29 21:10:13 2011
~ Min10
cf3> Sleeping for splaytime 17 seconds
cf3> Sleeping…
cf3> ——————————————————————
cf3>   LocalExec(scheduled) at Sun May 29 21:10:30 2011
cf3> ——————————————————————
cf3>  -> Command => “/var/cfengine/bin/cf-twin” -f failsafe.cf && “/var/cfengine/bin/cf-agent”
cf3>  -> Command is executing…

That’s it! You are now a Cfengine 3 scheduling expert!

Please leave a comment if you have any questions, corrections or ideas of other topics that should be covered.

Posted in CFEngine | Tagged , , , , , , , , | 1 Comment

Cfengine 3.1.4 and 3.1.3 extended change log

Highlights

First of all, thanks for the good feedback from the previous extended change log! It seems like this is something the Cfengine community is interested in, so I will continue the series. This time we cover the changes in both Cfengine 3.1.3 and 3.1.4, since they were released quite close to each other (January 22nd and January 31st). Some rather annoying bugs were discovered by the Cfengine community in 3.1.3, so the 3.1.4 release was brought forward.

The new releases bring the following advancements.

  • major memory leaks removed – daemons now show no growth
  • allowing definition of good and bad return codes for commands
  • lock database purging
  • 30 second recv() timeout on Linux
  • two race conditions (causing segmentation faults) in cf-serverd fixed
  • Solaris global zone process list fixed
  • new function ip2host()
  • package architectures handled correctly

There are some more details in the ChangeLog-file, and at the bug tracker.

Leak no more

Memory leaks occur when a program allocates memory, but does not release it again later. This is not always a problem, because operating systems always reclaim all memory when a process terminates. Releasing memory just before termination thus only results in unnecessary resource consumption (indeed the GNU C library does not by default release memory on process termination).

However, in daemons and long running programs, repeated memory leaks is clearly an issue. Memory leaks usually manifest themselves in an ever-increasing size of the process’ virtual memory. Unfortunately, such bugs are extremely hard to track down, because it is not always clear where the leak happens and when a certain memory segment should be released (if it is released to soon, the process will crash). In Cfengine, this is further complicated by the fact that certain policies may cause more severe leaks than others because different execution paths are followed when running them.

But since multiple reports of severe leaks started to come from the Cfengine community, a lot of effort was put into debugging it (see the report on the bug tracker). It took one month (!) of iteration before all the leaks were tracked down, even with much help with testing from the community – especially Jonathan. On the positive side, these leaks (or anything like them) are very unlikely to reappear. But don’t hesitate to create a report if you think you have found a leak some day.

The main sources of leaks turned out to be an error when releasing lists (struct Rlist). Also, when re-reading the policy, parts of the old one was never released. Since only cf-monitord and cf-serverd re-read the policy, they were the most affected components.

Jonathan from the Cfengine community provided a policy that caused a lot of leakage, and by using this, debugging was easier. But we can also use it to illustrate the difference between Cfengine 3.1.2 and Cfengine 3.1.4. The graphs below show the segment size (RSS) of the three Cfengine daemons, measured over one day. They pretty much speak for themselves. Thanks to community members helping to fix this issue!

Cfengine 3.1.2 daemon leakage

 

Cfengine 3.1.4 daemon memory usage
Cfengine 3.1.4 daemon memory usage

download all graphs (including virtual sizes)

Command return codes

As of Cfengine 3.1.0, promises of type commands were flagged as repaired if they returned zero, not kept otherwise. This allowed to define a class in either case and run follow-up promises. In Cfengine 3.1.4, a much more flexible framework has been introduced. In addition, commands in packages-promises and transformer in files-promises has been incorporated. Now, Cfengine users can specify a list of return codes for which one of these promises should be kept, repaired and not kept. It’s often easier to understand by example, so let’s do just that. First let’s start with a simple shell script.

#!/bin/sh
# saved to /tmp/retarg
exit $1

So this script just exits with the code given as the first parameter, which must be from 0 to 255 on Unix. We will use this little script to demonstrate the new return code functionality in the following snippet.

bundle agent commands_retcode
{
commands:
  "/tmp/retarg 0",
  classes => define_retcodes;
}
###
body classes define_retcodes
{
kept_returncodes => { "5" };
repaired_returncodes => { "0" };
failed_returncodes => { "1", "2", "3", "4" };
promise_kept => { "waskept" };
promise_repaired => { "wasrepaired" };
repair_failed => { "wasfailed" };
}

By running /tmp/retarg with arguments 0, 1 and 5, we see that the classes wasrepaired, wasfailed and waskept gets defined, respectively. We may also use overlapping return codes in the *_returncodes lists, which could result in the promise getting multiple statuses (e.g. both repaired and failed). This might seem a bit strange, but gives the user total control. If the return code is not found in any of the lists, the promise does not get a status at all. When none of the lists are defined, Cfengine falls back to the default of zero being promise repaired, and anything else promise failed.

This flexibility is also allowed in packages-promises, as demonstrated in the following.

bundle agent packages_retcode
{
packages:
  "aatv"
  package_policy => "add",
  package_method => generic,
  classes => define_retcodes;
}

Lastly, in files-promises, the return value of the transformer command is considered, as shown below.

bundle agent transformer_retcode
{
files:
  "/tmp"
  classes => define_retcodes,
  transformer => "/tmp/retarg 0";
}

A complete self-containing policy demonstrating the new framework in all the three above promise types is available for download here. In the reference manual, this is documented as part of the classes body.

Lock purging

As you probably know, Cfengine has a concept of locks.  Locks ensure that promises are not checked too often, but also that repairing each promise does not take too long. These parameters are configurable through ifelapsed and expireafter policy setting, available at a global and promise level. Since information about these locks needs to persist between runs of cf-agent, Cfengine keeps track of these locks in a database stored in /var/cfengine/state/cf_lock.* (suffix depends on the dbm used). A hash of the promise attributes is used as keys for this database.

The problem with this is that sometimes the attributes change even though the promise really is the same. For example, if you have a commands-promiser “/bin/echo $(date)”, the promiser would seem to change each time cf-agent runs. As another example, you may want to delete files in /tmp that are more than 3 days old. Many of these files would never reappear (but some might), so keeping an entry for all of them in the lock database just increases its size for no reason. This causes the lock database to grow indefinitely, but very slowly (if you are still not on Cfengine 3.1.4, check the size of yours). Trying to make some heuristic checks for if a given promise should be in the lock database or not would surely end in unexpected behaviour for some of the huge user base of Cfengine. A less risky approach that was introduced in Cfengine 3.1.4, is to automatically purge old locks.cf-agent will run a lock-purging algorithm every month, deleting locks that are more than one month old. This should take care of the (slow) growth of the lock database, while still not risking unexpected behaviour.

Other improvements

A 30 second timeout on the recv() system call is introduced on Linux hosts. This means that any connection that waits to receive data will time out if no data is received within 30 seconds. The reason to introduce this is to avoid a remote system to cause components of Cfengine to hang indefinitely. A remote system may become unresponsive for a number of reasons, including network unreliability, high load, deadlocks (e.g. when trying to open a database that was uncleanly shut down), kernel or driver bugs, most of which are outside of Cfengine’s control. Introducing a mechanism to back-off after a certain time has elapsed is the only way we can protect ourself from all these scenarios, but still allows for self-healing when Cfengine retries the operation later. As the details of the socket API is different amongst OSes, Linux is the first one to get this support.

A new function ip2host() that does reverse dns lookups is introduced. Note that DNS is often quite unreliable, and can thus cause cf-agent to hang for a while while doing the lookup.

bundle agent reverse_lookup
{
vars:
 "local4" string => ip2host("127.0.0.1");
 "local6" string => ip2host("::1");

reports:
cfengine_3::
  "local4 is $(local4)";
  "local6 is $(local6)";
}

Cfengine community members discovered that Cfengine sometimes ignored the architecture when considering packages-promises. This could cause Cfengine to believe that a given package was installed for all architectures, even though it was installed only for one. With Cfengine 3.1.4, this is handled correctly.

Two important issues casing segmentation faults in cf-serverd have been fixed. They were caused by race conditions in cf-serverd and were thus appearing only on busy servers. On Solaris global zones, Cfengine can now distinguish processes based on the zone they run in (previously a Nova-feature). This means that a process restart promise in the global zone will not kill processes in other zones. However, a bug was causing this not to function properly, so indeed processes in all zones were killed. This is all resolved in Cfengine 3.1.4.

Get it!

As usual, Cfengine 3.1.4 is provided not only as a source tarball, but also prepackaged for the most popular Linux distributions by logging into the Engine Room (free registration required). Users of the following distributions enjoy free packages, both 32- and 64-bit versions.

  • CentOS 5
  • Debian 4, 5 and 6
  • Fedora 14
  • Red Hat Enterprise Linux 3, 4, 5 and 6
  • Suse 9, 10 and 11
  • Ubuntu 8, 9 and 10

Note that most distributions also maintain a Cfengine 3 package, but this is usually older and may not be built in a uniform way.

The feedback from last post ensured that self-containing policies are available for download in companion with the snippets. Please do not hesitate to leave a comment if you found this useful, or have more suggestions for improvements.

Enjoy!

Posted in CFEngine | Tagged , , , , , , , , , , , , , , , , | 5 Comments

Cfengine 3.1.2 extended change log

Highlights

Cfengine 3.1.2 was released December 9th, 2010. The theme of the release is major efficiency improvements, but some bug fixes are also included. Looking in the ChangeLog-file in the root of the tarball, we find the following goodies.

  • cf-promises is almost gone
  • potential for much less network load when checking for policy updates
  • ps-command runs less frequently
  • faster access to classes

We will have a look at how to take advantage of the new features in the following.

Caching policy checks

The biggest improvements in version 3.1.2 comes from caching the outcome of cf-promises runs. The main task of cf-promises is to verify that the syntax of the policy is correct (but it also does more advanced analysis). The other components of Cfengine reading the policy (e.g. cf-agent, cf-execd, cf-serverd, etc.) will require verification from cf-promises before even touching the policy themselves. In the default schedule of cf-execd, cf-agent runs every five minutes. This means cf-promises is run at least every five minutes as well.

The amount of time it takes to run cf-promises depends on a number of factors, but perhaps most importantly on the size and complexity of the checked policy. My workstation, using a fairly small policy, seems to spend a bit less than one second on running cf-promises.

root@host:# time cf-promises
real    0m0.730s

Using an enterprise-size policy, this check will probably take multiple seconds to complete. Using the default schedule for cf-agent, this means about 30 seconds of server time per hour per server. Now, if we assume 1000 servers in the organisation, we see that a total of more than 8 hours of precious server time is getting lost just to this simple thing every hour. Even though Cfengine is the most efficient configuration management solution on the planet, there seems to be room for improvement here.

How often does the configuration management policy of an organisation change? Hopefully not every day. Perhaps every week, or month? Assuming once a week, it means that cf-promises is run against the same configuration 12*24*7 = 2016 times a row! How about reducing this to once?

This is exactly what Cfengine 3.1.2 brings, simply by touching a file WORKDIR/masterfiles/cf_promises_validated. This file is created by cf-agent or any other Cfengine component after it has successfully verified the policy with cf-promises. Also, before running cf-promises, the components check if any file either

is newer than the file cf_promises_validated (based on modification time). If not, the run of cf-promises is skipped, and 8 hours of server time is reclaimed every hour!

Reducing network load

The performance improvement by caching the outcome of runs of cf-promises is done automatically by Cfengine, without any need of policy change. However, in the most common architecture of Cfengine, there is still much to be gained by doing a tiny modification to the policy. We assume the hosts pull policy updates from the WORKDIR/masterfiles directory on distribution server(s), as seen in the picture (shamelessly copied from the Cfengine community site).

The trick is to try to copy our new cf_promises_validated file (based on modification time) before trying to copy anything from the remote masterfiles directory itself. Note that it resides in masterfiles on the distribution server(s), so the access policy should need only minor modifications, if any. The end hosts check if the file got copied using if-repaired classes, and only copy the rest of masterfiles if so. The important thing to note here, is that the distribution servers must also run the policy, i.e. copy from their WORKDIR/masterfiles to WORKDIR/inputs locally and run cf-agent regularly in order to update cf_promises_validated if anything changed in WORKDIR/masterfiles to signal the end hosts of the change. This is however the normal way to do it. The following policy snippet demonstrates the more efficient copy.

# Assumptions:
# *) the class “am_distribution_server” is set on distribution servers
# *) the string variable “distribution_server” contains the address of the distribution server

files:

!am_distribution_server::
“/var/cfengine/inputs/cf_promises_validated”
comment => “Check whether a validation stamp is available for a new policy update”,
copy_from => u_remote_cp(“/var/cfengine/masterfiles/cf_promises_validated”,”$(distribution_server)”),
classes => u_if_repaired(“validated_updates_ready”);

am_distribution_server|validated_updates_ready::
# distribution server should always put masterfiles in inputs in order to check new policy

“/var/cfengine/inputs”
comment => “Copy policy updates from master source on distribution server if a new validation was acquired”,
copy_from => u_remote_cp(“/var/cfengine/masterfiles”,”$(distribution_server)”),
depth_search => u_recurse(“inf”);

download above policy

The bodies used are found in the Cfengine Open-Promise Body Library, but they are prefixed by “u_” to make the update-policy (usually part of failsafe.cf) self-containing.

Using this method, we reduce the (possible recursive) copy of the masterfiles directory containing tens or hundreds of files to one file. Reclaim those bytes!

Internal optimisations

As you might know, Cfengine relies on the ps command in order to acquire information about the running processes. Process information interfaces are not portable across Unices, so the ps command was deemed the only viable interface. Process information is required for example when making promises to start a process if it is not running, like the following.

processes:
“httpd”
restart_class => “start_apache”;

“mysql”
restart_class => “start_mysql”;

commands:
start_apache::
“/etc/init.d/apache2 restart”;

start_mysql::
“/etc/init.d/mysql restart”;

download above policy

Previously, these processes-promises would result in two executions of ps. However, running commands has significant overhead, and should thus be done only when strictly necessary. Cfengine 3.1.2 caches the output of a ps execution and reuses it within the same bundle, so ps will only run once in Cfengine 3.1.2 using the above snippet. The reason for not using a global cache for the whole run of cf-agent is to try to avoid staleness, as process information may change quite frequently.

Another internal optimisation introduced is to index class access though a simple hash table. The hash function used is simply to pick the first character of the class name (so “aix” hashes to 0, “linux” hashes to 11, etc.). Because classes seem to be distributed quite well alphabetically, this should be quite efficient. There is a trade-off between the computational burden of the hash function and the quality of the probability distribution it produces. This hash function is very fast, and should have an decent distribution on classes. As a flat list of classes was used previously, the optimisation should have significant effect on all access to classes, including class evaluation, definition, and reporting.

Get it!

As usual, Cfengine 3.1.2 is provided not only as a source tarball, but also prepackaged for the most popular Linux distributions by logging into the Engine Room (free registration required). Users of the following distributions enjoy free packages, both 32- and 64-bit versions.

  • CentOS 5
  • Debian 5 and 6
  • Fedora 14
  • Red Hat Enterprise Linux 3, 4, 5 and 6
  • Suse 9, 10 and 11
  • Ubuntu 8, 9 and 10

Note that most distributions also maintain a Cfengine 3 package, but this is usually older and may not be built in a uniform way.

Please leave a comment if you found this useful, or have suggestions for improvements.

Enjoy!

Posted in CFEngine | Tagged , , , , , , , , , , , , , , , , , | 6 Comments

Amarok mp3, wma and flac codecs

Amarok LogoAmarok is an innovative and configurable music player running on top of the K Desktop Environment (KDE) libraries, making it available for both Linux and Windows.

Unfortunately, non-free codecs such as mp3 and wma are not included in the default installation due to licensing restrictions. Additionally, the flac playback is not always working properly — songs may lag in the beginning, and 24-bit flac is not working at all — the playback is extremely noisy and crackling. However, these issues are not caused by Amarok itself, but rather xine-lib, the default back-end to the KDE multimedia framework Phonon.

We will install the GStreamer back-end with the necessary plugins and configure Amarok to use it instead of xine-lib to solve our issues. The generic instructions should apply to all Amarok 2 installations, and they have been tested on Ubuntu 10.4 LTS. In the end we will cover some additional tips to make Amarok really shine.

Amarok with GStreamer back-end

  1. Install. We need to install a few packages. On Ubuntu, run the following command in a terminal.

    sudo apt-get install amarok phonon-backend-gstreamer gstreamer0.10-plugins-ugly

  2. Set up. Open Amarok and go to Settings-> Configure Amarok->Playback->Configure Phonon->Backend. Mark GStreamer and click Prefer until it is at the top, followed by OK. Restart Amarok.
    Phonon GStreamer Backend
  3. Play!

Amarok tips

  • No Local Collection.
    On Ubuntu 10.4, the Local Collection in AmAmarok - No Local Collectionarok 2 may show up empty even though local music is indeed available. This is a bug in Ubuntu yet to be fixed. A workaround is to install the package “mysql-server-core-5.1″ (e.g. run “sudo apt-get install mysql-server-core-5.1″ from a terminal), and restart Amarok, and the local collection will be displayed correctly.
  • Audio Device Not Working.
    If you get a message from Phonon when starting Amarok, Phonon Audio Warning when Starting Amaroksaying that the audio playback device is not working (showed to the left), just use the default one. Go to Settings-> Configure Amarok->Playback->Configure Phonon -> Device Preference -> Audio Output -> Music. Mark “default” and click Prefer until it reaches the top, followed by OK, and the message will go away.
  • Keyboard shortcuts. Having keyboard shortcuts to the mostly used actions is very useful. Next song, previous song, play/pause are nice to have shortcuts for. To set it up, go to Settings -> Configure Shortcuts in Amarok. Search for “next”, click on the “Global” cell, then “Custom” and type in the key combination of your liking (I use Win+B) — see the screenshot below. Global means that the combination will work even when Amarok is running in the background. Follow the same recipe for any action you want a shortcut to.
  • Which file type? If Amarok refuses to play some file, you can use the Unix “file” command to find out the exact type of that file. For example, “file audio.flac” will show if “audio.flac” is a 16- or 24-bit flac file.

    $ file audio.flac
    audio.flac: FLAC audio bitstream data, 24 bit, stereo, 48 kHz, 13914720 samples

  • Internet Services. Additional features may easily be added to Amarok by enabling internet services. Go to Settings -> Configure Amarok -> Internet Services to see them. In particular, last.fm is a handy service which recommends new music to you. The recommendations are based on the songs you play and the collection of other people playing the same songs.

Happy playing with Amarok!

Posted in Software configuration | Tagged , , , , , , , , , , , , , , , , | 3 Comments

Compile for Windows on Linux

Introduction

In an earlier post, we saw how to obtain gcc on windows, using the MinGW-w64 suite. However, users familiar to gcc are often using one of the operating systems of the Unix family, such as Linux. As amazing as it may first seem, the MinGW-w64 project allows users to compile native Windows binaries on Linux. This concept of targeting a different platform than the compiler is running on is however not new, and is known as cross-compilation.

Cross-compiling Windows binaries on Linux may have many benefits to it.

  • Increased compilation speed. Linux is generally faster than Windows, especially on process management. Compiling larger projects often involves starting processes to e.g. search through and modify text files, check for headers and run the compiler binaries themselves.  Also, Linux does not need anti-virus scanners to intervene the operations of the compilation process.
  • Reduced operating system complexity. On cross-platform projects that are also built on Linux, we can get one less operating system to maintain.
  • Access to Unix build tools. Build tools such as make, autoconf, automake and Unix utilities as grep, sed, and cat, to mention a few, become available for use in Windows builds as well. Even though projects such as MSYS port a few of these utilities to Windows, the performance is generally lower, and the versions are older and less supported than the native Unix counterparts. Also, if you already have a build environment set up under Linux, you don’t have to set it up again on Windows, but just use the existing one.
  • Lower license costs. As we know, Windows costs in terms of license fees. Building on Linux, developers do not need to have  a Windows installation on their machines, but maybe just a central Windows installation for testing purposes.

How It Works

On a Linux build environment, a gcc that compiles native binaries is usually installed in “/usr/bin”. Native headers and libraries are in turn found in “/usr/include” and “/usr/lib”, respectively. We can see that all these directories are rooted in “/usr”.

Any number of cross-compiler environments can be installed on the same system, as long as they are rooted in different directories. In our example, we will use “/opt/mingw32″ and “/opt/mingw64″ as root directories for the new build environments. Now, we would perhaps expect to find “/opt/mingw32/bin/gcc” and “/opt/mingw64/bin/gcc”, but we instead see “/opt/mingw32/bin/i686-w64-mingw32-gcc” and “/opt/mingw64/bin/x86_64-w64-mingw32-gcc”. The reason for this is that we  (and configure scripts) should be able to pick the “right” gcc, even if  we have multiple compilers in the PATH environment variable. If they were all named gcc, cross-compiling would easily become messy.

Cross-World Hello

  1. Go to the MinGW-w64 download page. We need two toolchains – one for targeting win32 and another for targeting win64. New packages are frequently uploaded, but we just pick the newest personal  build (I had some bad experiences with the automated builds). Open “Toolchains targetting Win32″ and “Toolchains targetting Win64″, followed by “Personal Builds”. At the time of writing, we can open for example “sezero_20110510″, and pick “mingw-w32-bin_x86_64-linux_20110510_sezero.tar.gz” and “mingw-w64-bin_x86_64-linux_20110510_sezero.tar.gz” to compile from a 64-bit Linux distribution. There are some notes on the package naming convention below to help you pick the right one.
  2. Unpack the first archive to /opt/mingw32 and the second to /opt/mingw64.
  3. In a text editor (e.g. gedit or nano), paste in the little greeting-code and save it to /tmp/hello.c

    #include <stdio.h>

    int main()
    {
    printf(“Hello World!\n”);
    return 0;
    }

  4. Compile it for both 32- and 64-bit Windows with the following commands.
    /opt/mingw32/bin/i686-w64-mingw32-gcc /tmp/hello.c -o /tmp/hello-w32.exe
    /opt/mingw64/bin/x86_64-w64-mingw32-gcc /tmp/hello.c -o /tmp/hello-w64.exe
  5. Run “hello-w32.exe” on 32-bit Windows, and “hello-w64.exe” on 64-bit Windows.

 

In order to build useful applications, it is convenient to use existing libraries such as the OpenSSL library on Windows.

Package Naming Conventions

As we saw on the MinGW-w64 download page, there are a lot of available packages with only subtle and perhaps confusing name differences. The automatically built packages have the following generic naming pattern.

mingw-TARGET-bin_HOST_DATE.PKG

  • TARGET states which platform we want the compiled binaries to run, and can be either “w32″ (32-bit Windows) or “w64″ (64-bit Windows).
  • HOST gives the host system, that is, the system on which the compiler binaries themselves are run. Thus, we are cross-compiling if HOST is different from TARGET. If we have a Intel 32-bit Linux distribution, we can pick a HOST value of “i686-linux”, from a 64-bit Linux host we would choose “x86_64-linux”, and from 32-bit Windows we can choose “i686-mingw”.
  • DATE is the date, in the form YYYYMMDD, when the automatic build was created.
  • PKG is the compressed archive format, such as “zip”, “tar.bz2″ and such. Generally, zip archives contain binaries that run on Windows, all other archives contains binarie that run on Linux.

Running the Binaries

Using Wine, we can even test the binaries directly from Linux. However, this only works on 32-bit Windows binaries and is not perfect due to bugs and missing features in Wine itself. After downloading and installing Wine for our distribution, we can test our program above by running “wine hello-w32.exe”.
Note that 64-bit Windows can run 32-bit binaries due to an emulation layer called Windows 32-bit On Windows 64-bit, but native binaries are more efficient.

Posted in GCC Windows | Tagged , , , , , , , , , | 5 Comments