<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Landscape Blog</title>
	<atom:link href="http://blog.landscape.canonical.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.landscape.canonical.com</link>
	<description>News about Landscape</description>
	<lastBuildDate>Mon, 10 Dec 2012 22:41:36 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Landscape as a Puppet External Node Classifier</title>
		<link>http://blog.landscape.canonical.com/2012/12/10/landscape-as-a-puppet-external-node-classifier/</link>
		<comments>http://blog.landscape.canonical.com/2012/12/10/landscape-as-a-puppet-external-node-classifier/#comments</comments>
		<pubDate>Mon, 10 Dec 2012 20:12:03 +0000</pubDate>
		<dc:creator>Mike Milner</dc:creator>
				<category><![CDATA[Focus on Tech]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[canonical]]></category>
		<category><![CDATA[landscape]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=777</guid>
		<description><![CDATA[In our last blog on Landscape and Puppet, we talked about using Landscape to automatically deploy Puppet on new computers. In this article we’ll dive deeper, and look at how to use Landscape as an External Node Classifier for Puppet. In a typical Puppet configuration, all your nodes are defined in site.pp under the “node” [...]]]></description>
			<content:encoded><![CDATA[<p>In our last blog on Landscape and Puppet, we talked about using Landscape to automatically deploy Puppet on new computers. In this article we’ll dive deeper, and look at how to use Landscape as an External Node Classifier for Puppet.</p>
<p>In a typical Puppet configuration, all your nodes are defined in site.pp under the “node” definitions section. Each node is assigned Puppet classes by manually editing the file. When your number of nodes grows, manually managing the site.pp file becomes tedious and error prone.</p>
<p>An External Node Classifier (ENC) is Puppet’s way of offloading the tedious node maintenance to an external program. The interface is dead simple &#8211; puppet executes the external node classifier program with a single full node name as the only argument. The classifier just has to write a YAML blob out to stdout before exiting.</p>
<p>To start, let’s create a simple python ENC in /etc/puppet/landscape_enc &#8211; Don’t forget to make the file executable.</p>
<p><!-- 1 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="line-height: 125%;"><span style="color: #408080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #008000; font-weight: bold;">import</span> <span style="color: #0000ff; font-weight: bold;">sys</span>
<span style="color: #008000; font-weight: bold;">import</span> <span style="color: #0000ff; font-weight: bold;">yaml</span>

<span style="color: #408080; font-style: italic;"># The node name to be classified is supplied as an argument to the script</span>
node_name <span style="color: #666666;">=</span> sys<span style="color: #666666;">.</span>argv[<span style="color: #666666;">1</span>]

classes <span style="color: #666666;">=</span> [<span style="color: #ba2121;">"basenode"</span>]

<span style="color: #408080; font-style: italic;"># Output must be a YAML document</span>
<span style="color: #008000; font-weight: bold;">print</span>(yaml<span style="color: #666666;">.</span>dump({
    <span style="color: #ba2121;">"classes"</span>: classes,
    }))</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>It ignores the node name and just puts everything into the “basenode” class. Not very interesting but it’s enough to get started with Puppet.</p>
<p>NOTE: These examples are all using puppet 2.7 which ships on Ubuntu 12.04 Precise LTS. The ENC functionality behaves a bit differently in versions of puppet earlier than 2.65 &#8211; See http://docs.puppetlabs.com/guides/external_nodes.html for details.</p>
<p>To test the ENC I put together a minimal puppet configuration with two simple classes and put everything into my site.pp in /etc/puppet/manifests/site.pp</p>
<p><!-- 2 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;">1
2
3
4
5
6
7</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="line-height: 125%;"><span style="color: #008000; font-weight: bold;">class</span> <span style="color: #0000ff; font-weight: bold;">basenode</span> {
  notify {<span style="color: #ba2121;">"I am a basenode!"</span>:}
}

<span style="color: #008000; font-weight: bold;">class</span> <span style="color: #0000ff; font-weight: bold;">specialnode</span> {
  notify {<span style="color: #ba2121;">"I am a specialnode!"</span>:}
}</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Notice that no nodes are actually defined. That is the ENC’s job. To enable the ENC you need to add two lines to your puppetmaster’s config file /etc/puppet/puppet.conf</p>
<p>Add these lines at the end of the “[master]” section:</p>
<p><!-- 3 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;">1
2</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="line-height: 125%;">node_terminus = exec
external_nodes = /etc/puppet/landscape_enc</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>You can now test that the puppetmaster is using your new, rather basic, ENC.</p>
<p><!-- 4 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;">1
2
3
4
5
6
7</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="line-height: 125%;"><span style="color: #000080; font-weight: bold;">ubuntu@ubuntu:~$</span> sudo puppet agent --test

<span style="color: #808080;">info: Caching catalog for ubuntu</span>
<span style="color: #808080;">info: Applying configuration version '1354824718'</span>
<span style="color: #808080;">notice: I am a basenode!</span>
<span style="color: #808080;">notice: /Stage[main]/Basenode/Notify[I am a basenode!]/message: defined 'message' as 'I am a basenode!'</span>
<span style="color: #808080;">notice: Finished catalog run in 0.06 seconds</span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>As you can see, with our trivial ENC everyone is a basenode.</p>
<p>Now we’re going to enhance our ENC to ask Landscape to classify nodes for us.</p>
<p><strong>The Landscape API</strong><br />
To use the Landscape API you need three pieces of information: the Landscape API endpoint URI, the user key, and the secret for your user.</p>
<p>To find your API credentials, log in to the Landscape web interface and click your username on the top right. Your API credentials are in the “API Access” section.</p>
<p>For this example, we’ll use the python API client provided with Landscape (NOTE, you must install the landscape-api package first). Here’s how to query for a computer registered with Landscape using it’s host name:</p>
<p><!-- 5 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="line-height: 125%;"><span style="color: #008000; font-weight: bold;">from</span> <span style="color: #0000ff; font-weight: bold;">landscape_api.base</span> <span style="color: #008000; font-weight: bold;">import</span> API

landscape_uri <span style="color: #666666;">=</span> <span style="color: #ba2121;">"https://landscape.canonical.com/api/"</span>
landscape_key <span style="color: #666666;">=</span> <span style="color: #ba2121;">"43NW6OV71L32CSOPCJGX"</span>
landscape_secret <span style="color: #666666;">=</span> <span style="color: #ba2121;">"agBf3v267DqO8vtVRnzjseWfYdV4ueklj5a81iIT"</span>
api <span style="color: #666666;">=</span> API(landscape_uri, landscape_key, landscape_secret)

api<span style="color: #666666;">.</span>get_computers(query<span style="color: #666666;">=</span><span style="color: #ba2121;">"my_hostname_here"</span>)
[{<span style="color: #ba2121;">u'access_group'</span>: <span style="color: #ba2121;">u'server'</span>,
<span style="color: #ba2121;">u'comment'</span>: <span style="color: #ba2121;">u''</span>,
<span style="color: #ba2121;">u'hostname'</span>: <span style="color: #ba2121;">u'appserv1'</span>,
<span style="color: #ba2121;">u'id'</span>: <span style="color: #666666;">1</span>,
<span style="color: #ba2121;">u'last_exchange_time'</span>: <span style="color: #008000;">None</span>,
<span style="color: #ba2121;">u'last_ping_time'</span>: <span style="color: #ba2121;">u'2012-09-07T15:19:22Z'</span>,
<span style="color: #ba2121;">u'reboot_required_flag'</span>: <span style="color: #008000;">False</span>,
<span style="color: #ba2121;">u'tags'</span>: [<span style="color: #ba2121;">u'lucid'</span>, <span style="color: #ba2121;">u'server'</span>, <span style="color: #ba2121;">u'puppet-webfarm'</span>],
<span style="color: #ba2121;">u'title'</span>: <span style="color: #ba2121;">u'Application Server 1'</span>,
<span style="color: #ba2121;">u'total_memory'</span>: <span style="color: #666666;">1024</span>,
<span style="color: #ba2121;">u'total_swap'</span>: <span style="color: #666666;">1024</span>}]</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Now if we combine that with our ENC we get the following:</p>
<p><!-- 6 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="line-height: 125%;"><span style="color: #408080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #008000; font-weight: bold;">import</span> <span style="color: #0000ff; font-weight: bold;">sys</span>
<span style="color: #008000; font-weight: bold;">import</span> <span style="color: #0000ff; font-weight: bold;">yaml</span>
<span style="color: #008000; font-weight: bold;">from</span> <span style="color: #0000ff; font-weight: bold;">landscape_api.base</span> <span style="color: #008000; font-weight: bold;">import</span> API

<span style="color: #408080; font-style: italic;"># Create our connection to Landscape</span>
landscape_uri <span style="color: #666666;">=</span> <span style="color: #ba2121;">"https://landscape.canonical.com/api/"</span>
landscape_key <span style="color: #666666;">=</span> <span style="color: #ba2121;">"43NW6OV71L32CSOPCJGX"</span>
landscape_secret <span style="color: #666666;">=</span> <span style="color: #ba2121;">"agBf3v267DqO8vtVRnzjseWfYdV4ueklj5a81iIT"</span>
api <span style="color: #666666;">=</span> API(landscape_uri, landscape_key, landscape_secret)

<span style="color: #408080; font-style: italic;"># The node name to be classified is supplied as an argument to the script</span>
node_name <span style="color: #666666;">=</span> sys<span style="color: #666666;">.</span>argv[<span style="color: #666666;">1</span>]

<span style="color: #408080; font-style: italic;"># Ask Landscape about the computer</span>
computers <span style="color: #666666;">=</span> api<span style="color: #666666;">.</span>get_computers(query<span style="color: #666666;">=</span>node_name)

<span style="color: #408080; font-style: italic;"># If we don't get back any computers or if we get more than one, error out.</span>
<span style="color: #408080; font-style: italic;"># You could also handle this case by simply giving the node a default class.</span>
<span style="color: #008000; font-weight: bold;">if</span> <span style="color: #008000;">len</span>(computers) <span style="color: #666666;">!=</span> <span style="color: #666666;">1</span>:
    sys<span style="color: #666666;">.</span>stderr<span style="color: #666666;">.</span>write(<span style="color: #ba2121;">"Only expecting one computer, instead got this: </span><span style="color: #bb6688; font-weight: bold;">%s</span><span style="color: #ba2121;">"</span> <span style="color: #666666;">%</span> computers)
    sys<span style="color: #666666;">.</span>exit(<span style="color: #666666;">1</span>)

<span style="color: #408080; font-style: italic;"># Extract the tags from our computer</span>
tags <span style="color: #666666;">=</span> computer[<span style="color: #666666;">0</span>][<span style="color: #ba2121;">"tags"</span>]

<span style="color: #408080; font-style: italic;"># Now here you can use whatever logic you want to convert</span>
<span style="color: #408080; font-style: italic;"># tags into classes. I'm going to use any tag that starts with "puppet-"</span>
<span style="color: #408080; font-style: italic;"># as a class name. I'm also going to make sure every node gets the</span>
<span style="color: #408080; font-style: italic;"># "basenode" class</span>
classes <span style="color: #666666;">=</span> [<span style="color: #ba2121;">"basenode"</span>]
<span style="color: #008000; font-weight: bold;">for</span> tag <span style="color: #aa22ff; font-weight: bold;">in</span> tags:
    <span style="color: #008000; font-weight: bold;">if</span> tag<span style="color: #666666;">.</span>startswith(<span style="color: #ba2121;">"puppet-"</span>):
        class_name <span style="color: #666666;">=</span> tag<span style="color: #666666;">.</span>split(<span style="color: #ba2121;">"-"</span>,<span style="color: #666666;">1</span>)[<span style="color: #666666;">1</span>]
        classes<span style="color: #666666;">.</span>append(class_name)

<span style="color: #408080; font-style: italic;"># Output must be a YAML document</span>
<span style="color: #008000; font-weight: bold;">print</span>(yaml<span style="color: #666666;">.</span>dump({
    <span style="color: #ba2121;">"classes"</span>: classes,
    }))</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>That’s all there is to it. Now if you tag a computer “puppet-database” in Landscape, it will automatically get the “database” class in Puppet.</p>
<p>You can see in the script comments that it’s very easy to customize the behaviour to match your environment. Now tag away and let Landscape and Puppet take over your world!</p>
<p><a href="https://www.usenix.org/conference/lisa12"><img class="alignnone size-full wp-image-799" title="USENIX LISA12" src="/wp-content/uploads/2012/12/lisa12_button_125x125.png" alt="" width="125" height="125" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2012/12/10/landscape-as-a-puppet-external-node-classifier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Landscape offline October 25th, 2012 from 14:00 UTC &#8211; 15:00 UTC</title>
		<link>http://blog.landscape.canonical.com/2012/10/25/landscape-offline-october-25th-2012-from-1400-utc-1500-utc/</link>
		<comments>http://blog.landscape.canonical.com/2012/10/25/landscape-offline-october-25th-2012-from-1400-utc-1500-utc/#comments</comments>
		<pubDate>Thu, 25 Oct 2012 13:58:07 +0000</pubDate>
		<dc:creator>Matthew Wedgwood</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=771</guid>
		<description><![CDATA[We are updating Landscape on October 25th. While we roll-out the code to Landscape’s servers, we’ll have to take the service offline. Goes offline: 14:00 October 25th 2012 UTC Expected back online: 15:00 October 25th 2012 UTC We’re sorry for the downtime you’ll experience during the roll-out.]]></description>
			<content:encoded><![CDATA[<p>We are updating Landscape on October 25th. While we roll-out the code to Landscape’s servers, we’ll have to take the service offline.</p>
<p>Goes offline: 14:00 October 25th 2012 UTC<br />
Expected back online: 15:00 October 25th 2012 UTC</p>
<p>We’re sorry for the downtime you’ll experience during the roll-out.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2012/10/25/landscape-offline-october-25th-2012-from-1400-utc-1500-utc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mastering Package Holds</title>
		<link>http://blog.landscape.canonical.com/2012/10/05/mastering-package-holds/</link>
		<comments>http://blog.landscape.canonical.com/2012/10/05/mastering-package-holds/#comments</comments>
		<pubDate>Fri, 05 Oct 2012 01:21:01 +0000</pubDate>
		<dc:creator>Federico Lucifredi</dc:creator>
				<category><![CDATA[Focus on Tech]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=660</guid>
		<description><![CDATA[Landscape&#8217;s new release brings to full circle the changes that began a few months ago, beginning with the deprecating of support for Smart package locks: with full APT integration in the client, we are now exposing dpkg holds as first class citizens. Package holds exist to stop a package from being updated, the most typical [...]]]></description>
			<content:encoded><![CDATA[<p>Landscape&#8217;s new release brings to full circle the changes that began a few months ago, beginning with the deprecating of support for Smart package locks: with full APT integration in the client, we are now exposing dpkg holds as first class citizens.</p>
<p><a title="Holds and Pinning HOWTO" href="https://help.ubuntu.com/community/PinningHowto#Introduction_to_Holding_Packages">Package holds</a> exist to stop a package from being updated, the most typical case being the commonplace <code><strong>sudo apt-get upgrade</strong></code> mass-upgrade command. We could use package holds to instruct the update stack not to modify my system&#8217;s currently installed version of Python:</p>
<p><strong><code>echo "python2.7 hold" | sudo dpkg --set-selections</code><br />
</strong><br />
and good old dpkg would oblige.  What we have done here is changing the dpkg policy for this package&#8217;s upgrades from the default <em>install</em> to <em>hold</em>, the system does the rest, and stops offering us updates for this package. Similarly, I can set a hold on a package from Landscape, and on a broader selection of our datacenter assets. in this case, let&#8217;s select the venerable AWK:</p>
<p>&nbsp;</p>
<p><a href="/wp-content/uploads/2012/09/Selection_022.png"><img class="size-full wp-image-685 alignnone" title="placing a hold on AWK" src="/wp-content/uploads/2012/09/Selection_022.png" alt="[Placing a hold on AWK]" width="702" height="396" /></a></p>
<p>All I had to do was click the package icon on the right and applying the change &#8211; in Landscape, doing this for a lone machine or a fleet of thousands takes the same time and effort. In a minute, Landscape confirms successful execution:</p>
<p><a href="/wp-content/uploads/2012/09/Selection_024.png"><img class="alignnone  wp-image-690" title="Holding package mawk" src="/wp-content/uploads/2012/09/Selection_024.png" alt="[activity results]" width="613" height="375" /></a></p>
<p>&nbsp;</p>
<p>What&#8217;s more, the very same hold Landscape configured is now visible at the shell level on the client system, in a seamless display of integration between dpkg and Landscape &#8211; here is the shell view before and after the command was issued:</p>
<p>&nbsp;</p>
<p><a href="/wp-content/uploads/2012/09/Selection_023.png"><img class=" wp-image-692 alignnone" title="Holds as seen from the shell" src="/wp-content/uploads/2012/09/Selection_023.png" alt="[the shell view]" width="716" height="107" /></a></p>
<p>&nbsp;</p>
<p>Once a hold is in place for a package, regular system upgrades will not change the installed version, even when a newer version becomes available in the configured repositories &#8211; regardless of where the update command was issued from, Apt or Landscape.  This provides administrators with a convenient way to protect themselves from accidental mistakes: when a workload is known to be dependent on a specific package version, holds make the system track and enforce this requirement for you &#8211; a more reliable and stress-free approach than post-it notes, spreadsheets, or the shared oral culture of your IT team.</p>
<p>A fairly common scenario exposing additional nuances is holding the kernel version. If a kernel update is made available, two scenarios are possible. In the simplest case, a new build of the kernel is available, with changes that do not impact the kernel ABI, and the installed package name would remain the same &#8211; for example, <code>linux-image-3.2.0-23-generic-pae</code>, with version going from 3.2.0-23.35 to 3.2.0-23.36 for the new build. Holding this package name will block minor kernel updates that remain ABI-compatible.</p>
<p>The second scenario is more interesting. When the kernel upgrade involves an ABI change, Ubuntu&#8217;s Kernel team will introduce a new package, with a different name, like <code>linux-image-3.2.0-24-generic-pae</code>, and as this is a differently named package, the hold on the previous version will not block this new install. The key to restricting kernel upgrades involving an ABI change is in holding the kernel metapackage upgrade, which is triggering the new install through its dependencies.</p>
<p><a href="/wp-content/uploads/2012/10/Selection_029.png"><img class="alignnone size-full wp-image-768" title="Installed kernels list" src="/wp-content/uploads/2012/10/Selection_029.png" alt="" width="755" height="199" /></a></p>
<p>On my system, I use the linux-generic-pae kernel flavour. Holding the corresponding metapackage does the trick:</p>
<p><code><strong>echo "linux-generic-pae hold" | sudo dpkg --set-selections</strong></code></p>
<p>Holding the metapackage upgrade restrains the system from upgrading to the latest kernel with the new ABI &#8212; but will allow ABI-compatible upgrades if any become available.  This is reflected both in upgrade selections managed by <code><strong>apt-get upgrade</strong></code>, and remotely by Landscape, as you can see graphically in Landscape&#8217;s interface:</p>
<p><a href="/wp-content/uploads/2012/10/Selection_028.png"><img class="alignnone size-full wp-image-758" title="Shell-originated hold, reflected in landscape" src="/wp-content/uploads/2012/10/Selection_028.png" alt="" width="744" height="464" /></a></p>
<p>To complete our hold master class, we should point out that holds are designed to block package updates, not new installs. If you instruct dpkg, apt-get or Landscape to specifically install a given package, your instructions shall be obeyed. The system is designed with the assumption that you know what you are doing, and holds are used to manage the update system&#8217;s behaviour, not to stand in the way of the admin.</p>
<p>We want the user experience of Landscape&#8217;s centralized console to reflect the interaction an administrator has with the terminal of a single Ubuntu system: following a <a title="Principle of Least Astonishment" href="http://en.wikipedia.org/wiki/Principle_of_least_astonishment" target="_blank">Principle of Least Surprise</a> philosophy in our design, we leverage your existing Ubuntu architectural knowledge as much as possible.  This way, we can reflect the user&#8217;s expectation of Ubuntu&#8217;s behaviour, and flatten Landscape&#8217;s learning curve.  To accomplish this, we rely as much as possible on Ubuntu&#8217;s built-in default interfaces to the system&#8217; state, like lshw or dpkg, as data sources and management interfaces for the Landscape client.</p>
<p>And those are package holds. Now just one click away in Landscape.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2012/10/05/mastering-package-holds/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Integrating Landscape and Puppet</title>
		<link>http://blog.landscape.canonical.com/2012/09/19/integrating-landscape-and-puppet/</link>
		<comments>http://blog.landscape.canonical.com/2012/09/19/integrating-landscape-and-puppet/#comments</comments>
		<pubDate>Wed, 19 Sep 2012 23:23:23 +0000</pubDate>
		<dc:creator>Mike Milner</dc:creator>
				<category><![CDATA[Focus on Tech]]></category>
		<category><![CDATA[canonical]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=612</guid>
		<description><![CDATA[There is something wonderful about getting new hardware. I love opening all the boxes and putting new servers into racks and plugging everything together. Setting up the OS and software however can be a pain. This is where Puppet and Landscape come to the rescue. Puppet is great at configuring nodes the way you want [...]]]></description>
			<content:encoded><![CDATA[<p>There is something wonderful about getting new hardware. I love opening all the boxes and putting new servers into racks and plugging everything together. Setting up the OS and software however can be a pain. This is where Puppet and Landscape come to the rescue.</p>
<p>Puppet is great at configuring nodes the way you want them and keeping them that way. On the puppet master, you describe various aspects of the system using a simple declarative language. On the managed computers, a small agent talks to the puppet master and pulls down config changes. If you need to change a configuration on all your machines, you can change it once on the puppet master and it gets pushed out to all the agents.</p>
<p>In this article we’re going to use Landscape to do the initial setup of puppet. Tag a computer in Landscape with &#8220;puppet&#8221;, and the puppet agent will automatically be installed and configured. We’re going to use a meta-package plus some new Landscape features to make it all easy.</p>
<p><strong>Meta-Package</strong><br />
The meta-package is a common trick used on Debian and Ubuntu based systems to easily pull in a subset of packages. Here we’ll use a meta-package to pull in all the puppet dependencies then run a small script to register the puppet agent to the puppet master.</p>
<p>Our meta-package will only have two files: control, and postinst. These files will both live in the DEBIAN directory like this:</p>
<pre>
working directory
  |&gt; landscape-puppet
      |&gt; DEBIAN
          |&gt; control
          |&gt; postinst
</pre>
<p><br/></p>
<p>Here’s the control file:</p>
<p><!-- control --></p>
<table class="highlighttable">
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px">
<pre style="line-height: 125%">1
2
3
4
5
6
7
8</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8">
<pre style="font-family:monospace; line-height: 125%"><span style="color: #008000; font-weight: bold">Package</span><span style="color: #bbbbbb">: </span><span style="color: #BA2121">landscape-puppet</span>
<span style="color: #008000; font-weight: bold">Version</span>: <span style="color: #666666">0.1</span>
<span style="color: #008000; font-weight: bold">Section</span><span style="color: #bbbbbb">: </span><span style="color: #BA2121">main</span>
<span style="color: #008000; font-weight: bold">Priority</span><span style="color: #bbbbbb">: </span><span style="color: #BA2121">standard</span>
<span style="color: #008000; font-weight: bold">Architecture</span><span style="color: #bbbbbb">: </span><span style="color: #BA2121">all</span>
<span style="color: #008000; font-weight: bold">Depends</span>: <span style="color: #0000FF">landscape-client</span>, <span style="color: #0000FF">puppet</span>
<span style="color: #008000; font-weight: bold">Maintainer</span>: Mike Milner <span style="font-weight: bold">&lt;mike.milner@example.com&gt;</span>
<span style="color: #008000; font-weight: bold">Description</span><span style="font-weight: bold">: Configure system for use with puppet.</span>
</pre>
</div>
</td>
</tr>
</table>
<p><br/></p>
<p>And here’s the postinst file &#8211; this gets executed after the package is installed:</p>
<p><!-- postinst --></p>
<table class="highlighttable">
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px">
<pre style="line-height: 125%"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8">
<pre style="font-family:monospace; line-height: 125%"><span style="color: #408080; font-style: italic">#!/bin/bash</span>

<span style="color: #19177C">PUPPETCONFIG</span><span style="color: #666666">=</span>/etc/puppet/puppet.conf

<span style="color: #408080; font-style: italic"># Back up current puppet config if it exists</span>
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">[</span> -f <span style="color: #BA2121">&quot;$PUPPETCONFIG&quot;</span> <span style="color: #666666">]</span>; <span style="color: #008000; font-weight: bold">then</span>
<span style="color: #008000; font-weight: bold">   </span>mv <span style="color: #19177C">$PUPPETCONFIG</span> <span style="color: #19177C">$PUPPETCONFIG</span>.bak-landscape
<span style="color: #008000; font-weight: bold">fi</span>

<span style="color: #408080; font-style: italic"># Write the new puppet config file</span>
cat &gt; <span style="color: #19177C">$PUPPETCONFIG</span> <span style="color: #BA2121">&lt;&lt; END</span>
<span style="color: #BA2121"># Default puppet configuration pushed by Landscape.</span>
<span style="color: #BA2121">[agent]</span>
<span style="color: #BA2121">  server = puppet.example.com</span>
<span style="color: #BA2121">  report = true</span>
<span style="color: #BA2121">  pluginsync = true</span>
<span style="color: #BA2121">END</span>

<span style="color: #408080; font-style: italic"># Use puppet itself to make sure the puppet service starts on boot</span>
puppet resource service puppet <span style="color: #19177C">ensure</span><span style="color: #666666">=</span>running <span style="color: #008000">enable</span><span style="color: #666666">=</span><span style="color: #008000">true</span>
</pre>
</div>
</td>
</tr>
</table>
<p><br/></p>
<p>To build the package, change to your working directory that contains the “landscape-puppet” directory then execute the following command:</p>
<p><!-- build command --></p>
<table class="highlighttable">
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px">
<pre style="line-height: 125%">1</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8">
<pre style="font-family:monospace; line-height: 125%"><span style="color: #000080; font-weight: bold">$</span> dpkg-deb -b landscape-puppet landscape-puppet_0.1_all.deb
</pre>
</div>
</td>
</tr>
</table>
<p><br/></p>
<p>If all goes well you should now have a landscape-puppet.deb file in the current directory. Congratulations, you’ve built a meta-package!</p>
<p>This is just a touch on meta-packages. For more info check out <a href="https://help.ubuntu.com/community/MetaPackages" title="Ubuntu MetaPackages">https://help.ubuntu.com/community/MetaPackages</a></p>
<p><strong>Landscape Repository Management</strong><br />
Now that we have a package, we’re going to use Landscape’s new Repository Management features to create a new apt repository and upload our package. Because this feature is so new, it’s only available through the API for now. I’ll walk you through setting things up.</p>
<p>Landscape&#8217;s Repository Management supports a few different use cases:</p>
<p>Landscape can mirror public repositories &#8211; like the official Ubuntu archive &#8211; into your local network. This gives you LAN speeds for updates and lets YOU control when packages get deployed.</p>
<p>Landscape can stage repositories. You might want to try new packages on a staging system before you roll them out to production. Landscape lets you selectively pull packages into your production repository after you&#8217;ve tested them on your staging system &#8211; all managed by Landscape.</p>
<p>And for this example, we&#8217;re using the Upload Repository. This lets you create an empty repository and upload your own packages for distribution.</p>
<p>In all cases Landscape takes care of the details for you. GPG keys are verified when mirroring external repositories, and keys are distributed to clients automatically when creating your own repositories. Everything is cryptographically verified.</p>
<p>To use the API, you first have to get your API credentials. Follow the steps on <a href="https://help.landscape.canonical.com/LDS/BetaReleaseNotes" title="LDS Release Notes">https://help.landscape.canonical.com/LDS/BetaReleaseNotes</a> under the “API Getting Started” section. Once you’ve got your credentials set up in the appropriate environment variables use the following commands to set up the repository:</p>
<p>Create a new GPG key to sign your repository:</p>
<p><!-- 1 --></p>
<table class="highlighttable">
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px">
<pre style="line-height: 125%"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8">
<pre style="font-family:monospace; line-height: 125%"><span style="color: #000080; font-weight: bold">$</span> cat &gt; gpg-batch-commands &lt;&lt; EOF
<span style="color: #808080">Key-Type: DSA</span>
<span style="color: #808080">Key-Length: 2048</span>
<span style="color: #808080">Subkey-Type: ELG-E</span>
<span style="color: #808080">Subkey-Length: 2048</span>
<span style="color: #808080">Name-Real: Landscape Repository Signing Key</span>
<span style="color: #808080">Name-Comment: Landscape</span>
<span style="color: #808080">Name-Email: landscape@example.com</span>
<span style="color: #808080">Expire-Date: 0</span>
<span style="color: #000080; font-weight: bold">%</span>pubring landscape.pub
<span style="color: #000080; font-weight: bold">%</span>secring landscape.sec
<span style="color: #000080; font-weight: bold">%</span>commit
<span style="color: #808080">EOF</span>

<span style="color: #000080; font-weight: bold">$</span> gpg --batch --gen-key gpg-batch-commands

<span style="color: #000080; font-weight: bold">$</span> gpg --no-default-keyring --secret-keyring ./landscape.sec <span style="color: #BB6622; font-weight: bold">\</span>
<span style="color: #808080">  --keyring ./landscape.pub --export-secret-keys \</span>
<span style="color: #808080">  -a &gt; landscape-signing-key-secret</span>
</pre>
</div>
</td>
</tr>
</table>
<p><br/></p>
<p>Now import your new secret key. Landscape will use it to sign your new repository:</p>
<p><!-- 2 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;">1
2
3
4
5</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #000080; font-weight: bold;">$</span> landscape-api import-gpg-key upload-signing-key landscape-signing-key-secret
<span style="color: #808080;">{u'fingerprint': u'c7da:4521:a948:600a:bd26:6e69:2fec:1d65:524a:3a15',</span>
<span style="color: #808080;"> u'has_secret': True,</span>
<span style="color: #808080;"> u'id': 3,</span>
<span style="color: #808080;"> u'name': u'upload-signing-key'}</span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Now that we have a key, we can configure our repository:</p>
<p><!-- 3 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #000080; font-weight: bold;">$</span> landscape-api create-distribution landscape
<span style="color: #808080;">{u'access_group': u'global',</span>
<span style="color: #808080;"> u'creation_time': u'2012-09-18T15:21:36Z',</span>
<span style="color: #808080;"> u'name': u'landscape',</span>
<span style="color: #808080;"> u'series': []}</span>

<span style="color: #000080; font-weight: bold;">$</span> landscape-api create-series upload landscape
<span style="color: #808080;">{u'creation_time': u'2012-09-18T15:23:21Z', u'name': u'upload', u'pockets': []}</span>

<span style="color: #000080; font-weight: bold;">$</span> landscape-api create-pocket ubuntu upload landscape main amd64 upload upload-signing-key --upload-allow-unsigned
<span style="color: #808080;">{u'apt_source_line': u'deb http://localhost:8080/repository/onward/landscape upload-ubuntu main',</span>
<span style="color: #808080;"> u'architectures': [u'amd64'],</span>
<span style="color: #808080;"> u'components': [u'main'],</span>
<span style="color: #808080;"> u'creation_time': u'2012-09-18T15:28:54Z',</span>
<span style="color: #808080;"> u'gpg_key': {u'fingerprint': u'c7da:4521:a948:600a:bd26:6e69:2fec:1d65:524a:3a15',</span>
<span style="color: #808080;"> u'has_secret': True,</span>
<span style="color: #808080;"> u'id': 3,</span>
<span style="color: #808080;"> u'name': u'upload-signing-key'},</span>
<span style="color: #808080;"> u'mode': u'upload',</span>
<span style="color: #808080;"> u'name': u'ubuntu',</span>
<span style="color: #808080;"> u'upload_allow_unsigned': True,</span>
<span style="color: #808080;"> u'upload_gpg_keys': []}</span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Now that we have our repository set up we need to upload our deb. To send packages to our upload pocket, we need to generate a &#8220;.changes&#8221; file which describes our upload. The &#8220;.changes&#8221; file contains additional information to help Landscape get your package into the right repository. Just use these commands to generate the &#8220;.changes&#8221; file and upload both files to Landscape.</p>
<p>If you are familiar with the &#8220;dput&#8221; command it can be used instead of the curl commands below. It has many options for checking your debs before upload. For this example however the curl commands will work fine.</p>
<p><!-- package upload --></p>
<table class="highlighttable">
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px">
<pre style="line-height: 125%">1
2
3
4
5</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8">
<pre style="font-family:monospace; line-height: 125%"><span style="color: #000080; font-weight: bold">$</span> changestool --create my.changes adddeb landscape_puppet_0.1_all.deb
<span style="color: #000080; font-weight: bold">$</span> changestool --create my.changes setdistribution upload-ubuntu

<span style="color: #000080; font-weight: bold">$</span> curl --upload-file landscape-puppet_0.1_all.deb http://lds.example.com/repository/standalone/landscape/upload/ubuntu/
<span style="color: #000080; font-weight: bold">$</span> curl --upload-file my.changes http://lds.example.com/repository/standalone/landscape/upload/ubuntu/
</pre>
</div>
</td>
</tr>
</table>
<p><br/></p>
<p>Now that our package is all set up in its repository, we will create a repository profile so we can make sure this repository is available to any machine with the “puppet” tag.</p>
<p>WARNING: Once you associate a repository profile to a computer in Landscape, it takes over management of your sources.list and sources.list.d on that computer. This means if you still want to use the official Ubuntu archive you need to make a repository profile for it. Take a look at the create-apt-source command and the documentation <a href="https://landscape.canonical.com/static/doc/repositories.html#createaptsource" title="CreateAPTSource Documentation">here</a> for more details.</p>
<p><!-- 5 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #000080; font-weight: bold;">$</span> landscape-api create-repository-profile landscape-upload
<span style="color: #808080;">{u'access_group': u'global',</span>
<span style="color: #808080;"> u'all_computers': False,</span>
<span style="color: #808080;"> u'apt_sources': [],</span>
<span style="color: #808080;"> u'description': u'',</span>
<span style="color: #808080;"> u'id': 4,</span>
<span style="color: #808080;"> u'name': u'landscape-upload',</span>
<span style="color: #808080;"> u'pockets': [],</span>
<span style="color: #808080;"> u'tags': []}</span>

<span style="color: #000080; font-weight: bold;">$</span> landscape-api add-pockets-to-repository-profile landscape-upload ubuntu upload landscape
<span style="color: #808080;">{u'access_group': u'global',</span>
<span style="color: #808080;"> u'all_computers': False,</span>
<span style="color: #808080;"> u'apt_sources': [],</span>
<span style="color: #808080;"> u'description': u'',</span>
<span style="color: #808080;"> u'id': 4,</span>
<span style="color: #808080;"> u'name': u'landscape-upload',</span>
<span style="color: #808080;"> u'pockets': [{u'apt_source_line': u'deb http://localhost:8080/repository/onward/landscape upload-ubuntu main',</span>
<span style="color: #808080;"> u'architectures': [u'amd64'],</span>
<span style="color: #808080;"> u'components': [u'main'],</span>
<span style="color: #808080;"> u'creation_time': u'2012-09-18T15:28:54Z',</span>
<span style="color: #808080;"> u'gpg_key': {u'fingerprint': u'c7da:4521:a948:600a:bd26:6e69:2fec:1d65:524a:3a15',</span>
<span style="color: #808080;"> u'has_secret': True,</span>
<span style="color: #808080;"> u'id': 3,</span>
<span style="color: #808080;"> u'name': u'upload-signing-key'},</span>
<span style="color: #808080;"> u'mode': u'upload',</span>
<span style="color: #808080;"> u'name': u'ubuntu',</span>
<span style="color: #808080;"> u'upload_allow_unsigned': True,</span>
<span style="color: #808080;"> u'upload_gpg_keys': []}],</span>
<span style="color: #808080;"> u'tags': []}</span>

<span style="color: #000080; font-weight: bold;">$</span> landscape-api associate-repository-profile landscape-upload --tags puppet
<span style="color: #808080;">{u'access_group': u'global',</span>
<span style="color: #808080;"> u'all_computers': False,</span>
<span style="color: #808080;"> u'apt_sources': [],</span>
<span style="color: #808080;"> u'description': u'',</span>
<span style="color: #808080;"> u'id': 4,</span>
<span style="color: #808080;"> u'name': u'landscape-upload',</span>
<span style="color: #808080;"> u'pockets': [{u'apt_source_line': u'deb http://localhost:8080/repository/onward/landscape upload-ubuntu main',</span>
<span style="color: #808080;"> u'architectures': [u'amd64'],</span>
<span style="color: #808080;"> u'components': [u'main'],</span>
<span style="color: #808080;"> u'creation_time': u'2012-09-18T15:28:54Z',</span>
<span style="color: #808080;"> u'gpg_key': {u'fingerprint': u'c7da:4521:a948:600a:bd26:6e69:2fec:1d65:524a:3a15',</span>
<span style="color: #808080;"> u'has_secret': True,</span>
<span style="color: #808080;"> u'id': 3,</span>
<span style="color: #808080;"> u'name': u'upload-signing-key'},</span>
<span style="color: #808080;"> u'mode': u'upload',</span>
<span style="color: #808080;"> u'name': u'ubuntu',</span>
<span style="color: #808080;"> u'upload_allow_unsigned': True,</span>
<span style="color: #808080;"> u'upload_gpg_keys': []}],</span>
<span style="color: #808080;"> u'tags': [u'puppet']}</span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><strong>Landscape Package Profiles</strong><br />
So now we have our deb package sitting in a new apt repository ready to go. The final step is to create a package profile so the new package gets installed. We’ll do this using the GUI.</p>
<p><br/><br />
First, choose &#8220;Package Profiles&#8221; from the main menu:<br/>
<img class="alignnone size-full wp-image-615" title="PkgProfile_Choose_From_Menu" src="/wp-content/uploads/2012/09/pkg_profile1.png" alt="" width="1005" height="227" /><br/></p>
<p><br/><br />
Now, select &#8220;Add Package Profile&#8221;:<br/>
<img class="alignnone size-full wp-image-616" title="PkgProfile_Add_New" src="/wp-content/uploads/2012/09/pkg_profile2.png" alt="" width="249" height="116" /><br/></p>
<p><br/><br />
Fill in the form with your details:<br/>
<img class="alignnone size-full wp-image-617" title="PkgProfile_New_Form_Filled_Out" src="/wp-content/uploads/2012/09/pkg_profile3.png" alt="" width="562" height="674" /><br/></p>
<p><br/><br />
Associate your new package profile with the &#8220;puppet&#8221; tag:<br/>
<img class="alignnone size-full wp-image-618" title="PkgProfile_Associate_Tag" src="/wp-content/uploads/2012/09/pkg_profile4.png" alt="" width="431" height="374" /><br/></p>
<p><br/><br />
Finally you can see the status of the profile and how many computers have the profile installed:<br/>
<img class="alignnone size-full wp-image-619" title="PkgProfile_View_Status" src="/wp-content/uploads/2012/09/pkg_profile5.png" alt="" width="824" height="286" /><br/></p>
<p><strong>Pulling it all together</strong><br />
Now that everything is set up, we really see the power of this technique. Pick any computer in Landscape and add the “puppet” tag. This will automatically add our new apt repository to the computers apt sources, then it will automatically install our new meta-package. The new meta-package will automatically install puppet and all its dependencies, then the postinst script will finish the whole thing off by registering the puppet agent to the puppet-master.</p>
<p>By combining Landscape features we can apply some very powerful automation to our infrastructure. In this case, once puppet is registered the puppet-master will finish off customising the system according to our system catalogues.</p>
<p>In a later post I&#8217;ll show how to use Landscape as an External Node Classifier for Puppet for even more automation!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2012/09/19/integrating-landscape-and-puppet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Landscape with Nagios</title>
		<link>http://blog.landscape.canonical.com/2012/09/13/landscape-with-nagios/</link>
		<comments>http://blog.landscape.canonical.com/2012/09/13/landscape-with-nagios/#comments</comments>
		<pubDate>Thu, 13 Sep 2012 14:40:35 +0000</pubDate>
		<dc:creator>Mike Milner</dc:creator>
				<category><![CDATA[Focus on Tech]]></category>
		<category><![CDATA[canonical]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=540</guid>
		<description><![CDATA[Nagios is not the prettiest monitoring tool, but I do love it. There is something wonderful about all those little green squares telling me that everything is up and working. I still remember the first time I set up a small Nagios system in my organization &#8211; I wrote every configuration file by hand and [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-medium wp-image-581" style="float: left; margin: 20px;" title="nagios_headline" src="/wp-content/uploads/2012/09/nagios_headline-300x259.png" alt="" width="300" height="259" />Nagios is not the prettiest monitoring tool, but I do love it. There is something wonderful about all those little green squares telling me that everything is up and working.</p>
<p>I still remember the first time I set up a small Nagios system in my organization &#8211; I wrote every configuration file by hand and watched the green squares multiply as I added more hosts and services. It was fun at first, but as the system grew, editing all those configuration files by hand quickly became tedious. If you’re like me, the need to automate tedious tasks is overwhelming. That’s where the Landscape API comes in to make this simple.</p>
<p>At it’s heart, Landscape is a tool to help you manage your computing architecture. Landscape allows you to assign tags to every computer in your infrastructure. We’re going to use the Landscape API plus these tags to discover new computers and automatically configure them in Nagios. Add a computer to Landscape and it will automatically be added to Nagios with the appropriate hostgroup and services automatically configured.</p>
<p><strong>The Landscape API</strong><br />
To use the Landscape API you need three pieces of information: the Landscape API endpoint URI, the user key, and the secret for your user.</p>
<p>To find your API credentials, log in to the Landscape web interface and click your username on the top right. Your API credentials are in the “API Access” section.</p>
<p>For this example, we’ll use the python API client provided with Landscape (NOTE, you must install the landscape-api package first). Here’s how to query for a list of all the computers in registered with Landscape:</p>
<p><!-- 1 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #008000; font-weight: bold;">from</span> <span style="color: #0000ff; font-weight: bold;">landscape_api.base</span> <span style="color: #008000; font-weight: bold;">import</span> API

landscape_uri <span style="color: #666666;">=</span> <span style="color: #ba2121;">"https://landscape.canonical.com/api/"</span>
landscape_key <span style="color: #666666;">=</span> <span style="color: #ba2121;">"43NW6OV71L32CSOPCJGX"</span>
landscape_secret <span style="color: #666666;">=</span> <span style="color: #ba2121;">"agBf3v267DqO8vtVRnzjseWfYdV4ueklj5a81iIT"</span>
api <span style="color: #666666;">=</span> API(landscape_uri, landscape_key, landscape_secret)

api<span style="color: #666666;">.</span>get_computers()
[{<span style="color: #ba2121;">u'access_group'</span>: <span style="color: #ba2121;">u'server'</span>,
<span style="color: #ba2121;">u'comment'</span>: <span style="color: #ba2121;">u''</span>,
<span style="color: #ba2121;">u'hostname'</span>: <span style="color: #ba2121;">u'appserv1'</span>,
<span style="color: #ba2121;">u'id'</span>: <span style="color: #666666;">1</span>,
<span style="color: #ba2121;">u'last_exchange_time'</span>: <span style="color: #008000;">None</span>,
<span style="color: #ba2121;">u'last_ping_time'</span>: <span style="color: #ba2121;">u'2012-09-07T15:19:22Z'</span>,
<span style="color: #ba2121;">u'reboot_required_flag'</span>: <span style="color: #008000;">False</span>,
<span style="color: #ba2121;">u'tags'</span>: [<span style="color: #ba2121;">u'lucid'</span>, <span style="color: #ba2121;">u'server'</span>, <span style="color: #ba2121;">u'webfarm'</span>],
<span style="color: #ba2121;">u'title'</span>: <span style="color: #ba2121;">u'Application Server 1'</span>,
<span style="color: #ba2121;">u'total_memory'</span>: <span style="color: #666666;">1024</span>,
<span style="color: #ba2121;">u'total_swap'</span>: <span style="color: #666666;">1024</span>},
{<span style="color: #ba2121;">u'access_group'</span>: <span style="color: #ba2121;">u'server'</span>,
<span style="color: #ba2121;">u'comment'</span>: <span style="color: #ba2121;">u''</span>,
<span style="color: #ba2121;">u'hostname'</span>: <span style="color: #ba2121;">u'appserv2'</span>,
<span style="color: #ba2121;">u'id'</span>: <span style="color: #666666;">2</span>,
<span style="color: #ba2121;">u'last_exchange_time'</span>: <span style="color: #008000;">None</span>,
<span style="color: #ba2121;">u'last_ping_time'</span>: <span style="color: #ba2121;">u'2012-09-07T15:18:22Z'</span>,
<span style="color: #ba2121;">u'reboot_required_flag'</span>: <span style="color: #008000;">False</span>,
<span style="color: #ba2121;">u'tags'</span>: [<span style="color: #ba2121;">u'nagios'</span>, <span style="color: #ba2121;">u'precise'</span>, <span style="color: #ba2121;">u'server'</span>, <span style="color: #ba2121;">u'webserver'</span>],
<span style="color: #ba2121;">u'title'</span>: <span style="color: #ba2121;">u'Application Server 2'</span>,
<span style="color: #ba2121;">u'total_memory'</span>: <span style="color: #666666;">1024</span>,
<span style="color: #ba2121;">u'total_swap'</span>: <span style="color: #666666;">1024</span>}]</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>For this example we will also apply a filter to the get_computers() call so we only get back computers tagged with “nagios” and we will ask for the networking information to be included in the response.</p>
<p><!-- 2 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;">api<span style="color: #666666;">.</span>get_computers(query<span style="color: #666666;">=</span><span style="color: #ba2121;">"tag:nagios"</span>, with_networking<span style="color: #666666;">=</span><span style="color: #008000;">True</span>)
[{<span style="color: #ba2121;">u'access_group'</span>: <span style="color: #ba2121;">u'server'</span>,
<span style="color: #ba2121;">u'comment'</span>: <span style="color: #ba2121;">u''</span>,
<span style="color: #ba2121;">u'hostname'</span>: <span style="color: #ba2121;">u'appserv2'</span>,
<span style="color: #ba2121;">u'id'</span>: <span style="color: #666666;">2</span>,
<span style="color: #ba2121;">u'last_exchange_time'</span>: <span style="color: #008000;">None</span>,
<span style="color: #ba2121;">u'last_ping_time'</span>: <span style="color: #ba2121;">u'2012-09-07T15:18:22Z'</span>,
<span style="color: #ba2121;">u'network_devices'</span>: [{<span style="color: #ba2121;">u'broadcast_address'</span>: <span style="color: #ba2121;">u'192.168.0.255'</span>,
<span style="color: #ba2121;">u'interface'</span>: <span style="color: #ba2121;">u'eth0'</span>,
<span style="color: #ba2121;">u'ip_address'</span>: <span style="color: #ba2121;">u'192.168.0.61'</span>,
<span style="color: #ba2121;">u'mac_address'</span>: <span style="color: #ba2121;">u'00:1f:d9:ce:e1:69'</span>,
<span style="color: #ba2121;">u'netmask'</span>: <span style="color: #ba2121;">u'255.255.255.0'</span>}],
<span style="color: #ba2121;">u'reboot_required_flag'</span>: <span style="color: #008000;">False</span>,
<span style="color: #ba2121;">u'tags'</span>: [<span style="color: #ba2121;">u'nagios'</span>, <span style="color: #ba2121;">u'precise'</span>, <span style="color: #ba2121;">u'server'</span>, <span style="color: #ba2121;">u'webserver'</span>],
<span style="color: #ba2121;">u'title'</span>: <span style="color: #ba2121;">u'Application Server 2'</span>,
<span style="color: #ba2121;">u'total_memory'</span>: <span style="color: #666666;">1024</span>,
<span style="color: #ba2121;">u'total_swap'</span>: <span style="color: #666666;">1024</span>}]</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><strong>Nagios Configuration</strong><br />
Once we get the computers we’re interested in, we need to add them to the Nagios config. This example creates a separate configuration file for each Landscape computer. These should all be stored in a directory which Nagios will read.</p>
<p>To tell Nagios to process all files in a directory (and it’s subdirectories) you use the cfg_dir= command like this:</p>
<p><!-- 3 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;">1</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #19177c;">cfg_dir</span><span style="color: #666666;">=</span>/path/to/host/files</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Now all we have to do is create files in that directory for each host we get back from Landscape.</p>
<p>A Nagios host configuration file looks something like this:</p>
<p><!-- 4 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;">1
2
3
4
5
6
7</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;">define host{
    use          linux-host
    host_name    appserv2
    alias        Application Server 2
    address      192.168.0.61
    hostgroups   server, webserver
}</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>This file defines the host by specifying the host_name, alias, and address. The “use” parameter causes this host to inherit all the settings of the “linux-host” template. The “hostgroups” parameter puts this host under the “server” hostgroup and the “webserver” hostgroup.</p>
<p>The hostgroups define all the services that need to be monitored for any host that is part of the hostgroup. In this example, our host will get all services from the &#8220;server&#8221; hostgroup and the &#8220;webserver&#8221; hostgroup.</p>
<p><strong>The Script</strong><br />
Now that we have the basics of talking to Landscape and writing config files for Nagios, we’re going to pull it all together.</p>
<p><img class="alignnone size-full wp-image-578" title="Adding Tag to Computer" src="/wp-content/uploads/2012/09/addtag.png" alt="" width="414" height="109" /><br />
The tags we get from landscape will be used to link the host to Nagios’s hostgroups. The script is designed to be run repeatedly to keep the host definitions up to date. In my setup I run it in a cronjob every five minutes &#8211; new hosts and tag changes are picked up fairly quickly.</p>
<p>The script is fairly simple. I’ll walk through it piece by piece. For the full listing with full comments and doc string see the end of the articale.</p>
<p>First, we import the libraries we need and define our configuration values:</p>
<p><!-- 5 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #408080; font-style: italic;"># List of valid hostgroups - Landscape tags not in this list are ignored.</span>
<span style="color: #408080; font-style: italic;"># You must have a Nagios hostgroup defined for each entry in the list.</span>
VALID_HOSTGROUPS <span style="color: #666666;">=</span> [<span style="color: #ba2121;">"server"</span>, <span style="color: #ba2121;">"webfarm"</span>]

<span style="color: #408080; font-style: italic;"># A host template name to use for all the generated hosts. This host template</span>
<span style="color: #408080; font-style: italic;"># must already be defined in your Nagios configuration.</span>
HOST_TEMPLATE <span style="color: #666666;">=</span> <span style="color: #ba2121;">"ubuntu-host"</span>

<span style="color: #408080; font-style: italic;"># The directory to store the generated host files. It must be loaded into</span>
<span style="color: #408080; font-style: italic;"># the Nagios config using a cfg_dir= command.</span>
NAGIOS_HOST_DIRECTORY <span style="color: #666666;">=</span> <span style="color: #ba2121;">"nagios"</span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Now we ask landscape for a list of all computers with the “nagios” tag set and update each computer:</p>
<p><!-- 6 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;">api <span style="color: #666666;">=</span> API(LANDSCAPE_URI, LANDSCAPE_KEY, LANDSCAPE_SECRET)

<span style="color: #008000; font-weight: bold;">try</span>:
    <span style="color: #408080; font-style: italic;"># Get all computers tagged with "nagios"</span>
    computers <span style="color: #666666;">=</span> api<span style="color: #666666;">.</span>get_computers(query<span style="color: #666666;">=</span><span style="color: #ba2121;">"tag:nagios"</span>, with_network<span style="color: #666666;">=</span><span style="color: #008000;">True</span>)
<span style="color: #008000; font-weight: bold;">except</span> errors<span style="color: #666666;">.</span>InvalidQueryError:
    <span style="color: #408080; font-style: italic;"># If there has never been a computer tagged "nagios" we get a</span>
    <span style="color: #408080; font-style: italic;"># query error</span>
    computers <span style="color: #666666;">=</span> []

<span style="color: #408080; font-style: italic;"># Update the nagios config for each computer</span>
<span style="color: #008000; font-weight: bold;">for</span> computer <span style="color: #aa22ff; font-weight: bold;">in</span> computers:
    update_computer(computer)</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>For each computer we extract the information Nagios needs. In this example we use the first IP address available for the host. If your network is more complex you may have to add some more smarts here to use the IP address reachable by Nagios. Once the config is generated we write it to a file in the Nagios hosts directory:</p>
<p><!-- 7 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #008000; font-weight: bold;">def</span> <span style="color: #0000ff;">update_computer</span>(computer):
    <span style="color: #ba2121; font-style: italic;">"""Generates a host config file for the computer and saves it to disk."""</span>

    hostname <span style="color: #666666;">=</span> computer[<span style="color: #ba2121;">"hostname"</span>]
    title <span style="color: #666666;">=</span> computer[<span style="color: #ba2121;">"title"</span>]
    tags <span style="color: #666666;">=</span> computer[<span style="color: #ba2121;">"tags"</span>]
    ips <span style="color: #666666;">=</span> [net[<span style="color: #ba2121;">"ip_address"</span>] <span style="color: #008000; font-weight: bold;">for</span> net <span style="color: #aa22ff; font-weight: bold;">in</span> computer[<span style="color: #ba2121;">"network_devices"</span>]]

    <span style="color: #408080; font-style: italic;"># Filter out tags that aren't valid hostgroups</span>
    hostgroups <span style="color: #666666;">=</span> <span style="color: #008000;">set</span>(VALID_HOSTGROUPS)<span style="color: #666666;">.</span>intersection(<span style="color: #008000;">set</span>(tags))

    <span style="color: #408080; font-style: italic;"># If there is more than one IP address, use the first</span>
    ip <span style="color: #666666;">=</span> ips[<span style="color: #666666;">0</span>]

    <span style="color: #408080; font-style: italic;"># Use the hostname as the nagios filename</span>
    filename <span style="color: #666666;">=</span> <span style="color: #ba2121;">"</span><span style="color: #bb6688; font-weight: bold;">%s</span><span style="color: #ba2121;">.cfg"</span> <span style="color: #666666;">%</span> hostname
    filepath <span style="color: #666666;">=</span> os<span style="color: #666666;">.</span>path<span style="color: #666666;">.</span>join(NAGIOS_HOST_DIRECTORY, filename)

    <span style="color: #408080; font-style: italic;"># Generate the config file contents</span>
    config <span style="color: #666666;">=</span> generate_nagios_config(HOST_TEMPLATE,
                                    hostname, title, ip, hostgroups)

    <span style="color: #408080; font-style: italic;"># Write out the config file</span>
    <span style="color: #008000; font-weight: bold;">with</span> <span style="color: #008000;">open</span>(filepath, <span style="color: #ba2121;">"wb"</span>) <span style="color: #008000; font-weight: bold;">as</span> f:
        f<span style="color: #666666;">.</span>write(config)</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Here&#8217;s how the nagios host configuration file is generated:</p>
<p><!-- 8 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #008000; font-weight: bold;">def</span> <span style="color: #0000ff;">generate_nagios_config</span>(template, hostname, alias, ip, hostgroups):
    <span style="color: #ba2121; font-style: italic;">"""Generates the contents of a Nagios host config file."""</span>
    lines <span style="color: #666666;">=</span> [
        <span style="color: #ba2121;">"# Automatically generated from Landscape API data."</span>,
        <span style="color: #ba2121;">"# Any changes will be overwritten."</span>,
        <span style="color: #ba2121;">"define host{"</span>,
        <span style="color: #ba2121;">" use </span><span style="color: #bb6688; font-weight: bold;">%s</span><span style="color: #ba2121;">"</span> <span style="color: #666666;">%</span> template,
        <span style="color: #ba2121;">" host_name </span><span style="color: #bb6688; font-weight: bold;">%s</span><span style="color: #ba2121;">"</span> <span style="color: #666666;">%</span> hostname,
        <span style="color: #ba2121;">" alias </span><span style="color: #bb6688; font-weight: bold;">%s</span><span style="color: #ba2121;">"</span> <span style="color: #666666;">%</span> alias,
        <span style="color: #ba2121;">" address </span><span style="color: #bb6688; font-weight: bold;">%s</span><span style="color: #ba2121;">"</span> <span style="color: #666666;">%</span> ip,
        <span style="color: #ba2121;">" hostgroups </span><span style="color: #bb6688; font-weight: bold;">%s</span><span style="color: #ba2121;">"</span> <span style="color: #666666;">%</span> (<span style="color: #ba2121;">", "</span><span style="color: #666666;">.</span>join(hostgroups)),
        <span style="color: #ba2121;">"}"</span>]
    <span style="color: #008000; font-weight: bold;">return</span> <span style="color: #ba2121;">"</span><span style="color: #bb6622; font-weight: bold;">\n</span><span style="color: #ba2121;">"</span><span style="color: #666666;">.</span>join(lines)</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Finally, we ask nagios to reload the configuration files to see the new data.</p>
<p><!-- 9 --></p>
<table class="highlighttable">
<tbody>
<tr>
<td>
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;">
<pre style="line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre>
</div>
</td>
<td class="code">
<div class="highlight" style="background: #f8f8f8;">
<pre style="font-family: monospace; line-height: 125%;"><span style="color: #008000; font-weight: bold;">def</span> <span style="color: #0000ff;">reload_config</span>():
    <span style="color: #ba2121; font-style: italic;">"""</span>
<span style="color: #ba2121; font-style: italic;"> Use Ubuntu init script to reload the Nagios configuration. Note that</span>
<span style="color: #ba2121; font-style: italic;"> the configuration is checked before reloading to prevent errors from</span>
<span style="color: #ba2121; font-style: italic;"> stopping the nagios process.</span>
<span style="color: #ba2121; font-style: italic;"> """</span>
    <span style="color: #008000; font-weight: bold;">try</span>:
        subprocess<span style="color: #666666;">.</span>check_output([<span style="color: #ba2121;">"service"</span>, <span style="color: #ba2121;">"nagios3"</span>, <span style="color: #ba2121;">"reload"</span>],
                                stderr<span style="color: #666666;">=</span>subprocess<span style="color: #666666;">.</span>STDOUT)
    <span style="color: #008000; font-weight: bold;">except</span> subprocess<span style="color: #666666;">.</span>CalledProcessError <span style="color: #008000; font-weight: bold;">as</span> e:
        sys<span style="color: #666666;">.</span>stderr<span style="color: #666666;">.</span>write(<span style="color: #ba2121;">"FAILED RELOADING NAGIOS CONFIG</span><span style="color: #bb6622; font-weight: bold;">\n</span><span style="color: #ba2121;">"</span>)
        sys<span style="color: #666666;">.</span>stderr<span style="color: #666666;">.</span>write(e<span style="color: #666666;">.</span>output)
        sys<span style="color: #666666;">.</span>exit(<span style="color: #666666;">1</span>)</pre>
</div>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>When the script is run, the new computer shows up immediately in Nagios:
<img class="alignnone size-full wp-image-579" title="New Computer in Nagios - Pending" src="/wp-content/uploads/2012/09/nagios1.png" alt="" width="834" height="262" /></p>
<p>And within a few minutes everything looks OK!</p>
<p><img class="alignnone size-full wp-image-580" title="New Computer in Nagios - OK" src="/wp-content/uploads/2012/09/nagios2.png" alt="" width="841" height="267" /></p>
<p>This simple example shows how you can integrate Landscape within your existing infrastructure. The Landscape API allows you to reach all your Ubuntu infrastructure using simple API commands from python or the command line.</p>
<p>We’ve barely scratched the surface of what the API can do. Check out <a title="The API Documentation" href="https://landscape.canonical.com/static/doc/" target="_blank">the API Documentation</a> to learn more.</p>
<p>The complete script is available here: <a title="Sync Script" href="http://paste.ubuntu.com/1200590/" target="_blank">http://paste.ubuntu.com/1200590/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2012/09/13/landscape-with-nagios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Landscape Dedicated Server 11.07 Update</title>
		<link>http://blog.landscape.canonical.com/2012/03/02/landscape-dedicated-server-11-07-update/</link>
		<comments>http://blog.landscape.canonical.com/2012/03/02/landscape-dedicated-server-11-07-update/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 22:37:58 +0000</pubDate>
		<dc:creator>Federico Lucifredi</dc:creator>
				<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Release Announcement]]></category>
		<category><![CDATA[Release Notes]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=524</guid>
		<description><![CDATA[The Landscape Team is happy to announce the release of an update to Landscape Dedicated Server, the version of our Ubuntu Systems Management service deployed behind the firewall at customer sites. LDS 11.07.1 (11.07.20120217-2) aligns the Dedicated Server with updates recently introduced on http://landscape.canonical.com.  It includes support for the new AWS region in São Paulo [...]]]></description>
			<content:encoded><![CDATA[<p>The Landscape Team is happy to announce the release of an update to Landscape Dedicated Server, the version of our Ubuntu Systems Management service deployed behind the firewall at customer sites.</p>
<p>LDS 11.07.1 (11.07.20120217-2) aligns the Dedicated Server with updates recently introduced on <a title="Landscape" href="http://landscape.canonical.com" target="_blank">http://landscape.canonical.com</a>.  It includes support for the new AWS region in São Paulo (sa-east-1) and Ubuntu Oneiric (11.10) images, as well as a number of security fixes detailed in the <a title="Release Notes for Landscape Dedicated Server 11.07.1" href="https://help.landscape.canonical.com/LDS/ReleaseNotes11.07.20120217-2" target="_blank">release notes</a>.</p>
<p>The most noteworthy new feature is support for OpenStack as a custom EC2 compatible endpoint.  I was able to set up CanoniStack (our internal R&amp;D Cloud) as a cloud deployment target in my Landscape account and start launching instances from Landscape quicker than it is taking me to write about it &#8211; and it is all fronted in our standard cross-cloud interface in Landscape.</p>
<p>&nbsp;</p>
<p><div id="attachment_527" class="wp-caption alignnone" style="width: 460px"><a href="/wp-content/uploads/2012/03/CanoniStack-31.png"><img class="size-large wp-image-527 " title="OpenStack Cloud Images Launched by Landscape" src="/wp-content/uploads/2012/03/CanoniStack-31-1024x640.png" alt="Landscape + OpenStack" width="450" height="281" /></a><p class="wp-caption-text">Landscape launching two Oneiric instances on an OpenStack Cloud.</p></div></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2012/03/02/landscape-dedicated-server-11-07-update/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Landscape offline September 12th, 2011 from 15:00 UTC &#8211; 15:30 UTC</title>
		<link>http://blog.landscape.canonical.com/2011/08/10/title-landscape-offline-september-12th-2011-from-1500-utc-1530-utc/</link>
		<comments>http://blog.landscape.canonical.com/2011/08/10/title-landscape-offline-september-12th-2011-from-1500-utc-1530-utc/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 16:48:23 +0000</pubDate>
		<dc:creator>Stefan Stasik</dc:creator>
				<category><![CDATA[Notifications]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=509</guid>
		<description><![CDATA[We’re releasing a new version of Landscape on September 12th. While we roll-out the code to Landscape’s servers, we’ll have to take the service offline. Goes offline: 15:00 September 12th 2011 UTC Expected back online: 15:30 September 12th 2011 UTC Keep an eye on this blog after the release to find out what’s new! We’re [...]]]></description>
			<content:encoded><![CDATA[<p>We’re releasing a new version of Landscape on September 12th. While we roll-out the code to Landscape’s servers, we’ll have to take the service offline.</p>
<p>Goes offline: 15:00 September 12th 2011 UTC<br />
Expected back online: 15:30 September 12th 2011 UTC</p>
<p>Keep an eye on this blog after the release to find out what’s new!</p>
<p>We’re sorry for the downtime you’ll experience during the roll-out.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2011/08/10/title-landscape-offline-september-12th-2011-from-1500-utc-1530-utc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Landscape offline June 20th, 2011 from 15:00 UTC &#8211; 15:30 UTC</title>
		<link>http://blog.landscape.canonical.com/2011/05/31/landscape-offline-june-20th-2011-from-1500-utc-1530-utc/</link>
		<comments>http://blog.landscape.canonical.com/2011/05/31/landscape-offline-june-20th-2011-from-1500-utc-1530-utc/#comments</comments>
		<pubDate>Tue, 31 May 2011 08:22:36 +0000</pubDate>
		<dc:creator>Tom Haddon</dc:creator>
				<category><![CDATA[Notifications]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=494</guid>
		<description><![CDATA[We’re releasing a new version of Landscape on June 20th. While we roll-out the code to Landscape’s servers, we’ll have to take the service offline. Goes offline: 15:00 June 20th 2011 UTC Expected back online: 15:30 June 20th 2011 UTC Keep an eye on this blog after the release to find out what’s new! We’re sorry [...]]]></description>
			<content:encoded><![CDATA[<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<p>We’re releasing a new version of Landscape on June 20th. While we roll-out the code to Landscape’s servers, we’ll have to take the service offline.</p>
<p>Goes offline: 15:00 June 20th 2011 UTC<br />
Expected back online: 15:30 June 20th 2011 UTC</p>
<p>Keep an eye on this blog after the release to find out what’s new!</p>
<p>We’re sorry for the downtime you’ll experience during the roll-out.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2011/05/31/landscape-offline-june-20th-2011-from-1500-utc-1530-utc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Progress, redefined</title>
		<link>http://blog.landscape.canonical.com/2011/05/28/progress-redefined/</link>
		<comments>http://blog.landscape.canonical.com/2011/05/28/progress-redefined/#comments</comments>
		<pubDate>Sat, 28 May 2011 03:21:45 +0000</pubDate>
		<dc:creator>Sidnei da Silva</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Focus on Tech]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=484</guid>
		<description><![CDATA[One of the first tasks I worked on when I joined the Landscape team in early 2009 was adding a progress bar to the activity page, to give an overall indication on the progress of a set of common activities. The original idea was that this progress bar would update automatically as activities got delivered [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first tasks I worked on when I joined the Landscape team in early 2009 was adding a progress bar to the activity page, to give an overall indication on the progress of a set of common activities. The original idea was that this progress bar would update automatically as activities got delivered to computers and computers reported back on their progress.</p>
<p>However, not all things happen as planned, and for a long time users were confused by staring at said progress bar and waiting for it to update, which it never did. Well. Not anymore! With our latest rollout, which happened earlier this week, we&#8217;ve finally introduced <strong>live activity progress updates!</strong></p>
<p>I could write a thousand words about it, but I don&#8217;t think it would do justice to how amazing it is to see it in action. So I&#8217;ll let you see for yourself with a very short video (~1min long) demoing this nice feature (if you&#8217;re reading this post from an RSS reader, you might have to click through to see the video).</p>
<p><object width="450" height="278"><param name="movie" value="http://www.youtube.com/v/889t9suqlA0?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/889t9suqlA0?version=3" type="application/x-shockwave-flash" width="450" height="278" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>This is only one of the many user-focused changes we&#8217;ve been doing, and hopefully you&#8217;ll enjoy it as much as we do. Keep tuned for more updates.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2011/05/28/progress-redefined/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Landscape offline 01:00 &#8211; 01:30 UTC May 24th, 2011</title>
		<link>http://blog.landscape.canonical.com/2011/04/26/landscape-offline-0100-0130-utc-may-24th-2011/</link>
		<comments>http://blog.landscape.canonical.com/2011/04/26/landscape-offline-0100-0130-utc-may-24th-2011/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 15:42:35 +0000</pubDate>
		<dc:creator>Tom Haddon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.landscape.canonical.com/?p=481</guid>
		<description><![CDATA[We’re releasing a new version of Landscape on May 24th. While we roll-out the code to Landscape’s servers, we’ll have to take the service offline. Goes offline: 01:00 May 24th 2011 UTC Expected back online: 01:30 May 24th 2011 UTC Keep an eye on this blog after the release to find out what’s new! We’re [...]]]></description>
			<content:encoded><![CDATA[<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<p>We’re releasing a new version of Landscape on May 24th. While       we roll-out the code to Landscape’s servers, we’ll have to take the       service offline.</p>
<p><strong>Goes offline:</strong> 01:00 May 24th 2011 UTC<br />
<strong>Expected back online:</strong> 01:30 May 24th 2011 UTC</p>
<p>Keep an eye on this blog after the release to find out what’s new!</p>
<p>We’re sorry for the downtime you’ll experience during the roll-out.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.landscape.canonical.com/2011/04/26/landscape-offline-0100-0130-utc-may-24th-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
