Introduction

This is the baseline deployment recommendation we have for the LDS product using the Debian packages delivery mechanism. At a minimum, we have two machines:

  • a database server, running Ubuntu 12.04 LTS ("precise"), with Postgresql 9.1
  • an application server, also running Ubuntu 12.04 LTS ("precise"), hosting the Landscape services

Important points:

  • the APP server needs http access to usn.canonical.com in order to download the USN database and detect security updates. Without this, the available updates won't be distinguished between security related and regular updates

  • the APP server also needs http access to the public Ubuntu archives and changelogs.ubuntu.com, in order to update the hash-id-database files and detect new distribution releases. Without this, the release upgrade feature won't work

  • if the Cloud feature is going to be used, the APP server needs to be able to reach the cloud endpoint

This is a long document. Don't be scared. If you want a quick installation that just works, but doesn't scale to a large number of machines, then install the landscape-server-quickstart package.

Preparing for the installation

What you will need:

  • Ubuntu 12.04 LTS ("precise") server install media
  • Landscape Dedicated Server license file
  • Server X509 certificate and key, signed by a publicly known Certificate Authority, and issued for the FQDN hostname of the application server
  • sources.list line that gives access to the package repository that holds the LDS packages. It was sent to you via email for this Beta program.

    {i} Custom CAs can be used, but this is not documented here as it's considered an advanced topic. Administrators deploying custom CAs most likely know what needs to be done. In any case, this quick how-to may help: creating a simple CA and issuing a certificate

Installing the Database Server

After having installed the basic server profile of Ubuntu Server, we need to install the postgresql database and configure it for use by Landscape. Please follow these steps:

Install postgresql and required libraries

sudo apt-get install postgresql-9.1 python-apt postgresql-plpython-9.1

Create a superuser Landscape can use

Landscape needs a database superuser in order to create the lower privilege users it needs to perform routine tasks and access the data, as well as alter the database schema whenever needed:

sudo -u postgres createuser --createdb --createrole --superuser --pwprompt landscape_superuser
  • /!\ Use a strong password!

If this database is to be shared with other services, it is recommended that another cluster is created instead for those services (or for Landscape). Please refer to the Postgresql documentation in that case.

Setup Cloud Deck databases

Run the following commands:

  • sudo -u postgres createuser -D -R -S -P clouddeck. Choose a good password when prompted for it. We will need it again later on

  • sudo -u postgres createdb landscape-standalone-clouddeck-main

  • sudo -u postgres createdb landscape-standalone-clouddeck-account

Configure PostgreSQL

We now need to allow the application server to access this database server. Landscape uses several users for this access, so we need to allow them all. Edit /etc/postgresql/9.1/main/pg_hba.conf and add the following line to its end:

host all landscape,landscape_maintenance,landscape_superuser,clouddeck <IP-OF-APP> md5

Replace <IP-OF-APP> with the IP address of the application server, followed by /32. Alternatively, you can specify the network address using the CIDR notation. Some examples of valid values:

  • 192.168.122.199/32: the IP address of the APP server

  • 192.168.122.0/24: a network address

Now we need to allow network connections to the database. Edit /etc/postgresql/9.1/main/postgresql.conf and find the listen_addresses parameter, which is probably commented, and change it to:

listen_addresses = '*'

Finally, restart the database service:

sudo /etc/init.d/postgresql restart

It's strongly recommended to fine tune this postgresql installation according to the hardware of the server machine. This page has some tips. We recommend to at least take a look at the following parameters:

Installing the application server

The application server will host the following Landscape services:

  • application server
  • message server
  • ping server
  • job handler
  • async-frontend
  • combo loader
  • clouddeck services
  • api server
  • package upload service

Additionally, other services needed by Landscape will also be running on this machine, such as:

  • apache
  • rabbit-mq

Let's begin.

Adding the Landscape package archive and installing the package

