<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>imagefactory | build, push, deploy</title>
 <link href="http://imgfac.org/atom.xml" rel="self"/>
 <link href="http://imgfac.org"/>
 <updated>2014-08-01T16:33:08+00:00</updated>
 <id>http://layouts.studiomohawk.com/</id>

 
 <entry>
   <title>Writing Plugins For Imagefactory</title>
   <link href="http://imgfac.org/blog/2014/07/30/writing-plugins-for-imagefactory"/>
   <updated>2014-07-30T00:00:00+00:00</updated>
   <id>http://imgfac.org/blog/2014/07/30/writing-plugins-for-imagefactory</id>
   <content type="html">&lt;p&gt;Have you found yourself wishing that Image Factory supported your favorite tool for building system images or some new hypervisor / cloud? Maybe you’re developing a new cloud offering or you have a favorite OS that you would like to see Image Factory build images for.&lt;/p&gt;

&lt;p&gt;Would you be surprised if I told you that writing a plugin for Image Factory is relatively easy? Actually, let’s back up a second… are you surprised to learn that Image Factory uses plugins? &lt;/p&gt;

&lt;p&gt;If the answer to any of these questions was ‘Yes’, then hopefully this post will introduce you to an exciting world of image building possibilities.&lt;/p&gt;

&lt;p&gt;Since the Nova plugin was just released, I’ll tear that open to use as a real world example. The source for this plugin can be found in the imagefactory git &lt;a href=&quot;https://github.com/redhat-imaging/imagefactory&quot;&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;whats-in-a-plugin&quot;&gt;What’s in a plugin?&lt;/h4&gt;

&lt;p&gt;First, what IS an imagefactory plugin? If you look at the plugins already installed on your system, you’ll see a number of directories that look like Python packages. You will find these in the &lt;code&gt;imagefactory_plugins&lt;/code&gt; directory in the &lt;code&gt;SITE_PACKAGES&lt;/code&gt; for the Python environment under which you run imagefactory.  &lt;/p&gt;

&lt;p&gt;According to the imagefactory plugins &lt;a href=&quot;http://imgfac.org/documentation/plugins.html&quot;&gt;documentation&lt;/a&gt;, there are only two things you need to add to a Python package in order to make it a plugin that imagefactory will recognize and load.&lt;/p&gt;

&lt;p&gt;These tasks are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Assign the delegate class.  &lt;/li&gt;
  &lt;li&gt;Define the plugin metadata.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s take a look at the second item first and create a .info document that describes our plugin. This file is named after the plugin it describes. In our case, this would be the &lt;code&gt;Nova.info&lt;/code&gt; file that looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
    &quot;type&quot;: &quot;os&quot;,
    &quot;targets&quot;: [ [&quot;Fedora&quot;, null, null], [&quot;RHEL-6&quot;, null, null], [&quot;RHEL-5&quot;, null, null],
                 [&quot;RHEL-7&quot;, null, null], [&quot;Ubuntu&quot;, null, null], [&quot;CentOS-6&quot;, null, null],
                 [&quot;CentOS-5&quot;, null, null], [&quot;Windows&quot;, null, null] ],
    &quot;description&quot;: &quot;Plugin to support building OS base images using OpenStack Nova.&quot;,
    &quot;maintainer&quot;: {
        &quot;name&quot;: &quot;Red Hat, Inc.&quot;,
        &quot;email&quot;: &quot;imagefactory-devel@lists.fedorahosted.org&quot;,
        &quot;url&quot;: &quot;http://imgfac.org&quot;
    },
    &quot;version&quot;: &quot;1.0&quot;,
    &quot;license&quot;: &quot;Copyright 2012 Red Hat, Inc. - http://www.apache.org/licenses/LICENSE-2.0&quot;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The .info file is just a JSON document that describes the plugin with a set of key/value pairs.See all of that stuff there? It is REALLY important that &lt;em&gt;everything&lt;/em&gt; is defined before a plugin is released. Okay, now that I’ve said that, I’ll point out that the only two keys that need values in order for the plugin to be loaded by imagefactory are the first two, &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;targets&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The “type” of the plugin is either “os” or “cloud”. If your plugin will be installing an operating system into an image in some way, then it is an “os” plugin. If your plugin will be transforming a base image that already has an operating system installed into something that your target hypervisor or cloud can use, then the plugin is a “cloud” plugin. This will come into play once we start writing code to implement our plugin, but we’ll get to that soon enough.&lt;/p&gt;

