<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Filip Pytloun — systems, agents &amp; the work between</title><link href="https://fpy.cz/" rel="alternate"/><link href="https://fpy.cz/feeds/all.atom.xml" rel="self"/><id>https://fpy.cz/</id><updated>2016-08-16T17:22:19+02:00</updated><entry><title>Distribution packages in Docker world</title><link href="https://fpy.cz/packages-in-docker-world.html" rel="alternate"/><published>2016-08-16T17:22:19+02:00</published><updated>2016-08-16T17:22:19+02:00</updated><author><name>Filip Pytloun</name></author><id>tag:fpy.cz,2016-08-16:/packages-in-docker-world.html</id><summary type="html">&lt;div class="section" id="or-why-using-them-is-still-a-good-idea"&gt;
&lt;h2&gt;..or why using them is still a good idea&lt;/h2&gt;
&lt;div class="section" id="distribution-packages"&gt;
&lt;h3&gt;Distribution packages&lt;/h3&gt;
&lt;p&gt;Software and it's dependencies maintained by Linux distribution vendor (Debian
community, Canonical, RedHat, etc.), delivered by packages (DEB, RPM, ..)
usually provided using package repositories (packages are signed so their
authenticity is verified on download).&lt;/p&gt;
&lt;p&gt;These packages actually forms stable …&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="or-why-using-them-is-still-a-good-idea"&gt;
&lt;h2&gt;..or why using them is still a good idea&lt;/h2&gt;
&lt;div class="section" id="distribution-packages"&gt;
&lt;h3&gt;Distribution packages&lt;/h3&gt;
&lt;p&gt;Software and it's dependencies maintained by Linux distribution vendor (Debian
community, Canonical, RedHat, etc.), delivered by packages (DEB, RPM, ..)
usually provided using package repositories (packages are signed so their
authenticity is verified on download).&lt;/p&gt;
&lt;p&gt;These packages actually forms stable Linux distribution because they are
tested altogether. Especially Debian has great CI infrastructure where
packaged software can be tested in case of dependency update.&lt;/p&gt;
&lt;p&gt;As an example, let's take Python application which doesn't have much
dependencies and generate dependency graph:&lt;/p&gt;
&lt;img alt="Dependency graph for an Aptly publisher application" src="images/aptly-publisher-deptree.png" /&gt;
&lt;p&gt;As you can see, you never deliver just application, you always deliver at
least some dependencies, dependencies of dependencies and so on, including
essential C libraries (eg. libssl in this example).&lt;/p&gt;
&lt;blockquote&gt;
&lt;em&gt;If anyone tells you that Docker is only about installing and running
single application and base distribution doesn't matter.. don't belive
it as he's only another naive utopist :-)&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;At the moment there's 860 packages in Debian repositories which directly
depends on libssl and 404 packages which depends on python-requests.&lt;/p&gt;
&lt;p&gt;And distribution maintainers and developers are here to ensure that update of
libraries like python-requests or libssl won't break anything.
Beside of that they are taking care of distribution purity, ensuring that
every package has documentation, every binary has a man page, that copyright
and license file is in place and that user understands what he is going to
install.
Again, especially Debian is very strict on this and has great set of pedantic
tests to ensure everything is correct. Check resources at
&lt;a class="reference external" href="https://qa.debian.org"&gt;https://qa.debian.org&lt;/a&gt;, especially &lt;a class="reference external" href="https://lintian.debian.org"&gt;https://lintian.debian.org&lt;/a&gt; if you don't
belive me :-)&lt;/p&gt;
&lt;div class="section" id="cons"&gt;
&lt;h4&gt;Cons&lt;/h4&gt;
&lt;p&gt;Now to the bad things..&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;There is and will always be software which is not packaged for your
distribution&lt;ul&gt;
&lt;li&gt;so yes, you need to teach people how to make packages&lt;/li&gt;
&lt;li&gt;and have some CI and repository management&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stable version of your distribution means older versions of software&lt;ul&gt;
&lt;li&gt;but you can run Debian testing or unstable which contains up-to-date
software and this can be especially useful in Docker world where you can
build image based on debian:unstable running just single up-to-date
application&lt;/li&gt;
&lt;li&gt;or you can use your CI and repository management to make backports, that
way you are basically creating your own Linux distribution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Distribution vendors also make mistakes&lt;ul&gt;
&lt;li&gt;so their minor update of single package can ruin your environment&lt;/li&gt;
&lt;li&gt;sometimes you need to fix something and don't wait for upstream&lt;/li&gt;
&lt;li&gt;so again, you need your own repository management and testing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sometimes you need to run multiple versions (or series) of some software&lt;ul&gt;
&lt;li&gt;this can be done by repository components (eg. by OpenStack release -
kilo, liberty, mitaka)&lt;/li&gt;
&lt;li&gt;or by prefix in package names (eg. python-, python3-)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="docker"&gt;
&lt;h3&gt;Docker&lt;/h3&gt;
&lt;p&gt;First of all it's not true that container == Docker. Containers existed sooner
than Docker (eg. LXC, OpenVZ) and was about running OS userspace (so using
host's kernel) in very lightweight sort-of virtualization (far comparable with
Xen paravirtualization).&lt;/p&gt;
&lt;p&gt;Then came docker with tooling and essential thoughts about container
management:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;isolation done by facilities provided by Linux kernel - cgroups and
namespaces, similar as LXC does&lt;/li&gt;
&lt;li&gt;images built using Dockerfile, distributed using private Docker registry or
public Dockerhub&lt;/li&gt;
&lt;li&gt;container should run single application&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This application focus brings many advantages over VM world:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;complete isolation of individual pieces (applications)&lt;/li&gt;
&lt;li&gt;much faster deployment (images are just ready to go)&lt;/li&gt;
&lt;li&gt;easier rolling updates and management (scaling up/down, updating by spinning
up new containers and just re-routing traffic and many new easy-to-be-done
options)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The biggest deal (beside of orchestration of containers deployment which can
be solved by tools like Kubernetes, Docker Swarm, etc.) which we are going to
talk about is creation of Docker images.&lt;/p&gt;
&lt;p&gt;Most Dockerfiles are similar to shell scripts, with structure like this:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;use base debian/centos/whatever image&lt;/li&gt;
&lt;li&gt;setup additional repositories if needed&lt;/li&gt;
&lt;li&gt;install Python, Go or programming language of one's choice&lt;/li&gt;
&lt;li&gt;install software using Pip or whatever management one's programming language
offers&lt;/li&gt;
&lt;li&gt;define entrypoint - application binary itself or shell script as a wrapper
that will for example:&lt;ul&gt;
&lt;li&gt;generate configuration file using ENV variables it obtained on container
launch (eg. mysql root password)&lt;/li&gt;
&lt;li&gt;do whatever preparations app needs to run (eg. create missing directories
on volume)&lt;/li&gt;
&lt;li&gt;finally launch application&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!--  --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Does it remind you something? Déjà vu or maybe some scary memories of
childhood? Didn't we already solve this once using configuration
management..
SaltStack, Puppet, Ansible? Why are we going to make a step backward to
shell scripts?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Fortunately it's possible to do this using your existing configuration
management, see for example &lt;a class="reference external" href="https://github.com/tcpcloud/docker-salt"&gt;docker-salt&lt;/a&gt; project but back to our topic.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That way, developers can create docker images easily, in similar manner they
are using for example Python's virtualenvs for local development. They can
install anything, any version in any way, no restrictions. A dev's paradise.
And they can upload final image so anyone can download and use it and it will
work just in the same way.&lt;/p&gt;
&lt;p&gt;But experienced sysadmin will surely ask some questions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;base image is comming from Dockerhub - who made that image, is it
trustworthy? Is it cryptographically signed and signature verified on
download?&lt;/li&gt;
&lt;li&gt;core libraries (Python, dev libraries, possibly more) are comming from
upstream distribution - how do I quickly patch all images in case of
critical security issue in libssl?&lt;/li&gt;
&lt;li&gt;application and it's dependencies are comming from Pypi - again, is it
trustworthy source? Are all these packages signed and signature verified?&lt;/li&gt;
&lt;li&gt;how can I be sure that critical security issue in dependency (eg. urllib) is
fixed and developers just didn't blindly lock it's version using
&lt;tt class="docutils literal"&gt;requirements.txt&lt;/tt&gt;?&lt;/li&gt;
&lt;li&gt;now we need to maintain multiple completely different ecosystems in case we
are going to keep some &amp;quot;legacy&amp;quot; environments running VMs/bare-metal&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And surely he will never deploy image from public dockerhub into production to
avoid ending up like when &lt;a class="reference external" href="https://www.youtube.com/watch?v=PivpCKEiQOQ"&gt;Hitler uses Docker&lt;/a&gt; :-)&lt;/p&gt;
&lt;p&gt;So it's clear there must be rules and defined workflows.
Docker isn't package management tool - most people think they will just
replace distribution packages by Docker but they will replace well-tested
stable, security updated distribution packages by something similar to &lt;tt class="docutils literal"&gt;curl
install.sh | sudo bash&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;But fortunately there's a solution - let Docker be &lt;strong&gt;revolutionary&lt;/strong&gt; for
developer use but take it &lt;strong&gt;evolutionary&lt;/strong&gt; for production.
Keep using distribution packages and just extend your workflows and repository
management to cover build of docker images.&lt;/p&gt;
&lt;p&gt;It will bring following advantages:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Repository management remains source of truth for versions going to be
installed&lt;ul&gt;
&lt;li&gt;when it's snapshot or environment-based you can always return to stable
set of packages, alter only versions you need (eg. security fixes)&lt;/li&gt;
&lt;li&gt;keeps still the same testing and QA process (on repository level), just
extending it to use Docker images for infrastructure testing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Image builds are reproducable (per-environment repository locks versions)
so you can make a small change in image without risk of being stucked on
new version of upstream dependency, breaking up your app&lt;/li&gt;
&lt;li&gt;By image creation date and snapshot of repository, you can easily tell which
images needs update after critical security fix of package xyz&lt;/li&gt;
&lt;li&gt;Build entirely from secure, trusted source (image build should have no
Internet access except for package repository, which is rule that applies
for package builds as well)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="repository-management"&gt;
&lt;h3&gt;Repository management&lt;/h3&gt;
&lt;p&gt;So my advice is to have Repository management as a core component of all your
workflows.&lt;/p&gt;
&lt;p&gt;For Debian, you can use &lt;a class="reference external" href="https://www.aptly.info/"&gt;Aptly&lt;/a&gt;, for RHEL-based distributions there's Pulp
which works in a very similar way.&lt;/p&gt;
&lt;p&gt;Simple workflow can consist of 3 environments (but there can be more depending
on company's use-cases).&lt;/p&gt;
&lt;img alt="Continuous integration pipeline diagram" src="images/ci_pipeline.png" /&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;nightly&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;up-to-date mirrors of upstream and 3rd party APT repositories&lt;/li&gt;
&lt;li&gt;latest builds of your packages&lt;/li&gt;
&lt;li&gt;automated integration tests run against this environment&lt;/li&gt;
&lt;li&gt;nightly builds of docker images&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;testing&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;promoted packages from nightly that passed automated testing&lt;/li&gt;
&lt;li&gt;base for staging environments where manual testing is done&lt;/li&gt;
&lt;li&gt;testing builds of docker images&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stable&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;source for production updates and build of production docker images&lt;/li&gt;
&lt;li&gt;QA approves promotion from testing&lt;/li&gt;
&lt;li&gt;stable builds of docker images&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This workflow covers packages from all sources:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;upstream distribution packages (eg. mirror of Debian repository)&lt;/li&gt;
&lt;li&gt;3rd party repositories (various Launchpad PPAs, 3rd party vendors)&lt;/li&gt;
&lt;li&gt;custom packages including:&lt;ul&gt;
&lt;li&gt;company's software&lt;/li&gt;
&lt;li&gt;additional packages&lt;/li&gt;
&lt;li&gt;backports and fixes of upstream packages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When using &lt;a class="reference external" href="https://www.aptly.info/"&gt;Aptly&lt;/a&gt;, you can automate these workflows using it's REST API. This
can be done by re-using &lt;a class="reference external" href="https://github.com/tcpcloud/python-aptly"&gt;aptly-publisher&lt;/a&gt; which is CLI tool for management of
&lt;a class="reference external" href="https://www.aptly.info/"&gt;Aptly&lt;/a&gt; publishes and designed for workflows similar to one described in these
paragraphs.&lt;/p&gt;
&lt;img alt="Aptly publisher deployment diagram" src="images/aptly-publisher.png" /&gt;
&lt;p&gt;This way, your private Docker registry will always reflect state of your
packages repository. You can always deploy up-to-date &lt;tt class="docutils literal"&gt;myimage:stable&lt;/tt&gt; or
you can &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;apt-get&lt;/span&gt; install myapp&lt;/tt&gt; on VM or bare-metal and you will get the
same result.
You are still maintaining software in the same way for all ecosystems (no
matter if it's container, Docker, VM or bare-metal) as you did before but wich
much easier deployment and integration testing thanks to advantages of Docker.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="docker"/><category term="debian"/><category term="packaging"/></entry><entry><title>Jabber anti-spam</title><link href="https://fpy.cz/jabber-anti-spam.html" rel="alternate"/><published>2016-01-10T17:44:43+01:00</published><updated>2016-01-10T17:44:43+01:00</updated><author><name>Filip Pytloun</name></author><id>tag:fpy.cz,2016-01-10:/jabber-anti-spam.html</id><summary type="html">&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;There's no anti-spam mechanism in XMPP protocol so there's limited options one
can do to avoid spam.&lt;/p&gt;
&lt;div class="section" id="server-side"&gt;
&lt;h3&gt;Server-side&lt;/h3&gt;
&lt;p&gt;Protect registration against automated spam account creation.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;disable in-band registration completely&lt;ul&gt;
&lt;li&gt;and create accounts different way&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;or enable captcha during registration&lt;ul&gt;
&lt;li&gt;which may not be enough&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There's currently no more servers …&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;There's no anti-spam mechanism in XMPP protocol so there's limited options one
can do to avoid spam.&lt;/p&gt;
&lt;div class="section" id="server-side"&gt;
&lt;h3&gt;Server-side&lt;/h3&gt;
&lt;p&gt;Protect registration against automated spam account creation.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;disable in-band registration completely&lt;ul&gt;
&lt;li&gt;and create accounts different way&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;or enable captcha during registration&lt;ul&gt;
&lt;li&gt;which may not be enough&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There's currently no more servers can do to protect users from receiving spam.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="client-side"&gt;
&lt;h3&gt;Client-side&lt;/h3&gt;
&lt;p&gt;Only option is to block messages from users not in roster. This works pretty
well but what matters is implementation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;use client which can block non-roster users by feature (eg. Psi)&lt;ul&gt;
&lt;li&gt;it's easy to setup, just one checkbox&lt;/li&gt;
&lt;li&gt;but this blocking will not work for other clients, eg. when using mobile
client&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;use server-side privacy lists, &lt;a class="reference external" href="https://xmpp.org/extensions/xep-0016.html"&gt;XEP-0016&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="setting-privacy-lists"&gt;
&lt;h2&gt;Setting privacy lists&lt;/h2&gt;
&lt;p&gt;Filtering using privacy lists is simple and works seamlessly for all clients.&lt;/p&gt;
&lt;p&gt;This howto will describe how to setup privacy lists to block messages from
contacts not in roster. Screenshots are from Gajim, but any client supporting
XEP-0016 should be able to define these rules in a similar way.&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;Open &lt;em&gt;Actions -&amp;gt; Advanced -&amp;gt; Edit Privacy Lists&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Edit current privacy list (one should already exist), ensure it's active
for this session and active on each startup.&lt;/p&gt;
&lt;img alt="Gajim privacy list settings" src="/images/privacy-lists.png" /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Add rules with order 0 (rules are ordered from lower to higher) for each
MUC domain, otherwise group chats will not work&lt;/p&gt;
&lt;img alt="Gajim rule allowing messages from a group chat domain" src="/images/allow-muc.png" /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Add deny rule with highest order (eg. 5). Only messages are blocked,
subscribe requests are still allowed&lt;/p&gt;
&lt;img alt="Gajim rule blocking messages from contacts outside the roster" src="/images/deny-unsubscribed.png" /&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="jabber"/></entry><entry><title>Using LXC</title><link href="https://fpy.cz/using-lxc.html" rel="alternate"/><published>2015-07-30T17:35:55+02:00</published><updated>2015-07-30T17:35:55+02:00</updated><author><name>Filip Pytloun</name></author><id>tag:fpy.cz,2015-07-30:/using-lxc.html</id><summary type="html">&lt;div class="section" id="intro"&gt;
&lt;h2&gt;Intro&lt;/h2&gt;
&lt;blockquote&gt;
Containers are insulated areas inside a system, which have their own namespace
for filesystem, network, PID, IPC, CPU and memory allocation and which can be
created using the Control Group and Namespace features included in the Linux
kernel.&lt;/blockquote&gt;
&lt;div class="section" id="docker-vs-lxc"&gt;
&lt;h3&gt;Docker vs. LXC&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The idea behind Docker is to reduce a …&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="intro"&gt;
&lt;h2&gt;Intro&lt;/h2&gt;
&lt;blockquote&gt;
Containers are insulated areas inside a system, which have their own namespace
for filesystem, network, PID, IPC, CPU and memory allocation and which can be
created using the Control Group and Namespace features included in the Linux
kernel.&lt;/blockquote&gt;
&lt;div class="section" id="docker-vs-lxc"&gt;
&lt;h3&gt;Docker vs. LXC&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The idea behind Docker is to reduce a container as much as possible to a single process and then manage that through Docker. This adds significant complexity. The main problem with this approach is you can't wish the OS away and the vast majority of apps and tools expect a multi process environment and support for things like cron, logging, ssh, daemons and with Docker since you have none of this you have do everything via Docker from basic app configuration to deployment, networking, storage and orchestration.&lt;/p&gt;
&lt;p&gt;LXC sidesteps that with a normal OS environment and is thus immediately and cleanly compatible all the apps and tools and any management and orchestration layers and be a drop in replacement for VMs.&lt;/p&gt;
&lt;p&gt;Beyond that Docker uses layers and disables storage persistence. LXC supports layers with aufs, overlayfs and has wide support for COW cloning and snapshots with btrfs, ZFS, LVM Thin and leaves their use of these to user choice. Separating storage is a simple bind mount to the host or another container for users who choose to do so.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="text-right"&gt;-- source: &lt;a class="reference external" href="https://www.flockport.com/lxc-vs-docker/"&gt;flockport.com&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="install-lxc"&gt;
&lt;h2&gt;Install lxc&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;lxc
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="sudo"&gt;
&lt;h3&gt;Sudo&lt;/h3&gt;
&lt;p&gt;To be able to execute lxc commands as root without password, you need to
configure sudo.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;  ALL=(root) NOPASSWD: /usr/bin/lxc-*&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/sudoers.d/&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="setup-network"&gt;
&lt;h3&gt;Setup network&lt;/h3&gt;
&lt;div class="section" id="nat"&gt;
&lt;h4&gt;NAT&lt;/h4&gt;
&lt;p&gt;Probably best option when you are using laptop and moving between various
networks.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;First install &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bridge-utils&lt;/span&gt;&lt;/tt&gt; and DHCP server (optional)&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
apt-get install bridge-utils isc-dhcp-server
&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;Configure &lt;tt class="docutils literal"&gt;/etc/network/interfaces&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
auto br0
iface br0 inet static
   address 172.20.0.1
   netmask 255.255.255.0
   bridge_stp off
   bridge_maxwait 5
   pre-up  /sbin/brctl addbr br0
   post-up /sbin/brctl setfd br0 0
   post-down /sbin/brctl delbr br0
   post-up /sbin/iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
   post-up /sbin/iptables -A FORWARD -i br0 -o wlan0 -j ACCEPT
   post-up /sbin/iptables -A FORWARD -i wlan0 -o br0 -j ACCEPT
   post-down /sbin/iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE
   post-down /sbin/iptables -D FORWARD -i br0 -o wlan0 -j ACCEPT
   post-down /sbin/iptables -D FORWARD -i wlan0 -o br0 -j ACCEPT
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;That was a little bit longer, replace &lt;tt class="docutils literal"&gt;wlan0&lt;/tt&gt; by your network primary interface.
Address and netmask defines your new network. Choose something that won't be
in collision with real networks that you use.&lt;/p&gt;
&lt;p&gt;You also need to enable IP forwarding, ensure you have following line in /etc/sysctl.conf:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
net.ipv4.ip_forward=1
&lt;/pre&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;And reload sysctl&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sysctl&lt;span class="w"&gt; &lt;/span&gt;-p
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Bring up network interface&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ifup&lt;span class="w"&gt; &lt;/span&gt;br0
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;You also need to setup DHCP server so your containers will get IP address
automatically.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Edit &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/etc/default/isc-dhcp-server&lt;/span&gt;&lt;/tt&gt; and set interfaces to listen on&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;INTERFACES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;br0&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Edit &lt;tt class="docutils literal"&gt;/etc/dhcp/dhcpd.conf&lt;/tt&gt; and setup your subnet&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
subnet 172.20.0.0 netmask 255.255.255.0 {
    range 172.20.0.10 172.20.0.100;
    option routers 172.20.0.1;
    option domain-name &amp;quot;lxc.hydra&amp;quot;;
    option domain-name-servers 8.8.4.4, 8.8.8.8;
}
&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;Finally start dhcpd&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;service&lt;span class="w"&gt; &lt;/span&gt;isc-dhcp-server&lt;span class="w"&gt; &lt;/span&gt;restart
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;And last step, edit &lt;tt class="docutils literal"&gt;/etc/lxc/default.conf&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="create-container"&gt;
&lt;h2&gt;Create container&lt;/h2&gt;
&lt;div class="section" id="debian"&gt;
&lt;h3&gt;Debian&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-create&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;my_container&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;debian
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="ubuntu"&gt;
&lt;h3&gt;Ubuntu&lt;/h3&gt;
&lt;p&gt;To bootstrap Ubuntu container on Debian, you need to install ubuntu keyring
first.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;ubuntu-archive-keyring
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-create&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;ubuntu_container&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;ubuntu
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="container-management"&gt;
&lt;h2&gt;Container management&lt;/h2&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;List containers&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-ls&lt;span class="w"&gt; &lt;/span&gt;-f
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Get container informations&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-info&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;my_container
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Start container (add &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-d&lt;/span&gt;&lt;/tt&gt; parameter to run as daemon)&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-start&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;my_container
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Stop running container&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-stop&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;my_container
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Destroy container&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-destroy&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;my_container
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Enter root shell within container&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-attach&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;ubuntu
&lt;span class="c1"&gt;# Or enter console&lt;/span&gt;
sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-console&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;ubuntu
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Execute command inside container&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lxc-attach&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;ubuntu&lt;span class="w"&gt; &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;hostname
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="section" id="advanced-usage"&gt;
&lt;h3&gt;Advanced usage&lt;/h3&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Create container on LVM (without &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--lvname&lt;/span&gt;&lt;/tt&gt; LV name will be same as container)&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;lxc-create&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;debian&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;debian&lt;span class="w"&gt; &lt;/span&gt;-B&lt;span class="w"&gt; &lt;/span&gt;lvm&lt;span class="w"&gt; &lt;/span&gt;--vgname&lt;span class="w"&gt; &lt;/span&gt;vg0&lt;span class="w"&gt; &lt;/span&gt;--lvname&lt;span class="w"&gt; &lt;/span&gt;lxc_debian
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="reference"&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://linuxcontainers.org/"&gt;https://linuxcontainers.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.docker.com/"&gt;https://www.docker.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.flockport.com/lxc-vs-docker/"&gt;https://www.flockport.com/lxc-vs-docker/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="virtualization"/></entry><entry><title>Using libvirt and KVM</title><link href="https://fpy.cz/using-libvirt-and-kvm.html" rel="alternate"/><published>2015-07-27T17:35:55+02:00</published><updated>2015-07-27T17:35:55+02:00</updated><author><name>Filip Pytloun</name></author><id>tag:fpy.cz,2015-07-27:/using-libvirt-and-kvm.html</id><summary type="html">&lt;div class="section" id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Install required packages&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;qemu-kvm&lt;span class="w"&gt; &lt;/span&gt;libvirt-bin&lt;span class="w"&gt; &lt;/span&gt;bridge-utils&lt;span class="w"&gt; &lt;/span&gt;virtinst
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Setup &lt;tt class="docutils literal"&gt;/etc/network/interfaces&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
iface eth0 inet manual

auto br0
iface br0 inet static
    bridge_interfaces eth0
    bridge_stp off
    bridge_maxwait 5
    .. address, netmask, etc.
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Try to put &lt;tt class="docutils literal"&gt;br0&lt;/tt&gt; interface up or reboot&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;brctl&lt;span class="w"&gt; &lt;/span&gt;addbr&lt;span class="w"&gt; &lt;/span&gt;br0
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="deploy-instance"&gt;
&lt;h2&gt;Deploy instance&lt;/h2&gt;
&lt;p&gt;Now you have more …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Install required packages&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;qemu-kvm&lt;span class="w"&gt; &lt;/span&gt;libvirt-bin&lt;span class="w"&gt; &lt;/span&gt;bridge-utils&lt;span class="w"&gt; &lt;/span&gt;virtinst
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Setup &lt;tt class="docutils literal"&gt;/etc/network/interfaces&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
iface eth0 inet manual

auto br0
iface br0 inet static
    bridge_interfaces eth0
    bridge_stp off
    bridge_maxwait 5
    .. address, netmask, etc.
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Try to put &lt;tt class="docutils literal"&gt;br0&lt;/tt&gt; interface up or reboot&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;brctl&lt;span class="w"&gt; &lt;/span&gt;addbr&lt;span class="w"&gt; &lt;/span&gt;br0
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="deploy-instance"&gt;
&lt;h2&gt;Deploy instance&lt;/h2&gt;
&lt;p&gt;Now you have more options&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;deploy from custom image&lt;/li&gt;
&lt;li&gt;deploy clean Ubuntu using &lt;cite&gt;ubuntu-vm-builder&lt;/cite&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="section" id="ubuntu-vm-builder"&gt;
&lt;h3&gt;Ubuntu VM builder&lt;/h3&gt;
&lt;div class="admonition attention"&gt;
&lt;p class="first admonition-title"&gt;Attention!&lt;/p&gt;
&lt;p class="last"&gt;Untested&lt;/p&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;ubuntu-vm-builder
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ubuntu-vm-builder&lt;span class="w"&gt; &lt;/span&gt;kvm&lt;span class="w"&gt; &lt;/span&gt;trusty&lt;span class="w"&gt; &lt;/span&gt;--rootsize&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--domain&lt;span class="w"&gt; &lt;/span&gt;cfg01&lt;span class="w"&gt; &lt;/span&gt;--dest&lt;span class="w"&gt; &lt;/span&gt;cfg01
--hostname&lt;span class="w"&gt; &lt;/span&gt;cfg01&lt;span class="w"&gt; &lt;/span&gt;--arch&lt;span class="w"&gt; &lt;/span&gt;amd64&lt;span class="w"&gt; &lt;/span&gt;--mem&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--ip&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;172&lt;/span&gt;.19.5.30&lt;span class="w"&gt; &lt;/span&gt;--mask&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;.255.255.0
--net&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;172&lt;/span&gt;.19.0.0&lt;span class="w"&gt; &lt;/span&gt;--gw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;172&lt;/span&gt;.19.5.0&lt;span class="w"&gt; &lt;/span&gt;--dns&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;172&lt;/span&gt;.19.0.1&lt;span class="w"&gt; &lt;/span&gt;--libvirt&lt;span class="w"&gt; &lt;/span&gt;qemu:///system
--addpkg&lt;span class="w"&gt; &lt;/span&gt;openssh-server&lt;span class="w"&gt; &lt;/span&gt;--addpkg&lt;span class="w"&gt; &lt;/span&gt;acpid&lt;span class="w"&gt; &lt;/span&gt;--addpkg&lt;span class="w"&gt; &lt;/span&gt;vim-nox&lt;span class="w"&gt; &lt;/span&gt;--components
&lt;span class="s2"&gt;&amp;quot;main,universe&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="boot-from-image"&gt;
&lt;h3&gt;Boot from image&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;virtinst
&lt;/pre&gt;&lt;/div&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Get image and prepare image for guest (you can use overlay image instead)&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/var/lib/libvirt/images
wget&lt;span class="w"&gt; &lt;/span&gt;http://apt.cloudlab.cz/images/ubuntu-14-04-x64-1437659147.qcow2
cp&lt;span class="w"&gt; &lt;/span&gt;ubuntu-14-04-x64-1437659147.qcow2&lt;span class="w"&gt; &lt;/span&gt;cfg01.qcow2
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Install guest&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;virt-install&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;cfg01&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--ram&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--vcpus&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--accelerate&lt;span class="w"&gt; &lt;/span&gt;--network&lt;span class="w"&gt; &lt;/span&gt;bridge:br0&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--disk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/lib/libvirt/images/cfg01.qcow2,bus&lt;span class="o"&gt;=&lt;/span&gt;virtio,cache&lt;span class="o"&gt;=&lt;/span&gt;none&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--boot&lt;span class="w"&gt; &lt;/span&gt;hd&lt;span class="w"&gt; &lt;/span&gt;--vnc&lt;span class="w"&gt; &lt;/span&gt;--noreboot&lt;span class="w"&gt; &lt;/span&gt;--autostart
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="section" id="using-overlay-image"&gt;
&lt;h4&gt;Using overlay image&lt;/h4&gt;
&lt;p&gt;To save disk space, you can use overlay image instead of copying original
image for each instance.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;qemu-img&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;qcow2&lt;span class="w"&gt; &lt;/span&gt;-b&lt;span class="w"&gt; &lt;/span&gt;ubuntu-14-04-x64-1437659147.qcow2&lt;span class="w"&gt; &lt;/span&gt;cfg01.ovl
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then simply use &lt;tt class="docutils literal"&gt;*.ovl&lt;/tt&gt; for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--disk&lt;/span&gt;&lt;/tt&gt; parameter of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;virt-install&lt;/span&gt;&lt;/tt&gt; command.&lt;/p&gt;
&lt;div class="admonition attention"&gt;
&lt;p class="first admonition-title"&gt;Attention!&lt;/p&gt;
&lt;p class="last"&gt;Don't ever touch original image&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="cloud-init-configuration"&gt;
&lt;h3&gt;Cloud-init configuration&lt;/h3&gt;
&lt;p&gt;To use cloud-init with libvirt, you need to provide meta-data and user-data
somehow. There are multiple data sources that cloud-init expects, the simplest
way is probably to generate configuration iso and attach it to instance cdrom.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Install dependencies&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;genisoimage
curl&lt;span class="w"&gt; &lt;/span&gt;-q&lt;span class="w"&gt; &lt;/span&gt;https://raw.githubusercontent.com/larsks/virt-utils/master/create-config-drive&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;s,/bin/sh,/bin/bash,g&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;create-config-drive
chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;create-config-drive
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Prepare userdata file, eg. &lt;tt class="docutils literal"&gt;userdata.sh&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;

sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/iface\ eth0\ inet\ dhcp/d&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/network/interfaces
cat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; /etc/network/interfaces&lt;/span&gt;
&lt;span class="s"&gt;iface eth0 inet static&lt;/span&gt;
&lt;span class="s"&gt;  address 172.19.5.101&lt;/span&gt;
&lt;span class="s"&gt;  netmask 255.255.255.0&lt;/span&gt;
&lt;span class="s"&gt;  gateway 172.19.5.254&lt;/span&gt;
&lt;span class="s"&gt;  dns-nameservers 172.19.0.1&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;

ifdown&lt;span class="w"&gt; &lt;/span&gt;eth0&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ifup&lt;span class="w"&gt; &lt;/span&gt;eth0

&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;id: test1.int.cloudlab.cz&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/salt/minion.d/minion.conf
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;master: 172.19.5.30&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/salt/minion.d/minion.conf
service&lt;span class="w"&gt; &lt;/span&gt;salt-minion&lt;span class="w"&gt; &lt;/span&gt;restart

salt-call&lt;span class="w"&gt; &lt;/span&gt;state.highstate
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Generate configuration iso image&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;./create-config-drive&lt;span class="w"&gt; &lt;/span&gt;-k&lt;span class="w"&gt; &lt;/span&gt;~/.ssh/id_rsa.pub&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;userdata.sh&lt;span class="w"&gt; &lt;/span&gt;-h&lt;span class="w"&gt; &lt;/span&gt;test1&lt;span class="w"&gt; &lt;/span&gt;test1-config.iso
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Finally you can create domain&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;virt-install&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;test1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--ram&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--vcpus&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--accelerate&lt;span class="w"&gt; &lt;/span&gt;--network&lt;span class="w"&gt; &lt;/span&gt;bridge:br0&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--disk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/lib/libvirt/images/test1.qcow2,bus&lt;span class="o"&gt;=&lt;/span&gt;virtio,cache&lt;span class="o"&gt;=&lt;/span&gt;none
&lt;span class="w"&gt;    &lt;/span&gt;--disk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test1-config.iso,device&lt;span class="o"&gt;=&lt;/span&gt;cdrom&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;--boot&lt;span class="w"&gt; &lt;/span&gt;hd&lt;span class="w"&gt; &lt;/span&gt;--vnc&lt;span class="w"&gt; &lt;/span&gt;--noreboot&lt;span class="w"&gt; &lt;/span&gt;--autostart&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="manage-instance"&gt;
&lt;h2&gt;Manage instance&lt;/h2&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;List instances&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;--all
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Stop instance gracefuly&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;shutdown&lt;span class="w"&gt; &lt;/span&gt;cfg01
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Stop instance by force in case it's hanged&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;destroy&lt;span class="w"&gt; &lt;/span&gt;cfg01
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Delete instance&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;undefine&lt;span class="w"&gt; &lt;/span&gt;cfg01
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="section" id="resize-disk"&gt;
&lt;h3&gt;Resize disk&lt;/h3&gt;
&lt;div class="admonition attention"&gt;
&lt;p class="first admonition-title"&gt;Attention!&lt;/p&gt;
&lt;p class="last"&gt;Shut down instance first, this is important&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You can resize both overlay image or normal image. But don't ever resize image
that is source for overlay images.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;qemu-img&lt;span class="w"&gt; &lt;/span&gt;resize&lt;span class="w"&gt; &lt;/span&gt;cfg01.ovl&lt;span class="w"&gt; &lt;/span&gt;+10G
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On reboot, cloud-init should automatically grow root filesystem.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="extend-memory"&gt;
&lt;h3&gt;Extend memory&lt;/h3&gt;
&lt;p&gt;First you need to redefine max memory for guest:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;setmaxmem&lt;span class="w"&gt; &lt;/span&gt;cfg01&lt;span class="w"&gt; &lt;/span&gt;16G&lt;span class="w"&gt; &lt;/span&gt;--config
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After that you need to destroy domain and start it again.&lt;/p&gt;
&lt;p&gt;Finally you can set memory onlin with following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;setmem&lt;span class="w"&gt; &lt;/span&gt;cfg01&lt;span class="w"&gt; &lt;/span&gt;16G&lt;span class="w"&gt; &lt;/span&gt;--config&lt;span class="w"&gt; &lt;/span&gt;--live
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Parameter &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--config&lt;/span&gt;&lt;/tt&gt; will update domain XML so changes will preserve boot.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="resources"&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://help.ubuntu.com/community/KVM/CreateGuests"&gt;https://help.ubuntu.com/community/KVM/CreateGuests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.techotopia.com/index.php/Installing_a_KVM_Guest_OS_from_the_Command-line_(virt-install"&gt;http://www.techotopia.com/index.php/Installing_a_KVM_Guest_OS_from_the_Command-line_(virt-install&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://wiki.debian.org/KVM"&gt;https://wiki.debian.org/KVM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://blog.oddbit.com/2015/03/10/booting-cloud-images-with-libvirt/"&gt;http://blog.oddbit.com/2015/03/10/booting-cloud-images-with-libvirt/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="virtualization"/></entry><entry><title>Launchpad tricks</title><link href="https://fpy.cz/launchpad-tricks.html" rel="alternate"/><published>2015-07-20T17:33:37+02:00</published><updated>2015-07-20T17:33:37+02:00</updated><author><name>Filip Pytloun</name></author><id>tag:fpy.cz,2015-07-20:/launchpad-tricks.html</id><summary type="html">&lt;div class="section" id="upload-issues"&gt;
&lt;h2&gt;Upload issues&lt;/h2&gt;
&lt;div class="section" id="file-orig-tar-gz-already-exists"&gt;
&lt;h3&gt;File &lt;tt class="docutils literal"&gt;*.orig.tar.gz&lt;/tt&gt; already exists&lt;/h3&gt;
&lt;pre class="literal-block"&gt;
File python-redis_2.10.1.orig.tar.gz already exists in Primary Archive for Ubuntu, but uploaded version has different contents.
&lt;/pre&gt;
&lt;p&gt;You cannot upload file that already exists in Launchpad but has different
content (file checksum).
File checksum changes every time you re-create …&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="upload-issues"&gt;
&lt;h2&gt;Upload issues&lt;/h2&gt;
&lt;div class="section" id="file-orig-tar-gz-already-exists"&gt;
&lt;h3&gt;File &lt;tt class="docutils literal"&gt;*.orig.tar.gz&lt;/tt&gt; already exists&lt;/h3&gt;
&lt;pre class="literal-block"&gt;
File python-redis_2.10.1.orig.tar.gz already exists in Primary Archive for Ubuntu, but uploaded version has different contents.
&lt;/pre&gt;
&lt;p&gt;You cannot upload file that already exists in Launchpad but has different
content (file checksum).
File checksum changes every time you re-create gzipped tarball, because it
modifies gzip headers.&lt;/p&gt;
&lt;p&gt;This happens for example if you import original source package from Ubuntu
archive, make some fixes, eg. backport fixes, create your own source package
by &lt;tt class="docutils literal"&gt;gbp buildpackage &lt;span class="pre"&gt;-S&lt;/span&gt;&lt;/tt&gt; and want to upload it to PPA.&lt;/p&gt;
&lt;p&gt;Fortunately the &amp;quot;fix&amp;quot; is simple - you need to download original tarball from
Ubuntu archive and use it in your source package.&lt;/p&gt;
&lt;p&gt;You can use script similar to this one to download original tarball from
archive and replace checksums in your &lt;tt class="docutils literal"&gt;*.dsc&lt;/tt&gt; file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/bash -x&lt;/span&gt;

&lt;span class="nv"&gt;PPA_REPO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;fpytloun/extra&amp;quot;&lt;/span&gt;

&lt;span class="nv"&gt;orig&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;*.orig.tar.gz&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;orig_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;*.orig.tar.gz&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;orig_sha1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sha1sum&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;orig_sha256&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sha256sum&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;orig_md5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;md5sum&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;

wget&lt;span class="w"&gt; &lt;/span&gt;--quiet&lt;span class="w"&gt; &lt;/span&gt;-O&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;-tmp&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;https://launchpad.net/ubuntu/+archive/primary/+files/&lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-eq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[WARN] Original tarball found in Ubuntu archive, using it instead&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mv&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;-tmp&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;new_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;*.orig.tar.gz&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;new_sha1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sha1sum&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;new_sha256&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sha256sum&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;new_md5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;md5sum&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$orig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="nv"&gt;$orig_sha1&lt;/span&gt;,&lt;span class="nv"&gt;$new_sha1&lt;/span&gt;,g&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="nv"&gt;$orig_sha256&lt;/span&gt;,&lt;span class="nv"&gt;$new_sha256&lt;/span&gt;,g&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="nv"&gt;$orig_size&lt;/span&gt;,&lt;span class="nv"&gt;$new_size&lt;/span&gt;,g&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="nv"&gt;$orig_md5&lt;/span&gt;,&lt;span class="nv"&gt;$new_md5&lt;/span&gt;,g&lt;span class="w"&gt; &lt;/span&gt;*.dsc
&lt;span class="w"&gt;    &lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="nv"&gt;$orig_sha1&lt;/span&gt;,&lt;span class="nv"&gt;$new_sha1&lt;/span&gt;,g&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="nv"&gt;$orig_sha256&lt;/span&gt;,&lt;span class="nv"&gt;$new_sha256&lt;/span&gt;,g&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="nv"&gt;$orig_size&lt;/span&gt;,&lt;span class="nv"&gt;$new_size&lt;/span&gt;,g&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="nv"&gt;$orig_md5&lt;/span&gt;,&lt;span class="nv"&gt;$new_md5&lt;/span&gt;,g&lt;span class="w"&gt; &lt;/span&gt;*.changes
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-e
debsign&lt;span class="w"&gt; &lt;/span&gt;--re-sign&lt;span class="w"&gt; &lt;/span&gt;*.changes
dput&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ppa:&lt;/span&gt;&lt;span class="nv"&gt;$PPA_REPO&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;*.changes
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alternatively you can re-build source package using original tarball so you
don't need to fix checksums manually.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="packaging"/><category term="debian"/></entry><entry><title>Building OpenContrail</title><link href="https://fpy.cz/building-opencontrail.html" rel="alternate"/><published>2015-06-22T12:29:00+02:00</published><updated>2015-06-22T12:29:00+02:00</updated><author><name>Filip Pytloun</name></author><id>tag:fpy.cz,2015-06-22:/building-opencontrail.html</id><summary type="html">&lt;div class="section" id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;div class="section" id="build-dependencies"&gt;
&lt;h3&gt;Build dependencies&lt;/h3&gt;
&lt;p&gt;Dependencies needed to build Opencontrail.&lt;/p&gt;
&lt;p&gt;Actual deps in &lt;tt class="docutils literal"&gt;tools/packages/debian/contrail/debian/builddep.trusty&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;tools/packages/debian/contrail/debian/builddep.trusty&lt;span class="p"&gt;|&lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\ \\\t&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,,g&lt;span class="p"&gt;|&lt;/span&gt;tr&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;tr&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;pre class="literal-block"&gt;
libboost-dev libboost-chrono-dev libboost-date-time-dev
libboost-filesystem-dev libboost-program-options-dev libboost-python-dev
libboost-regex-dev libboost-system-dev libboost-thread-dev
libcurl4-openssl-dev google-mock libgoogle-perftools-dev liblog4cplus-dev
libtbb-dev libhttp-parser-dev libxml2-dev …&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;div class="section" id="build-dependencies"&gt;
&lt;h3&gt;Build dependencies&lt;/h3&gt;
&lt;p&gt;Dependencies needed to build Opencontrail.&lt;/p&gt;
&lt;p&gt;Actual deps in &lt;tt class="docutils literal"&gt;tools/packages/debian/contrail/debian/builddep.trusty&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;tools/packages/debian/contrail/debian/builddep.trusty&lt;span class="p"&gt;|&lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;s,&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\ \\\t&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,,g&lt;span class="p"&gt;|&lt;/span&gt;tr&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;tr&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;pre class="literal-block"&gt;
libboost-dev libboost-chrono-dev libboost-date-time-dev
libboost-filesystem-dev libboost-program-options-dev libboost-python-dev
libboost-regex-dev libboost-system-dev libboost-thread-dev
libcurl4-openssl-dev google-mock libgoogle-perftools-dev liblog4cplus-dev
libtbb-dev libhttp-parser-dev libxml2-dev libicu-dev
&lt;/pre&gt;
&lt;p&gt;Dependencies for building 3rd party packages:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
python-lxml autoconf automake bzip2 libtool patch unzip wget
&lt;/pre&gt;
&lt;p&gt;And a few more, see &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Build-Depends:&lt;/span&gt;&lt;/tt&gt; section of &lt;tt class="docutils literal"&gt;tools/packages/debian/contrail/debian/control&lt;/tt&gt;&lt;/p&gt;
&lt;pre class="literal-block"&gt;
scons git python-lxml wget gcc patch make unzip flex bison g++ libssl-dev
autoconf automake libtool pkg-config vim python-dev python-setuptools
libprotobuf-dev protobuf-compiler libsnmp-python librdkafka-dev
&lt;/pre&gt;
&lt;p&gt;Note that you need latest librdkafka (version 0.8.6) to provide &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;librdkafka++.so&lt;/span&gt;&lt;/tt&gt;
It is not present in Debian or Ubuntu repositories so you need to find it
somewhere on Launchpad or build on your own.&lt;/p&gt;
&lt;p&gt;You also need libipfix. It's not in Debian repository so you need to build it
on your own or grab it here:
&lt;a class="reference external" href="https://launchpad.net/~opencontrail/+archive/ubuntu/ppa/+packages"&gt;https://launchpad.net/~opencontrail/+archive/ubuntu/ppa/+packages&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some more dependencies may be needed, I have found out at least following:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
debhelper libxml2-utils python-all python-sphinx ruby-ronn
module-assistant ant default-jdk javahelper libcommons-codec-java
libhttpcore-java liblog4j1.2-java
&lt;/pre&gt;
&lt;div class="section" id="cowbuilder"&gt;
&lt;h4&gt;Cowbuilder&lt;/h4&gt;
&lt;p&gt;To build debian packages with Cowbuilder/Pbuilder, it will handle dependencies
by itself in chrooted environment.&lt;/p&gt;
&lt;p&gt;Therefore you need just a few packages to be able to build debian source
files.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
libxml2-utils
python-lxml
autoconf
automake
libtool
patch
unzip
pkg-config
javahelper
ant
python-setuptools
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="install-dependencies"&gt;
&lt;h3&gt;Install dependencies&lt;/h3&gt;
&lt;p&gt;To install opencontrail packages, you need to satisfy some dependencies that
are not in Ubuntu Trusty installation.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
python-geventhttpclient (&amp;gt;= 1.0)
python-certifi
python-backports.ssl-match-hostname
python-ncclient
python-pycassa (&amp;gt;= 1.7.2)
python-xmltodict
python-docker-py (python-opencontrail-vrouter-netns)
python-redis (&amp;gt;= 2.8.0)
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="build"&gt;
&lt;h2&gt;Build&lt;/h2&gt;
&lt;div class="section" id="manual"&gt;
&lt;h3&gt;Manual&lt;/h3&gt;
&lt;p&gt;Follow these steps to build Opencontrail manually or skip to building with
Jenkins and Cowbuilder.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Get android repo tool&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;wget&lt;span class="w"&gt; &lt;/span&gt;https://storage.googleapis.com/git-repo-downloads/repo
chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;repo
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Initialize sandbox&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;build&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;build
repo&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;git@github.com:Juniper/contrail-vnc.git&lt;span class="w"&gt; &lt;/span&gt;-b&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONTRAIL_BRANCH&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;master&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
repo&lt;span class="w"&gt; &lt;/span&gt;sync
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Get and patch 3rd party packages&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;third_party
./fetch_packages.py
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Execute the build&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# For building into dest root, no debian package&lt;/span&gt;
scons&lt;span class="w"&gt; &lt;/span&gt;-j&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;JOBS_COUNT&lt;/span&gt;&lt;span class="k"&gt;:-$(&lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;processor&lt;span class="w"&gt; &lt;/span&gt;/proc/cpuinfo&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Or create Debian packages, they will appear in build/packages/ directory&lt;/span&gt;
make&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;packages.make&lt;span class="w"&gt; &lt;/span&gt;all

&lt;span class="c1"&gt;# You can also build only source packages and build binaries with&lt;/span&gt;
&lt;span class="c1"&gt;# cowbuilder or some better way that will also handle dependencies&lt;/span&gt;
make&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;packages.make&lt;span class="w"&gt; &lt;/span&gt;source-all
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;div class="section" id="jenkins"&gt;
&lt;h3&gt;Jenkins&lt;/h3&gt;
&lt;p&gt;To automate building with Jenkins, you can use script like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/bash -xe&lt;/span&gt;

&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;whoami&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;JOBS_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;JOBS_COUNT&lt;/span&gt;&lt;span class="k"&gt;:-$(&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;/proc/cpuinfo&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;processor&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Github account is needed to fetch repositories&lt;/span&gt;
pgrep&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;ssh-agent&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ssh-agent&lt;span class="p"&gt;|&lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Agent pid&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;~/.ssh/ssh-agent.sh
.&lt;span class="w"&gt; &lt;/span&gt;~/.ssh/ssh-agent.sh
ssh-add&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SSH_KEY&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.ssh/id_rsa&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
grep&lt;span class="w"&gt; &lt;/span&gt;github&lt;span class="w"&gt; &lt;/span&gt;~/.ssh/known_hosts&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ssh-keyscan&lt;span class="w"&gt; &lt;/span&gt;github.com&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;~/.ssh/known_hosts

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;bin&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;bin
&lt;span class="w"&gt;    &lt;/span&gt;wget&lt;span class="w"&gt; &lt;/span&gt;-O&lt;span class="w"&gt; &lt;/span&gt;bin/repo&lt;span class="w"&gt; &lt;/span&gt;https://storage.googleapis.com/git-repo-downloads/repo
&lt;span class="w"&gt;    &lt;/span&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;bin/repo
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$WORKSPACE&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;build&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;build
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;build
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$CONTRAIL_BRANCH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;repo&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$CONTRAIL_VNC_REPO&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;repo&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$CONTRAIL_VNC_REPO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-b&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$CONTRAIL_BRANCH&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
repo&lt;span class="w"&gt; &lt;/span&gt;sync

&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;third_party
python&lt;span class="w"&gt; &lt;/span&gt;fetch_packages.py
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;..

&lt;span class="c1"&gt;# Normal build&lt;/span&gt;
&lt;span class="c1"&gt;# scons -j $JOBS_COUNT&lt;/span&gt;
&lt;span class="c1"&gt;# Build debian packages&lt;/span&gt;
&lt;span class="c1"&gt;#  make -f packages.make all&lt;/span&gt;
&lt;span class="c1"&gt;# Build debian source packages for binary build&lt;/span&gt;
&lt;span class="c1"&gt;# unfortunately source-all target doesn&amp;#39;t work&lt;/span&gt;
&lt;span class="c1"&gt;#  make -f packages.make source-all&lt;/span&gt;
grep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^source-package-.*:&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;packages.make&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;i&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;packages.make&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You could possibly also use &lt;a class="reference external" href="https://wiki.jenkins-ci.org/display/JENKINS/Repo+Plugin"&gt;Jenkins repo plugin&lt;/a&gt; for SCM
management.&lt;/p&gt;
&lt;div class="section" id="cowbuilder-1"&gt;
&lt;h4&gt;Cowbuilder&lt;/h4&gt;
&lt;p&gt;If you are going to build debian packages, I would advice to use &lt;tt class="docutils literal"&gt;make &lt;span class="pre"&gt;-f&lt;/span&gt;
packages.make &lt;span class="pre"&gt;source-all&lt;/span&gt;&lt;/tt&gt; in the script above.&lt;/p&gt;
&lt;p&gt;This will create &lt;tt class="docutils literal"&gt;*.dsc&lt;/tt&gt; files that can be used as source artifacts for
build with &lt;cite&gt;Cowbuilder&lt;/cite&gt; which can create build chroot and handle build
dependencies without garbaging your system.&lt;/p&gt;
&lt;p&gt;Binary build job can look like this, using &lt;a class="reference external" href="http://jenkins-debian-glue.org/"&gt;jenkins-debian-glue&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/bash -xe&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;*.dsc&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$pkgname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$pkgname&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mv&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;_*.gz&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;_*.dsc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pkgname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$pkgname&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;WORKSPACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;/usr/bin/build-and-provide-package
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;..
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;WORKSPACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Don't forget you need to install additional dependencies that are not present
in Debian or Ubuntu repositories.&lt;/p&gt;
&lt;p&gt;To setup additional repository, update &lt;tt class="docutils literal"&gt;/etc/pbuilderrc&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;OTHERMIRROR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;deb http://apt.tcpcloud.eu/nightly cloudlab&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or to use your only own repository for both debootstrap and build, you can use
setup similar to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;MIRRORSITE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;http://apt.tcpcloud.eu/nightly&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;COMPONENTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;main cloudlab security&amp;quot;&lt;/span&gt;
&lt;span class="c1"&gt;# Debootstrap in Ubuntu is using ubuntu keyring, to use # your own, provide&lt;/span&gt;
&lt;span class="c1"&gt;# default keyring&lt;/span&gt;
&lt;span class="nv"&gt;DEBOOTSTRAPOPTS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DEBOOTSTRAPOPTS&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;--keyring=/etc/apt/trusted.gpg&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;APTKEYRINGS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APTKEYRINGS&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/etc/apt/trusted.gpg&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Unfortunately if you have different list of components than are default for
your distribution, you need to export &lt;tt class="docutils literal"&gt;COMPONENTS&lt;/tt&gt; before running
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;build-and-provide-package&lt;/span&gt;&lt;/tt&gt; otherwise jenkins debian glue will override
these provided in &lt;tt class="docutils literal"&gt;pbuilderrc&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://juniper.github.io/contrail-vnc/README.html"&gt;Contrail building instructions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/Juniper/contrail-build"&gt;Juniper/contrail-build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/Juniper/contrail-packages"&gt;Juniper/contrail-packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://wiki.ubuntu.com/PbuilderHowto"&gt;Pbuilder Ubuntu howto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://pbuilder.alioth.debian.org/"&gt;Pbuilder Debian manual&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="packaging"/><category term="debian"/><category term="opencontrail"/></entry><entry><title>Using Aptly for repository management</title><link href="https://fpy.cz/using-aptly-for-repository-management.html" rel="alternate"/><published>2015-06-15T20:30:35+02:00</published><updated>2015-06-15T20:30:35+02:00</updated><author><name>Filip Pytloun</name></author><id>tag:fpy.cz,2015-06-15:/using-aptly-for-repository-management.html</id><summary type="html">&lt;div class="section" id="repository-anatomy"&gt;
&lt;h2&gt;Repository anatomy&lt;/h2&gt;
&lt;p&gt;Record in &lt;tt class="docutils literal"&gt;sources.list&lt;/tt&gt; may look like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
deb http://ppa.launchpad.net/saltstack/salt/ubuntu trusty main
&lt;/pre&gt;
&lt;p&gt;It consists of repository url, distribution and one or more components.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
deb &amp;lt;repository&amp;gt; &amp;lt;distribution&amp;gt; &amp;lt;component(s)&amp;gt;
&lt;/pre&gt;
&lt;div class="section" id="distribution"&gt;
&lt;h3&gt;Distribution&lt;/h3&gt;
&lt;p&gt;Distribution name consists of Linux distribution version codename (eg.
&lt;tt class="docutils literal"&gt;trusty&lt;/tt&gt;) and our internal …&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="repository-anatomy"&gt;
&lt;h2&gt;Repository anatomy&lt;/h2&gt;
&lt;p&gt;Record in &lt;tt class="docutils literal"&gt;sources.list&lt;/tt&gt; may look like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
deb http://ppa.launchpad.net/saltstack/salt/ubuntu trusty main
&lt;/pre&gt;
&lt;p&gt;It consists of repository url, distribution and one or more components.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
deb &amp;lt;repository&amp;gt; &amp;lt;distribution&amp;gt; &amp;lt;component(s)&amp;gt;
&lt;/pre&gt;
&lt;div class="section" id="distribution"&gt;
&lt;h3&gt;Distribution&lt;/h3&gt;
&lt;p&gt;Distribution name consists of Linux distribution version codename (eg.
&lt;tt class="docutils literal"&gt;trusty&lt;/tt&gt;) and our internal stability identifier (&lt;tt class="docutils literal"&gt;stable&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;testing&lt;/tt&gt;)&lt;/p&gt;
&lt;p&gt;It can also have a prefix that can identify source.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Examples&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trusty-stable&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trusty-testing&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;upstream/trusty-testing&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;div class="section" id="component"&gt;
&lt;h3&gt;Component&lt;/h3&gt;
&lt;p&gt;Components are subsets of each distribution repository. They can be used
independently by choice or all together.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Examples&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;main&lt;/tt&gt; - Ubuntu packages&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;universe&lt;/tt&gt; - Ubuntu universe packages&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="local-repository"&gt;
&lt;h2&gt;Local repository&lt;/h2&gt;
&lt;p&gt;Custom packages build by us. Published as &lt;tt class="docutils literal"&gt;cloudlab&lt;/tt&gt; component.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
aptly repo create -component=cloudlab -architectures=amd64 cloudlab
&lt;/pre&gt;
&lt;div class="section" id="publishing"&gt;
&lt;h3&gt;Publishing&lt;/h3&gt;
&lt;div class="section" id="direct-publish"&gt;
&lt;h4&gt;Direct publish&lt;/h4&gt;
&lt;p&gt;It's possible to publish repository directly with no snapshots. Unfortunately
this is not possible with mirrors so if it's needed to combine components
including custom repository and mirrorred ones, it has to be via snapshots.
See &lt;a class="reference external" href="http://www.aptly.info/doc/feature/multi-component/"&gt;Multi component publishing&lt;/a&gt;&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;New publish&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
aptly publish repo -distribution=trusty-testing cloudlab
&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;Update publish&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
aptly publish update trusty-testing
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;div class="section" id="snapshot-publish"&gt;
&lt;h4&gt;Snapshot publish&lt;/h4&gt;
&lt;p&gt;To create new snapshot and create or update existing publish.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;New publish&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
aptly snapshot create cloudlab-`date +%s` from repo cloudlab
 aptly publish snapshot -distribution=trusty-stable cloudlab-1433941328
&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;Update publish&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
aptly snapshot create cloudlab-`date +%s` from repo cloudlab
 aptly publish switch -component=cloudlab trusty-stable cloudlab-1433941328
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="repository-mirror"&gt;
&lt;h2&gt;Repository mirror&lt;/h2&gt;
&lt;p&gt;First you need to import distributor's GPG key to be able to verify packages.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
gpg --no-tty --no-default-keyring --keyring trustedkeys.gpg --keyserver keys.gnupg.net --recv-keys 0E27C0A6
&lt;/pre&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Create mirror&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
aptly mirror create -architectures=amd64 salt http://ppa.launchpad.net/saltstack/salt/ubuntu/ trusty main
&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;Update mirror&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first"&gt;This will fetch newest packages from upstream. Should be run periodically
to be always up to date.&lt;/p&gt;
&lt;pre class="last literal-block"&gt;
aptly mirror update salt
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;div class="section" id="real-world-example"&gt;
&lt;h2&gt;Real-world example&lt;/h2&gt;
&lt;p&gt;Let's try to design some real-world example.&lt;/p&gt;
&lt;div class="section" id="software-sources"&gt;
&lt;h3&gt;Software sources&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;local repository with custom packages&lt;/li&gt;
&lt;li&gt;upstream mirror&lt;ul&gt;
&lt;li&gt;trusty main&lt;/li&gt;
&lt;li&gt;trusty-security main&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://ubuntu-cloud.archive.canonical.com/ubuntu/"&gt;ubuntucloud&lt;/a&gt; (trusty-updates/juno main)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://ppa.launchpad.net/saltstack/salt/ubuntu/"&gt;salt repository mirror&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Example status&lt;/dt&gt;
&lt;dd&gt;&lt;pre class="first last literal-block"&gt;
aptly&amp;#64;aptly01:/home/filip$ aptly repo list
List of local repos:
 - [cloudlab]: TCP Cloud custom components (packages: 0)

aptly&amp;#64;aptly01:/home/filip$ aptly mirror list
List of mirrors:
 - [salt-trusty]: http://ppa.launchpad.net/saltstack/salt/ubuntu/ trusty
 - [trusty-main]: http://eu.archive.ubuntu.com/ubuntu/ trusty
 - [trusty-security]: http://eu.archive.ubuntu.com/ubuntu/ trusty-security
 - [trusty-updates-juno]: http://ubuntu-cloud.archive.canonical.com/ubuntu/ trusty-updates/juno
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="section" id="sync-mirrors"&gt;
&lt;h4&gt;Sync mirrors&lt;/h4&gt;
&lt;p&gt;It's good idea to keep mirrors up to date and sync them periodically.
You can use script bellow, place it eg. into
&lt;tt class="docutils literal"&gt;/usr/local/bin/aptly_update_mirrors.sh&lt;/tt&gt; and create crontab record for aptly
user (suppose that aptly repo is not managed by root).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;SCRIPT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;basename&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;MAXTRIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="nv"&gt;VERBOSE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="nv"&gt;SNAPSHOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;

log_info&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;logger&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;user.info&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SCRIPT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-eq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[INFO] &lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

log_error&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;logger&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;user.error&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SCRIPT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[ERROR] &lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;*--verbose*&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;*-v*&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;VERBOSE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;*--snapshot*&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;*-s*&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;SNAPSHOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="nv"&gt;MIRRORS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;mirror&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;--raw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-ne&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log_error&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$MIRRORS&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;mirror&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$MIRRORS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;try&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;retval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;666&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$retval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-ne&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-lt&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$MAXTRIES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;log_info&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Starting update of mirror &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-eq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nv"&gt;out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;mirror&lt;span class="w"&gt; &lt;/span&gt;update&lt;span class="w"&gt; &lt;/span&gt;-force&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;mirror&lt;span class="w"&gt; &lt;/span&gt;update&lt;span class="w"&gt; &lt;/span&gt;-force&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;retval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$retval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-ne&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nv"&gt;try&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;$&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;+&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;log_error&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to update mirror &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, try=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;try&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;-z&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$out&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;log_error&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;out&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;log_info&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Synced mirror &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$SNAPSHOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-eq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nv"&gt;snapshot_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="w"&gt; &lt;/span&gt;+%s&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-eq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nv"&gt;out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;snapshot&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;snapshot_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;mirror&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;snapshot&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;snapshot_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;mirror&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nv"&gt;retval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$retval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-ne&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;log_error&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to create snapshot &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;snapshot_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; from mirror &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;-z&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$out&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;log_error&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$out&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;log_info&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Created snapshot &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;snapshot_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; from mirror &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mirror&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;crontab&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;aptly
&lt;span class="c1"&gt;# Sync aptly mirrors every 6 hours&lt;/span&gt;
&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;*/6&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt;  &lt;/span&gt;aptly_sync_mirrors.sh&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;-s
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First run may take a long time so it's good idea to execute it in terminal
multiplexer (Tmux, Screen, Byobu, etc.) in verbose mode.
Parameter &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--snapshot&lt;/span&gt;&lt;/tt&gt; will automatically create snapshots of newly synced
mirrors.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;aptly_sync_mirrors.sh&lt;span class="w"&gt; &lt;/span&gt;--verbose&lt;span class="w"&gt; &lt;/span&gt;--snapshot
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="publishing-1"&gt;
&lt;h3&gt;Publishing&lt;/h3&gt;
&lt;p&gt;First we need to decide how our published repository will look like.&lt;/p&gt;
&lt;div class="section" id="distribution-1"&gt;
&lt;h4&gt;Distribution&lt;/h4&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;We want to support only Ubuntu Trusty in three branches:&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;nightly&lt;/tt&gt; with up-to-date packages with mirrors&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;testing&lt;/tt&gt; for stabilization&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;stable&lt;/tt&gt; for rock-solid distribution&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;So final distributions will be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trusty-nightly&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trusty-testing&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trusty-stable&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="components"&gt;
&lt;h4&gt;Components&lt;/h4&gt;
&lt;p&gt;Each OS distribution has different approach to components. For our workflow,
component means:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;set of independently versioned packages (sub-distribution) where customer
may choose
- eg. Openstack juno, kilo
- or Opencontrail 21, 22, etc.&lt;/li&gt;
&lt;li&gt;set of packages with different or faster release workflow
- because you can update publish per-component
- eg. security from trusty-security distribution
- or custom packages in our repository&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For our example, components will be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;main&lt;/tt&gt; - merged upstream + ppa repositories with newer software versions&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;security&lt;/tt&gt; - security updates&lt;ul&gt;
&lt;li&gt;because we want to push security updates between publishes separately&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;cloudlab&lt;/tt&gt; - our packages&lt;ul&gt;
&lt;li&gt;because our packages can have different release cycle than rest of the
distribution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;juno&lt;/tt&gt; - packages of Openstack Juno&lt;ul&gt;
&lt;li&gt;because this component is optional and one can use different openstack
version than juno&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="create-publish"&gt;
&lt;h4&gt;Create publish&lt;/h4&gt;
&lt;p&gt;This way you will create snapshots, merge some of them into one component
snapshot (main) and publish using &lt;cite&gt;multi-component publishing&lt;/cite&gt;.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Create snapshots for each mirror and repo&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="w"&gt; &lt;/span&gt;+%s&lt;span class="k"&gt;)&lt;/span&gt;
aptly&lt;span class="w"&gt; &lt;/span&gt;mirror&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;--raw&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;i&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;snapshot&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;mirror&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;
aptly&lt;span class="w"&gt; &lt;/span&gt;repo&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;--raw&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;i&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;snapshot&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;repo&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Merge snapshots into desired final components&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;snapshot&lt;span class="w"&gt; &lt;/span&gt;merge&lt;span class="w"&gt; &lt;/span&gt;main-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;salt-trusty-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;trusty-main-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Create multi-component publish of snapshots&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;publish&lt;span class="w"&gt; &lt;/span&gt;snapshot&lt;span class="w"&gt; &lt;/span&gt;-component&lt;span class="o"&gt;=&lt;/span&gt;main,cloudlab,juno,security&lt;span class="w"&gt; &lt;/span&gt;-distribution&lt;span class="o"&gt;=&lt;/span&gt;trusty-nightly&lt;span class="w"&gt; &lt;/span&gt;main-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cloudlab-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;trusty-updates-juno-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;trusty-security-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;When new snapshots are created, use similar command as the one above to update publish:&lt;/dt&gt;
&lt;dd&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;aptly&lt;span class="w"&gt; &lt;/span&gt;publish&lt;span class="w"&gt; &lt;/span&gt;switch&lt;span class="w"&gt; &lt;/span&gt;-component&lt;span class="o"&gt;=&lt;/span&gt;main,cloudlab,juno,security&lt;span class="w"&gt; &lt;/span&gt;trusty-nightly&lt;span class="w"&gt; &lt;/span&gt;main-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cloudlab-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;trusty-updates-juno-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;trusty-security-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAMP&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;For more information, read &lt;a class="reference external" href="http://www.aptly.info/doc/feature/multi-component/"&gt;multi-component publishing&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="naming-conventions"&gt;
&lt;h3&gt;Naming conventions&lt;/h3&gt;
&lt;div class="section" id="mirrors"&gt;
&lt;h4&gt;Mirrors&lt;/h4&gt;
&lt;p&gt;There has to be one mirror per each repository distribution, so distribution
has to be reflected in the name.
Aptly doesn't work with components on this level so each component has to be
mirrored separately, otherwise it will be merged into main component.&lt;/p&gt;
&lt;p&gt;Source repository can be ommited from mirror name if it's upstream repository.
Distribution name can me ommited if there's only one distribution per mirrored
repository and naming it explicitly would be confusing.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Patterns and examples&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;source&amp;gt;-&amp;lt;distribution&amp;gt;(-&amp;lt;component&amp;gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;salt-trusty (&lt;tt class="docutils literal"&gt;&amp;lt;salt_ppa&amp;gt; trusty main&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;trusty-main (&lt;tt class="docutils literal"&gt;&amp;lt;ubuntu_upstream&amp;gt; trusty main&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;trusty-updates-juno (&lt;tt class="docutils literal"&gt;&amp;lt;ubuntucloud_repository&amp;gt; &lt;span class="pre"&gt;trusty-updates/juno&lt;/span&gt; main&lt;/tt&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;div class="section" id="snapshots"&gt;
&lt;h4&gt;Snapshots&lt;/h4&gt;
&lt;p&gt;It's always good idea to use Unix timestamp for snapshot versioning and same
name as for source mirror or repository.&lt;/p&gt;
&lt;p&gt;For snapshots created by merging other snapshots, naming by published
distribution is a good idea.&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Patterns and examples&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cloudlab-$(date&lt;/span&gt; +%s)&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trusty-updates-juno-1434444631&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;main-1434444631&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="packaging"/><category term="debian"/></entry></feed>