As part of your LDS purchase, you should have gotten a URL pointing to a private archive which hosts the LDS packages. To access that archive, please follow the instructions on https://landscape.canonical.com/account/<youraccount>/how-to-get-dedicated, replacing <youraccount> with your Landscape account name. If you are using the new Landscape theme, you should see a link to this page on the left right after you login.

As a final step, please adjust permissions on that file:

sudo chmod 0640 /etc/apt/sources.list.d/landscape-dedicated-server.list
sudo chown root:landscape /etc/apt/sources.list.d/landscape-dedicated-server.list

If not done so already, please import the signing key for this archive:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key 4652B4E6
  • install the package. Note that it will complain about a missing license file:

sudo apt-get update
sudo apt-get install landscape-server rabbitmq-server apache2-mpm-worker

Install the license file

Copy the license file you received to /etc/landscape:

sudo cp license.txt /etc/landscape

Make sure it's readable by everybody, or at least the landscape user.

Configure rabbitmq

Just run the following commands, replacing <password> with a password of your choice. It will be needed later.

sudo rabbitmqctl add_user landscape <password>
sudo rabbitmqctl add_vhost landscape
sudo rabbitmqctl set_permissions -p landscape landscape ".*" ".*" ".*"

To make rabbitmq listen only on the loopback interface (127.0.0.1), please create the file /etc/rabbitmq/rabbitmq.conf with the following content:

NODE_IP_ADDRESS=127.0.0.1

Then restart it:

sudo /etc/init.d/rabbitmq-server restart

Bootstrap clouddeck

Cloud Deck is the new cloud infrastructure used by Landscape. Please see CloudDeck and CloudDeckQuickStart for details.

Let's configure its database access. Edit /etc/clouddeck/stores.cfg and change the following:

  • in the [main-store] section:

    • password: use the password for the clouddeck user created in the database server earlier

    • host: use the IP or hostname of the database server

    • database: set it to landscape-standalone-clouddeck-main

  • in the [account-store] section:

    • password: use the password for the clouddeck user created in the database server earlier

    • host: use the IP or hostname of the database server

    • database: set it to landscape-standalone-clouddeck-account

Now let's bootstrap these databases, which takes only a few seconds. Run the following command:

sudo clouddeck-schema /etc/clouddeck/stores.cfg

We want clouddeck to start at boot, so change /etc/default/clouddeck:

RUN="yes"

Finally, we need to create a service manager that Landscape can use. Below is the command to run and what its output looks like:

$ sudo clouddeck create-service-manager landscape | sed -e 's,access-key,service_access_key,;s,secret-key,service_secret_key,'
service_access_key = JAIW0A3IUC8JBNHM08F3
service_secret_key = 0ipXHWSsJqKK/YhCO2/BadL5fVTgwIJFeovh9zaS
  • {i} The sed bit is just to slightly change the names of the keywords that are returned by the clouddeck command to match what we need to use in the Landscape configuration file.

Copy and paste your resulting lines in the [clouddeck] section of the /etc/landscape/service.conf file. It will look like this:

[clouddeck]
service_access_key = JAIW0A3IUC8JBNHM08F3
service_secret_key = 0ipXHWSsJqKK/YhCO2/BadL5fVTgwIJFeovh9zaS
(...)

Configure database and broker access

We now need to make some configuration changes to the /etc/landscape/service.conf file to tell Landscape how to use some other services: Please make the following changes:

  • section [schema]:

    • change the value of store_user to the landscape super user we created above during the DB installation

    • add an entry for store_password with the password that was chosen in that same step

  • section [stores]:

    • host: the IP or hostname of the database server

    • port: if not the default Postgresql port (5432), specify the right one here

  • section [broker]:

    • replace the password value with the password chosen above when configuring rabbitmq

Run the Landscape setup script

This script will bootstrap the databases Landscape needs to work and setup the remaining of the configuration:

sudo setup-landscape-server
  • {i} Depending on the hardware, this may take several minutes to complete

Configure Landscape services and schema upgrades

We need to enable the Landscape services now. Please edit /etc/default/landscape-server and change the RUN_ALL line to yes:

# To run all Landscape services set this to "yes"
RUN_ALL="yes"
  • {i} If more performance and availability are needed out of LDS, it's possible to spread out the services amongst several machines. In that case, for example, one could run message servers in one machine, application servers in another one, etc.

The message, application and ping services can be configured to run multiple instances. If your hardware has several cores and enough memory (4Gb or more), running two or more of each will improve performance. To run multiple instances of a service, just set the value in the respective RUN_ line to the number of instances. For example, if you want to run two message servers, just set:

RUN_MSGSERVER="2"
  • {i} In order to take advantage of this multiple-instances setting, you need to configure some sort of load balancer or proxy. See the README.multiple-services file in the landscape-server package documentation directory for an example using Apache's proxy_loadbalancer module.

In that same file, the UPGRADE_SCHEMA option needs to be reviewed. If set to yes, whenever the package landscape-server is updated it will attempt to update the database schema too. It is a very convenient setting, but please think about the following before enabling it:

  • schema updates can take several minutes
  • if the package is updated while the database is offline, or unreachable, the update will fail
  • you should have a backup of the database before updating the package

Without this setting enabled, a package update might result in services that won't start anymore because of a needed schema change. In that case:

  • stop all the Landscape services
  • backup your database
  • run sudo setup-landscape-server on the application server. This will update the schema

  • start all Landscape services again

Webserver configuration

Landscape uses Apache to, among other things, redirect requests to each service and provide SSL support. The usual way to do this in Ubuntu is to create a Virtual Host for Landscape.

Below is a suggested configuration file that does just that. Install it as /etc/apache2/sites-available/landscape and change the following values:

  • @hostname@: the FQDN of the hostname the clients (browser and machines) will use to connect to LDS. This is what will be in the URL, and it needs to be resolvable via DNS. For example, lds.example.com

  • @certfile@: the full filesystem path to where the SSL certificate for this server is installed. For example, /etc/ssl/certs/landscape_server.pem

  • @keyfile@: the full filesystem path to where the corresponding private key of that certificate is installed. For example, /etc/ssl/private/landscape_server.key.

    /!\ Make sure the user apache runs as can read those files! Also, make sure the private key can only be read by root and that same apache user

<VirtualHost *:80>

    # This Hostname is the HTTP/1.1 hostname that users and Landscape clients will access
    # It must be the same as your SSL Certificate's CommonName
    # And the DNS Hostname for this machine
    # It is not recommended that you use an IP address here...
    ServerName @hostname@
    ServerAdmin webmaster@@hostname@
    ErrorLog /var/log/apache2/landscape.error-log
    CustomLog /var/log/apache2/landscape.access-log combined
    DocumentRoot /opt/canonical/landscape/canonical/landscape

    # Set a Via header in outbound requests to the proxy, so proxied apps can
    # know who the actual client is
    ProxyVia on
    ProxyTimeout 10

    <Directory "/">
      Options +Indexes
      Order deny,allow
      Allow from all
      ErrorDocument 403 /static/offline/unauthorized.html
      ErrorDocument 404 /static/offline/notfound.html
    </Directory>

    Alias /packages /opt/canonical/landscape/packages
    Alias /static /opt/canonical/landscape/canonical/static
    Alias /repository /var/lib/landscape/landscape-repository

    <Directory "/opt/canonical/landscape/packages">
        Order allow,deny
        Allow from all
    </Directory>
    <Location "/packages">
        Order allow,deny
        Allow from all
    </Location>
    <Location "/repository">
      Order deny,allow
      Deny from all
      ErrorDocument 403 default
      ErrorDocument 404 default
    </Location>
   <LocationMatch "/repository/[^/]+/[^/]+/(dists|pool)/.*">
     Allow from all
   </LocationMatch>
   <Location "/icons">
        Order allow,deny
        Allow from all
   </Location>
   <Location "/ping">
        Order allow,deny
        Allow from all
    </Location>

    <Location "/message-system">
        Order allow,deny
        Allow from all 
    </Location>

   <Location "/r">
      FileETag none
      ExpiresActive on
      ExpiresDefault "access plus 10 years"
      Header append Cache-Control "public"
   </Location>

    RewriteEngine On

    RewriteRule ^/r/([^/]+)/(.*) /$2 [L]

    RewriteRule ^/ping$ http://localhost:8070/ping [P]

    RewriteCond %{REQUEST_URI} !/server-status
    RewriteCond %{REQUEST_URI} !/icons
    RewriteCond %{REQUEST_URI} !/static
    RewriteCond %{REQUEST_URI} !/packages
    RewriteCond %{REQUEST_URI} !/repository
    RewriteCond %{REQUEST_URI} !/message-system

    # Replace the @hostname@ with the DNS hostname for this machine.
    # If you change the port number that Apache is providing SSL on, you must change the 
    # port number 443 here.
    RewriteRule ^/(.*) https://@hostname@:443/$1 [R=permanent]