&lt;p&gt;The “targets” value is a list of terms matched when building a base or target image. In the case of an OS plugin, each value in that list is itself a list of the OS name, the OS version, and the OS architecture. In a TDL document, this matches the &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;version&lt;/code&gt;, &lt;code&gt;arch&lt;/code&gt; child elements under the &lt;code&gt;os&lt;/code&gt; element. In our example the above, &lt;code&gt;null&lt;/code&gt; is used as a wildcard meaning that each entry matches for any version or architecture of the OS listed by name.&lt;/p&gt;

&lt;p&gt;For a Cloud plugin, each of the values in the targets list is just a string that is the name of the cloud or hypervisor with which the plugin is compatible. This cloud name is what will be passed to imagefactory when using the &lt;code&gt;target_image&lt;/code&gt; or &lt;code&gt;provider_image&lt;/code&gt; command. Here is the target entry in the .info file for the Docker plugin as an example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &quot;targets&quot;: [ [ &quot;docker&quot;] ],
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now that we have described the plugin, we need to implement it. Here is where we need to satisfy the first requirement of assigning the delegate class. The delegate class is the interface imagefactory uses to interact with the plugin and define the methods your plugin can implement. This class will implement either the &lt;a href=&quot;https://github.com/redhat-imaging/imagefactory/blob/master/imgfac/OSDelegate.py&quot;&gt;OSDelegate&lt;/a&gt; or &lt;a href=&quot;https://github.com/redhat-imaging/imagefactory/blob/master/imgfac/CloudDelegate.py&quot;&gt;CloudDelegate&lt;/a&gt; interface. The Nova plugin, the example for this article, is an OS plugin, so the delegate class implements the OSDelegate interface in the &lt;code&gt;Nova.py&lt;/code&gt; module:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import zope
import logging