</VirtualHost>

<VirtualHost *:443>
    ServerName @hostname@
    ServerAdmin webmaster@@hostname@

    ErrorLog /var/log/apache2/landscape.error-log
    CustomLog /var/log/apache2/landscape.access-log combined

    DocumentRoot /opt/canonical/landscape/canonical/landscape

    SSLEngine On
    SSLCertificateFile @certfile@
    SSLCertificateKeyFile @keyfile@
    # If you have either an SSLCertificateChainFile or, a self-signed CA signed certificate
    # uncomment the line below.
    # SSLCertificateChainFile /etc/ssl/certs/landscape_server_ca.crt

    # Try to keep this close to the storm timeout. Not less, maybe slightly
    # more
    ProxyTimeout 305

    <Directory "/">
      Options -Indexes
      Order deny,allow
      Allow from all
      ErrorDocument 403 /static/offline/unauthorized.html
      ErrorDocument 404 /static/offline/notfound.html
    </Directory>

    <Location "/ajax">
      Order allow,deny
      Allow from all
    </Location>

    Alias /config /opt/canonical/landscape/apacheroot
    Alias /hash-id-databases /var/lib/landscape/hash-id-databases

    ProxyRequests off
    <Proxy *>
       Order deny,allow
       Allow from all
       ErrorDocument 403 /static/offline/unauthorized.html
       ErrorDocument 500 /static/offline/exception.html
       ErrorDocument 502 /static/offline/unplanned-offline.html
       ErrorDocument 503 /static/offline/unplanned-offline.html
    </Proxy>

    ProxyPass /robots.txt !
    ProxyPass /favicon.ico !
    ProxyPass /static !

    ProxyPreserveHost on


   <Location "/r">
      FileETag none
      ExpiresActive on
      ExpiresDefault "access plus 10 years"
      Header append Cache-Control "public"
   </Location>

    RewriteEngine On

    RewriteRule ^/r/([^/]+)/(.*) /$2
    RewriteRule ^/.*\+\+.* / [F]

    # See /etc/landscape/service.conf for a description of all the
    # Landscape services and the ports they run on.
    # Replace the @hostname@ with the DNS hostname for this machine.
    # If you change the port number that Apache is providing SSL on, you must change the 
    # port number 443 here.
    RewriteRule ^/message-system http://localhost:8090/++vh++https:@hostname@:443/++/ [P,L]

    RewriteRule ^/ajax http://localhost:9090/ [P,L]
    RewriteRule ^/combo http://localhost:9070/ [P,L]
    RewriteRule ^/api http://localhost:9080/ [P,L]
    RewriteRule ^/attachment/(.*) http://localhost:8090/attachment/$1 [P,L]
    RewriteRule ^/cloud/(.*) http://localhost:8600/$1 [P,L]
    RewriteRule ^/upload/(.*) http://localhost:9100/$1 [P,L]

    RewriteCond %{REQUEST_URI} !/robots.txt
    RewriteCond %{REQUEST_URI} !/favicon.ico
    RewriteCond %{REQUEST_URI} !/static
    RewriteCond %{REQUEST_URI} !/config
    RewriteCond %{REQUEST_URI} !/hash-id-databases

    # Replace the @hostname@ with the DNS hostname for this machine.
    # If you change the port number that Apache is providing SSL on, you must change the 
    # port number 443 here.
    RewriteRule ^/(.*) http://localhost:8080/++vh++https:@hostname@:443/++/$1 [P]

    <Location /message-system>
      Order allow,deny
      Allow from all
    </Location>

    <Location />
        # Insert filter
        SetOutputFilter DEFLATE

        # Don't compress images or .debs
        SetEnvIfNoCase Request_URI \
        \.(?:gif|jpe?g|png|deb)$ no-gzip dont-vary

        # Make sure proxies don't deliver the wrong content
        Header append Vary User-Agent env=!dont-vary
    </Location>