class Nova(object):
    zope.interface.implements(OSDelegate)
    def __init__(self):
        super(Nova, self).__init__()
        self.log = logging.getLogger(&#39;%s.%s&#39; % (__name__, self.__class__.__name__))

    def create_base_image(self, builder, template, parameters):
        self.log.info(&#39;create_base_image() called for Nova plugin - creating a BaseImage&#39;)

    def create_target_image(self, builder, target, base_image, parameters):
        self.log.info(&#39;create_target_image() called for Nova plugin - creating a TargetImage&#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In order for imagefactory to find the class that implements the delegate interface, in this case &lt;code&gt;Nova&lt;/code&gt;, we need to assign that class. We do this in the &lt;code&gt;__init__.py&lt;/code&gt; of our plugin package with a line like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;from Nova import Nova as delegate_class
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now imagefactory knows how to call into our plugin when creating a base image for the operating systems our plugin supports.&lt;/p&gt;

&lt;p&gt;Our example code listing above doesn’t do anything but log that each method was called. There is, of course, more to connecting to OpenStack Nova to spawn an instance, install an OS, and customize it for use by future instances. Luckily, there is a project we can use in this plugin to handle these tasks. Once we have installed &lt;a href=&quot;https://github.com/redhat-imaging/novaimagebuilder&quot;&gt;Nova Image Builder&lt;/a&gt; we can import what we need into our delegate class and call out to this other project to do the heavy lifting for us:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import zope
import logging
from novaimagebuilder.Builder import Builder

class Nova(object):
    zope.interface.implements(OSDelegate)
    def __init__(self):
        super(Nova, self).__init__()
        self.log = logging.getLogger(&#39;%s.%s&#39; % (__name__, self.__class__.__name__))
        self.nib = None

    def create_base_image(self, builder, template, parameters):
        self.log.info(&#39;create_base_image() called for Nova plugin - creating a BaseImage&#39;)
        if template.os_version:
            if template.os_name[-1].isdigit():
                install_os = &#39;%s.%s&#39; % (template.os_name, template.os_version)
            else:
                install_os = &#39;%s%s&#39; % (template.os_name, template.os_version)
        else:
            install_os = template.os_name

        install_os = install_os.lower()

        install_location = template.install_location
        # TDL uses &#39;url&#39; but Nova Image Builder uses &#39;tree&#39;
        install_type = &#39;tree&#39; if template.install_type == &#39;url&#39; else template.install_type
        install_script = parameters.get(&#39;install_script&#39;)
        install_config = {&#39;admin_password&#39;: parameters.get(&#39;admin_password&#39;),
                          &#39;license_key&#39;: parameters.get(&#39;license_key&#39;),
                          &#39;arch&#39;: template.os_arch,
                          &#39;disk_size&#39;: parameters.get(&#39;disk_size&#39;),
                          &#39;flavor&#39;: parameters.get(&#39;flavor&#39;),
                          &#39;storage&#39;: parameters.get(&#39;storage&#39;),
                          &#39;name&#39;: template.name,
                          &#39;direct_boot&#39;: parameters.get(&#39;direct_boot&#39;, False),
                          &#39;timeout&#39;: parameters.get(&#39;timeout&#39;, 1800),
                          &#39;public&#39;: parameters.get(&#39;public&#39;, False),
                          &#39;floating_ip&#39;: parameters.get(&#39;request_floating_ip&#39;, False)}

        builder.base_image.update(10, &#39;BUILDING&#39;, &#39;Created Nova Image Builder instance...&#39;)
        self.nib = Builder(install_os, install_location, install_type, install_script, install_config)
        self.nib.run()
        jeos_image_id = self.nib.wait_for_completion(180)
        builder.base_image.properties[&#39;x-image-properties-glance_id&#39;] = jeos_image_id
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the code above, we are gathering the information Nova Image Builder will need from the TDL that was passed in along with any external build parameters. This information is then passed to a new instance of the Builder class in Nova Image Builder, which is then told to run the build task. Finally, we wait for a glance id for the built image to be returned which we set in the metadata imagefactory stores locally so that we can find the image and use it later.&lt;/p&gt;

&lt;p&gt;There is more to the implementation of the Nova plugin, but that gets beyond the scope of this article. If you are interested in all of the gory details, have a look in the imagefactory git &lt;a href=&quot;https://github.com/redhat-imaging/imagefactory&quot;&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, there you have it. Plugins for imagefactory. &lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Running Diskimage Builder With Indirection Plugin</title>
   <link href="http://imgfac.org/blog/2014/07/29/Running-diskimage-builder-with-Indirection-plugin"/>
   <updated>2014-07-29T00:00:00+00:00</updated>
   <id>http://imgfac.org/blog/2014/07/29/Running-diskimage-builder-with-Indirection-plugin</id>
   <content type="html">&lt;p&gt;Indirection plugin is the most versatile plugin for ImageFactory. Indirection
allows the user to go beyond just package installation and configuration.
Originally it was developed to generate LiveCD images using the
livemedia-creator project in Fedora. More on that can be found [here] 
(https://github.com/redhat-imaging/imagefactory/blob/master/imagefactory_plugins/IndirectionCloud/README.md).
Such flexibility is achieved by breaking up the image building process into
three steps.&lt;/p&gt;

&lt;h3 id=&quot;step-1-create-utility-image&quot;&gt;Step 1: Create utility image&lt;/h3&gt;

&lt;p&gt;Utility image is the image that contains any special tools needed to customize 
an image. In the example here, the utility image will contain 
diskimage-builder, instack-undercloud, and git packages. The following
kickstart file will be passed in to imagefactory as utility_image.ks:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;url --url=http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/20/Fedora/x86_64/os/
# Without the Everything repo, we cannot install cloud-init
repo --name=&quot;fedora-everything&quot; --baseurl=http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/20/Everything/x86_64/os/
repo --name=&quot;testing&quot; --baseurl=http://mirror.pnl.gov/fedora/linux/updates/20/x86_64/
# At moment this is where the working version of diskimage-builder lives
repo --name=updates-testing --baseurl=http://mirror.pnl.gov/fedora/linux/updates/testing/20/x86_64/
# instack-undercloud lives here for now
repo --name=openstack --baseurl=http://repos.fedorapeople.org/repos/openstack/openstack-icehouse/fedora-20/

install
text
keyboard us
lang en_US.UTF-8

skipx

network --device eth0 --bootproto dhcp
rootpw ROOTPW
firewall --disabled
authconfig --enableshadow --enablemd5
selinux --enforcing
timezone --utc America/New_York
bootloader --location=mbr --append=&quot;console=tty0 console=ttyS0,115200&quot;
zerombr
clearpart --all --drives=vda

part biosboot --fstype=biosboot --size=1
part /boot --fstype ext4 --size=200 --ondisk=vda
part pv.2 --size=1 --grow --ondisk=vda
volgroup VolGroup00 --pesize=32768 pv.2
logvol swap --fstype swap --name=LogVol01 --vgname=VolGroup00 --size=768 --grow --maxsize=1536
logvol / --fstype ext4 --name=LogVol00 --vgname=VolGroup00 --size=1024 --grow
reboot

%packages
@core
diskimage-builder
instack-undercloud
git
%end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above TDL does not contain administrative password property. ImageFactory will
complain unless /etc/imagefactory/imagefactory.conf has root password
enforcement disabled in following manner:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  ...
  &quot;tdl_require_root_pw&quot;: 0,
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In addition to the kickstart file, ImageFactory requires a TDL template
to build an image. Let’s call this file utility_image.tdl:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;name&amp;gt;f20-jeos&amp;lt;/name&amp;gt;
  &amp;lt;os&amp;gt;
    &amp;lt;name&amp;gt;Fedora&amp;lt;/name&amp;gt;
    &amp;lt;version&amp;gt;20&amp;lt;/version&amp;gt;
    &amp;lt;arch&amp;gt;x86_64&amp;lt;/arch&amp;gt;
    &amp;lt;install type=&#39;url&#39;&amp;gt;
      &amp;lt;url&amp;gt;http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/20/Fedora/x86_64/os/&amp;lt;/url&amp;gt;
    &amp;lt;/install&amp;gt;
  &amp;lt;/os&amp;gt;
  &amp;lt;disk&amp;gt;
    &amp;lt;size&amp;gt;20&amp;lt;/size&amp;gt;
  &amp;lt;/disk&amp;gt;
  &amp;lt;description&amp;gt;Fedora 20 JEOS Image&amp;lt;/description&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following command should be run from the directory where utility_image.tdl
and utility_image.ks live:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;imagefactory --debug base_image --file-parameter install_script utility_image.ks utility_image.tdl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please take note of the image ID when ImageFactory finishes building the
utility image 
###Step 2: Create input image&lt;/p&gt;

&lt;p&gt;After a utility image is built, another base image needs to be created to be
used as input image. Since both utility image and input image are base_image,
it is possible to use one image for both. Because diskimage-builder can only
modify images without logical volumes, the following kickstart file
(input_image.ks) will create a Fedora 20 image that fits this criteria:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;url --url=http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/20/Fedora/x86_64/os/
# Without the Everything repo, we cannot install cloud-init
repo --name=&quot;fedora-everything&quot; --baseurl=http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/20/Everything/x86_64/os/
install
text
keyboard us
lang en_US.UTF-8
skipx
network --device eth0 --bootproto dhcp
rootpw ROOTPW
firewall --disabled
authconfig --enableshadow --enablemd5
selinux --enforcing
timezone --utc America/New_York
bootloader --location=mbr --append=&quot;console=tty0 console=ttyS0,115200&quot;
zerombr
clearpart --all --drives=vda
part / --fstype=&quot;ext4&quot; --size=3000
reboot

%packages
@core
cloud-init
tar

%end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following TDL template (input_image.tdl) is needed to build the input image:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;name&amp;gt;f20-jeos&amp;lt;/name&amp;gt;
  &amp;lt;os&amp;gt;
    &amp;lt;name&amp;gt;Fedora&amp;lt;/name&amp;gt;
    &amp;lt;version&amp;gt;20&amp;lt;/version&amp;gt;
    &amp;lt;arch&amp;gt;x86_64&amp;lt;/arch&amp;gt;
    &amp;lt;install type=&#39;url&#39;&amp;gt;
      &amp;lt;url&amp;gt;http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/20/Fedora/x86_64/os/&amp;lt;/url&amp;gt;
    &amp;lt;/install&amp;gt;
  &amp;lt;/os&amp;gt;
  &amp;lt;description&amp;gt;Fedora 20 JEOS Image&amp;lt;/description&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following command should be run from the directory where input_image.tdl
and input_image.ks live:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;imagefactory --debug base_image --file-parameter install_script input_image.ks input_image.tdl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please take note of the image id when ImageFactory finishes building input
image.
###Step 3: Create target image &lt;/p&gt;

&lt;p&gt;The indirection plugin takes the following parameters. Some of the parameters
have default values and as a result will not be present in the command used to
build the target image. However, they are discussed here so one can modify this
example in all possible ways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;–id&lt;/strong&gt; - The image id for the input image&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;–parameter utility_image&lt;/strong&gt; - The image id for utility image&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;–parameter input_image_device&lt;/strong&gt; - The name of the device where the base_image
is presented to the utility VM. Default is /dev/vdb1. The filesystem on this
device is also referred to as workspace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;–parameter input_image_file&lt;/strong&gt; - The path to the copy of input image in the
workspace. Default is /input_image.raw. Either input_image_device or
input_image_file can be provided at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;–parameter results_location&lt;/strong&gt; - Full path to the customized image in the
filesystem presented as work space. Default is /results/images/boot.iso&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;–file-parameter utility_customizations&lt;/strong&gt; - Name of file containing partial
TDL with commands to be exectuted after the utility image is launched in run
level 3&lt;/p&gt;

&lt;p&gt;The utility image is used to launch a VM in run level 3. The utility VM has an
unmounted filesystem attached as ‘/dev/vdb1’ or input_image_device with the
following characteristics:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The input image is available as ‘/input_image.raw’ or input_image_file&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Once the customization TDL has finished running the plugin expects to find
the resulting image at ‘/results/images/boot.iso’ or results_location. &lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The partial TDL (dib_overcloud_compute.tdl) below does the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Mounts the workspace filesystem to /mnt &lt;/li&gt;
  &lt;li&gt;Makes a copy of sudoers files&lt;/li&gt;
  &lt;li&gt;Modifies the sudoers file to disable requirement for tty when using sudo&lt;/li&gt;
  &lt;li&gt;Converts the input image from RAW to QCOW2 so diskimage-builder can consume
it&lt;/li&gt;
  &lt;li&gt;Runs all the commands needed to build the ovecloud-compute [1].
disk-image-create command takes -o argument which specifies the name of output
image. Since the workspace was mounted at /mnt the full path should be
‘/mnt/overloud-compute’ in order for the indirection plugin to find it at
/overcloud-compute.qcow2&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;[1] https://github.com/agroup/instack-undercloud/blob/instack-undercloud-0.0.13-1/scripts/instack-build-images#L65&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;template&amp;gt;
&amp;lt;commands&amp;gt;
   &amp;lt;command name=&#39;mount&#39;&amp;gt;mount /dev/vdb1 /mnt&amp;lt;/command&amp;gt;
   &amp;lt;command name=&#39;backup&#39;&amp;gt;cp /etc/sudoers /etc/sudoers_backup&amp;lt;/command&amp;gt;
   &amp;lt;command name=&#39;pty&#39;&amp;gt;sed &#39;s/.*requiretty//g&#39; /etc/sudoers_backup &amp;gt; /etc/sudoers&amp;lt;/command&amp;gt;
   &amp;lt;command name=&#39;convert&#39;&amp;gt;qemu-img convert -f raw -O qcow2 /mnt/input_image.raw /mnt/input_image.qcow2&amp;lt;/command&amp;gt;
   &amp;lt;command name=&quot;localimage&quot;&amp;gt;export DIB_LOCAL_IMAGE=/mnt/input_image.qcow2
set -eux
export TMP_DIR=${TMP_DIR:-/var/tmp}
export NODE_ARCH=${NODE_ARCH:-amd64}
export NODE_DIST=${NODE_DIST:-&quot;fedora selinux-permissive&quot;}
export DEPLOY_IMAGE_ELEMENT=${DEPLOY_IMAGE_ELEMENT:-deploy}
export DIB_INSTALLTYPE_nova=package
export DIB_INSTALLTYPE_heat=package
export DIB_INSTALLTYPE_keystone=package
export DIB_INSTALLTYPE_neutron=package
export DIB_INSTALLTYPE_glance=package
export DIB_INSTALLTYPE_swift=package
export DIB_INSTALLTYPE_cinder=package
export DIB_INSTALLTYPE_horizon=package
export DIB_INSTALLTYPE_python_cinderclient=package
export DIB_INSTALLTYPE_python_glanceclient=package
export DIB_INSTALLTYPE_python_heatclient=package
export DIB_INSTALLTYPE_python_keystoneclient=package
export DIB_INSTALLTYPE_python_neutronclient=package
export DIB_INSTALLTYPE_python_novaclient=package
export DIB_INSTALLTYPE_python_swiftclient=package
export DIB_INSTALLTYPE_python_ceilometerclient=package
export DIB_INSTALLTYPE_python_ironicclient=package
export DIB_INSTALLTYPE_os_collect_config=package
export DIB_INSTALLTYPE_os_refresh_config=package
export DIB_INSTALLTYPE_os_apply_config=package
export DIB_INSTALLTYPE_get_pip_py=package
export ELEMENTS_PATH=/usr/share/tripleo-image-elements:/usr/share/instack-undercloud
disk-image-create \
        --no-tmpfs \
        -a $NODE_ARCH \
        -o /mnt/overcloud-compute \
        $NODE_DIST pip-cache nova-compute nova-kvm neutron-openvswitch-agent os-collect-config \
        baremetal \
        dhcp-all-interfaces stackuser fedora-rdo-icehouse-repository \
        stable-interface-names&amp;lt;/command&amp;gt;
&amp;lt;/commands&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following command will execute the target image build:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;imagefactory --debug target_image --id [input_image_id] \
    --parameter utility_image [utility_image_id] \
    --file-parameter utility_customizations dib_overcloud_compute.tdl \
    --parameter results_location &quot;/overcloud-computer.qcow2&quot; indirection
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Introducing Nova Plugin</title>
   <link href="http://imgfac.org/blog/2014/07/25/introducing-nova-plugin"/>
   <updated>2014-07-25T00:00:00+00:00</updated>
   <id>http://imgfac.org/blog/2014/07/25/introducing-nova-plugin</id>
   <content type="html">&lt;p&gt;The &lt;a href=&quot;http://imgfac.org&quot;&gt;imagefactory&lt;/a&gt; approach to image creation has always been to use the native installer for an OS to create an image that has &lt;em&gt;“Just Enough OS”&lt;/em&gt;, customize that image by adding packages or running commands to create a base image, and then translating that base image into various formats compatible with a wide range of cloud/virtualization targets. These activities of creating the JEOS image, customizing, and converting are delegated out to plugins by imagefactory. While there have been a number of “cloud plugins” that allow imagefactory to work with numerous hypervisors and public clouds, there has only been one “OS plugin” and that is the TinMan plugin.&lt;/p&gt;

&lt;p&gt;The name comes from the plugin’s dependency on the &lt;a href=&quot;https://github.com/clalancette/oz/wiki&quot;&gt;Oz&lt;/a&gt; project to create the JEOS image. Oz is a powerful tool that has been stable, fast, and offers support for a wide range of Linux distributions along with limited support for creating Microsoft Windows images. Oz has worked so well that TinMan has been the only OS plugin for imagefactory since the plugin API was added to imagefactory in early 2012.&lt;/p&gt;

&lt;p&gt;While the Oz and TinMan have served us well, this combination has a couple of requirements the system running imagefactory must meet. Because Oz uses &lt;a href=&quot;http://libvirt.org&quot;&gt;libvirt&lt;/a&gt; and and TinMan uses &lt;a href=&quot;http://libguestfs.org&quot;&gt;libguestfs&lt;/a&gt;, imagefactory has been limited to running on systems that support these libraries. It also means that the system running imagefactory needs a fair amount of memory and storage to run installers in virtual machines and to store the images created. &lt;/p&gt;

&lt;p&gt;It’s true that imagefactory has the ability to talk to a remote imagefactory and have the remote instance do the heavy lifting. But we live in exciting times when projects like &lt;a href=&quot;http://www.openstack.org&quot;&gt;OpenStack&lt;/a&gt; have made it relatively easy to spin up our own clouds to pool together physical resources. With that available to us, why setup a system dedicated to building images? Using OpenStack directly allows us to break the tight dependency on libvirt and libguestfs and open up the possibility of running imagefactory on systems with fewer resources or systems that do not support those libraries. It also gives us a way to scale imagefactory for a higher number of concurrent builds by letting OpenStack manage the pool of physical resources.&lt;/p&gt;

&lt;h4 id=&quot;introducing-the-nova-plugin-for-imagefactory&quot;&gt;Introducing the Nova plugin for imagefactory:&lt;/h4&gt;

&lt;p&gt;The Nova plugin was written to allow imagefactory to benefit from access to an OpenStack infrastructure. Now, imagefactory can spawn an instance on OpenStack to run the OS installer. Once the JEOS installation is completed, the customization and creation of the base image is also done within OpenStack. The resulting base image can be used to create other OpenStack instances or it can be passed to one of the imagefactory Cloud plugins to be used on a different cloud or hypervisor.&lt;/p&gt;

&lt;p&gt;The Nova plugin is a drop in replacement for the TinMan plugin. It handles the same OS, version, architecture combinations. In order to use Nova instead of TinMan, you’ll want to remove the TinMan.info alias in /etc/imagefactory/plugins.d and make sure that Nova.info exists.&lt;/p&gt;

&lt;p&gt;Once installed, using the Nova plugin is mostly the same as building images with the TinMan plugin with some additional arguments and setup related to connecting to OpenStack.&lt;/p&gt;

&lt;p&gt;You’ll want to make sure that you have the common OpenStack environment variables set where you are running imagefactory. These are &lt;code&gt;OS_AUTH_URL&lt;/code&gt;, &lt;code&gt;OS_TENANT_NAME&lt;/code&gt;, &lt;code&gt;OS_USERNAME&lt;/code&gt;, and &lt;code&gt;OS_PASSWORD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If instances in the OpenStack you are connecting to require the instance to request a floating IP address instead of automatically assigning one, you’ll want to pass the &lt;code&gt;request_floating_ip&lt;/code&gt; option to imagefactory.&lt;/p&gt;

&lt;p&gt;Similarly, if instances have a default non-root user, you need to tell imagefactory what that username is using the option &lt;code&gt;default_user&lt;/code&gt; as well as how to run commands as a privileged user using the &lt;code&gt;command_prefix&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;Finally, you need to choose what instance flavor to use for installation and customization steps. The flavor id can be passed to imagefactory with the &lt;code&gt;flavor&lt;/code&gt; option.&lt;/p&gt;

&lt;h4 id=&quot;example&quot;&gt;Example:&lt;/h4&gt;

&lt;p&gt;So, let’s run through a quick example of building a base image using the Nova plugin. We’ll build a Fedora 19 for x86_64 using the following kickstart and TDL files.&lt;/p&gt;

&lt;p&gt;We’ll use this kickstart file to setup the instance and specify the repository to use for installing over the network:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;url --url=http://download.fedoraproject.org/pub/fedora/linux/releases/19/Fedora/x86_64/os
# Without the Everything repo, we cannot install cloud-init
repo --name=&quot;fedora-everything&quot; --baseurl=http://download.fedoraproject.org/pub/fedora/linux/releases/19/Everything/x86_64/os/
install
text
keyboard us
lang en_US.UTF-8
skipx
network --device eth0 --bootproto dhcp
rootpw myrootpw
firewall --disabled
authconfig --enableshadow --enablemd5
selinux --enforcing
timezone --utc America/New_York
bootloader --location=mbr
zerombr
clearpart --all --drives=vda

part biosboot --fstype=biosboot --size=1 --ondisk=vda
part /boot --fstype ext4 --size=200 --ondisk=vda
part pv.2 --size=1 --grow --ondisk=vda
volgroup VolGroup00 --pesize=32768 pv.2
logvol swap --fstype swap --name=LogVol01 --vgname=VolGroup00 --size=768 --grow --maxsize=1536
logvol / --fstype ext4 --name=LogVol00 --vgname=VolGroup00 --size=1024 --grow
poweroff

bootloader --location=mbr --timeout=5 --append=&quot;rhgb quiet&quot;

%packages
@core
cloud-init

%end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This simple TDL file just specifies what OS and version we’re building in order to select the correct OS plugin. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;name&amp;gt;f19&amp;lt;/name&amp;gt;
  &amp;lt;os&amp;gt;
    &amp;lt;name&amp;gt;Fedora&amp;lt;/name&amp;gt;
    &amp;lt;version&amp;gt;19&amp;lt;/version&amp;gt;
    &amp;lt;arch&amp;gt;x86_64&amp;lt;/arch&amp;gt;
    &amp;lt;rootpw&amp;gt;test&amp;lt;/rootpw&amp;gt;
    &amp;lt;install type=&#39;url&#39;&amp;gt;
      &amp;lt;url&amp;gt;http://download.fedoraproject.org/pub/fedora/linux/releases/19/Fedora/x86_64/os&amp;lt;/url&amp;gt;
    &amp;lt;/install&amp;gt;
  &amp;lt;/os&amp;gt;
  &amp;lt;disk&amp;gt;
    &amp;lt;size&amp;gt;20&amp;lt;/size&amp;gt;
  &amp;lt;/disk&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We’ll pass those two files to imagefactory using a command like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;imagefactory base_image \
 --file-parameter install_script f19.ks \
 --parameter request_floating_ip True \
 --parameter default_user ec2-user \
 --parameter command_prefix sudo \
 --parameter flavor 2 f19.tdl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A number of steps are completed as an image is built:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;First any images needed to boot into the installation are created or downloaded.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Once a bare bones installation is completed, the instance is shutdown and a snapshot is taken before terminating the instance.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A new instance is spawned from the snapshot and imagefactory installs any packages and/or runs any commands specified in the TDL by issuing commands via a series of ssh connections.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Once customization is complete, an ICICLE document is created that lists all of the packages installed before shutting down this second instance.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A snapshot is taken before terminating the instance.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upon completion of these steps, imagefactory will report that the image has been created successfully and provide the UUID for reference. We can then pass this UUID when creating a target image for another cloud or hypervisor or we can use the final snapshot in OpenStack to spawn new instances.&lt;/p&gt;

&lt;p&gt;Here is an example of the final output from imagefactory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;============ Final Image Details ============
UUID: bdd32b97-0e94-473a-b376-74d2da289a2c
Type: base_image
Image filename: /var/lib/imagefactory/storage/bdd32b97-0e94-473a-b376-74d2da289a2c.body
Image build completed SUCCESSFULLY!
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;getting-the-plugin&quot;&gt;Getting the plugin:&lt;/h4&gt;

&lt;p&gt;The Nova plugin will be packaged and released with the 1.1.6 release of imagefactory. To start using this plugin now, pull the master branch from the imagefactory repository on GitHub.&lt;/p&gt;

&lt;p&gt;To see a demo of the plugin being installed and used, have a look at this video:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://youtu.be/UiJmF5iC8KI&quot;&gt;Introduction to the Nova plugin for Image Factory&lt;/a&gt;&lt;/p&gt;

&lt;div&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube-nocookie.com/embed/UiJmF5iC8KI?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Floss Weekly 231</title>
   <link href="http://imgfac.org/blog/2012/11/01/floss-weekly-231"/>
   <updated>2012-11-01T00:00:00+00:00</updated>
   <id>http://imgfac.org/blog/2012/11/01/floss-weekly-231</id>
   <content type="html">&lt;p&gt;Ian and Steve met up with &lt;a href=&quot;http://thesourceshow.org/&quot;&gt;Aaron Newcomb&lt;/a&gt; and &lt;a href=&quot;http://danlynch.org/&quot;&gt;Dan Lynch&lt;/a&gt; yesterday to talk about imagefactory on FLOSS Weekly episode 231.&lt;/p&gt;

&lt;p&gt;You can download the interview (audio and video) from the podcast website:&lt;br /&gt;
&lt;a href=&quot;http://twit.tv/show/floss-weekly/231&quot; title=&quot;FLOSS Weekly on TWiT&quot;&gt;http://twit.tv/show/floss-weekly/231&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;or watch it on YouTube:&lt;br /&gt;
&lt;a href=&quot;http://www.youtube.com/watch?v=H5z-tpYS0Ng&quot; title=&quot;FLOSS Weekly episode 231 on YouTube&quot;&gt;http://www.youtube.com/watch?v=H5z-tpYS0Ng&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our thanks to the whole &lt;a href=&quot;http://twit.tv/floss&quot;&gt;FLOSS Weekly&lt;/a&gt; team for giving us a chance to talk about the project.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>V2 Coming Soon</title>
   <link href="http://imgfac.org/blog/2012/10/31/V2-coming-soon"/>
   <updated>2012-10-31T00:00:00+00:00</updated>
   <id>http://imgfac.org/blog/2012/10/31/V2-coming-soon</id>
   <content type="html">&lt;p&gt;We have been working hard to get a stable release of imagefactory 2.0 released. There is still a bit of revision to be done on documentation (particularly the REST api and examples there). Watch this space for news as we get closer to release. Until then, release candidate RPMs are ready for testing.&lt;/p&gt;

</content>
 </entry>
 
 
</feed>