</VirtualHost>

We now need to enable some modules:

for module in rewrite proxy_http ssl headers expires; do sudo a2enmod $module; done

Finally we can enable the new site:

sudo a2ensite landscape
sudo service apache2 reload

Start Landscape and Cloud Deck services

Just run the helper script lsctl:

sudo lsctl start

They may take a few seconds to start. After a while, list the running processes. You should see something like this (example with /etc/default/landscape-server configured to start two instances of the ping, app and message servers):

(...)
 5195 ?        S      0:00 /usr/bin/python /usr/bin/clouddeck-service /etc/clouddeck --logfile=(...)
 5202 ?        Sl     0:00 /usr/bin/python /usr/bin/clouddeck-poller /etc/clouddeck --logfile=(...)
 5211 ?        S      0:00 /usr/bin/python /usr/bin/clouddeck-ec2 /etc/clouddeck --logfile=(...)
 5264 ?        D      0:01 /usr/bin/python /usr/bin/twistd -y /opt/canonical/landscape/api (...)
 5281 ?        D      0:01 python /opt/canonical/landscape/landscape
 5292 ?        D      0:01 python /opt/canonical/landscape/landscape
 5338 ?        D      0:01 /usr/bin/python /usr/bin/twistd -y /opt/canonical/landscape/job-handler (...)
 5358 ?        D      0:01 python /opt/canonical/landscape/message-server
 5370 ?        D      0:01 python /opt/canonical/landscape/message-server
 5388 ?        R      0:01 /usr/bin/python /usr/bin/twistd -y /opt/canonical/landscape/pingserver (...)
 5400 ?        R      0:01 /usr/bin/python /usr/bin/twistd -y /opt/canonical/landscape/pingserver (...)
 5429 ?        R      0:01 /usr/bin/python /usr/bin/twistd -y /opt/canonical/landscape/combo-loader (...)
 5441 ?        Sl     0:00 /usr/bin/python /usr/bin/twistd -y /opt/canonical/landscape/async-frontend (...)

Setup first user

The first user that is created in LDS automatically becomes the administrator of the "standalone" account. To create it, please go to https://<servername> and, inside the login box, click on the "I don't have a login yet" link and fill in the requested information.

  • /!\ It's really unusual to have to change either the ping url or root url parameters. The root url parameter is calculated from the browser, i.e., whatever URL you used in your browser to see that page is going to be used. The ping url, if left blank (the default), is automatically derived from the root one.

Configuring the first client

On the client machine, after installing the landscape-client package, please run this command:

$ sudo landscape-config --computer-title "My First Computer" --account-name standalone --url https://<servername>/message-system --ping-url http://<servername>/ping

You can now accept your client in the Landscape UI, and it begins to upload data.

  • {i} If you configure an account password, the client will be automatically accepted when using that password.

Email alias

We recommend adding an alias for user landscape on your local environment, to ensure that important system emails get attention.

$ sudo vim /etc/aliases

Add a line landscape: <insert recipient's email address> to this file and rebuild your aliases

$ sudo /usr/bin/newaliases

LDS/RecommendedDeployment12.06Beta3 (last edited 2012-07-02 14:47:29 by ahasenack)