Common OVF Tool (COT)

Introduction

Build Status Coverage Status Documentation Status

COT (the Common OVF Tool) is a tool for editing Open Virtualization Format (.ovf, .ova) virtual appliances, with a focus on virtualized network appliances such as the Cisco CSR 1000V and Cisco IOS XRv platforms.

COT’s capabilities include:

  • Add a disk or other file to an OVF/OVA
  • Edit OVF hardware information (CPUs, RAM, NICs, configuration profiles, etc.)
  • Edit product description information in an OVF/OVA
  • Edit OVF environment properties
  • Display a descriptive summary of the contents of an OVA or OVF package
  • Embed a bootstrap configuration text file into an OVF/OVA.
  • Deploy an OVF/OVA to an ESXi (VMware vSphere or vCenter) server to provision a new virtual machine (VM).

Examples

Displaying a summary of OVA contents:

> cot info --brief iosxrv.5.1.1.ova
---------------------------------------------------------------------------
iosxrv.5.1.1.ova
COT detected platform type: Cisco IOS XRv
---------------------------------------------------------------------------
Product:  Cisco IOS XRv
Vendor:   Cisco Systems, Inc.
Version:  5.1.1

Files and Disks:     File Size  Capacity Device
                     --------- --------- --------------------
  iosxrv.vmdk        271.59 MB   3.00 GB harddisk @ IDE 0:0

Hardware Variants:
  System types:             vmx-08 Cisco:Internal:VMCloud-01
  Ethernet device types:    E1000

Configuration Profiles:   CPUs    Memory NICs Serials Disks/Capacity
                          ---- --------- ---- ------- --------------
  1CPU-3GB-2NIC (default)    1   3.00 GB    2       2  1 /   3.00 GB
  2CPU-4GB-8NIC              2   4.00 GB    8       2  1 /   3.00 GB
  4CPU-6GB-10NIC             4   6.00 GB   10       2  1 /   3.00 GB

Adding a custom hardware configuration profile to an OVA:

> cot edit-hardware csr1000v.ova --output csr1000v_custom.ova \
      --profile 1CPU-4GB --cpus 1 --memory 4GB

Customizing OVF environment properties:

> cot edit-properties csr1000v.ova --output csr1000v_custom.ova \
      --properties mgmt-ipv4-addr=10.1.1.100/24 \
                   mgmt-ipv4-gateway=10.1.1.1

Installing COT

System requirements

  • COT requires either Python 2.7 or Python 3.2 or later.
  • COT is tested to work under Mac OS X and Ubuntu Linux and similar distros.
  • COT now has limited support for CentOS and Python 2.6 as well.
  • Certain COT features require helper programs - these will typically be installed automatically when installing COT:
    • COT uses qemu-img as a helper program for various operations involving the creation, inspection, and modification of hard disk image files packaged in an OVF.
    • The cot add-disk command requires either qemu-img (version 2.1 or later) or vmdktool as a helper program when adding hard disks to an OVF.
    • The cot inject-config command requires mkisofs to create ISO (CD-ROM) images and/or fatdisk to create hard disk images.
    • The cot deploy ... esxi command requires ovftool to communicate with an ESXi server. If ovftool is installed, COT’s automated unit tests will also make use of ovftool to perform additional verification that OVFs and OVAs created by COT align with VMware’s expectations for these file types.

Mac OS X installation

The recommended installation method on Mac OS X is to use MacPorts. Once you have MacPorts set up on your system, all you have to do is:

sudo port install cot

Optionally, download ovftool from VMware and install it. (VMware requires a site login to download ovftool, which is the only reason I haven’t automated this too...)

Linux installation

The simplest installation path (assuming you have Python 2.6 or later and Git installed already) is as follows:

git clone git://github.com/glennmatthews/cot
cd cot
python ./setup.py build
sudo python ./setup.py install

If you can’t install or use Git for whatever reason, you can download via HTTP instead:

wget -O cot.tgz https://github.com/glennmatthews/cot/archive/master.tar.gz
tar zxf cot.tgz
cd cot-master
python setup.py build
sudo python setup.py install

The specifics may vary depending on your Linux distribution, of course. For more details, see Linux installation in detail.

Linux installation in detail

Detailed installation instructions for Linux if the basic instructions from Installing COT are insufficient.

Check installed Python version

Make sure your Python version is ideally at least 2.7 or 3.2:

> python --version
Python 2.7.4

CentOS in particular defaults to Python 2.6 - COT can be installed and run under Python 2.6 but this is not optimal. See below for more details.

Download COT

You can download COT via either HTTP or via Git.

Downloading COT via HTTP

To download the latest bleeding-edge version:

wget -O cot.tgz https://github.com/glennmatthews/cot/archive/master.tar.gz
tar zxf cot.tgz
cd cot-master

To download a specific stable release (in this example, v1.2.1):

wget -O cot.tgz https://github.com/glennmatthews/cot/archive/v1.2.1.tar.gz
tar zxf cot.tgz
cd cot-1.2.1
Downloading COT via Git

Under Ubuntu and similar, you may need to run sudo apt-get install git. Under CentOS and similar, you may need to run sudo yum install git.

Make a local clone of the Git repository:

git clone git://github.com/glennmatthews/cot
cd cot

This will default to the latest bleeding-edge version. If you want a specific stable release, use the following command to select to the desired release (for example, version 1.2.1):

git checkout tags/v1.2.1
Build COT

While you can run COT directly from this directory (./bin/cot ...), you can also use the included setup.py script to install the COT modules and scripts as part of your system Python environment. In that case, build and test COT as follows:

> python ./setup.py check
running check
> python ./setup.py build
running build
running build_py
Install helper programs

Once you have verified your Python version, run the following command to check for and install the various helper programs COT relies upon.

sudo python ./setup.py install_helpers

If any helpers are missing, the script will warn you and give you an option to attempt to automatically install them. If it tries and fails to do so, it will point you to the web site for the failed tool - but please post an issue on GitHub (https://github.com/glennmatthews/cot/issues) so that we can identify the failure and work to improve this script.

If for some reason you do not wish to use the above script, or would like to understand exactly what it’s doing, see the following sections:

In any case, once the helper tools you need are installed, you can proceed to Install COT.

Install qemu-img
  • Ubuntu and similar: sudo apt-get install qemu
  • CentOS and similar: sudo yum install qemu-img

See http://en.wikibooks.org/wiki/QEMU/Installing_QEMU for other Linux variants.

Install vmdktool (if needed)

First, check your QEMU version to see if you even need vmdktool:

$ qemu-img --version | grep " version"
qemu-img version 2.1.0, Copyright (c) 2004-2008 Fabrice Bellard

If the reported version is 2.1.0 or newer, you don’t need vmdktool. If you have an older QEMU version and do need vmdktool:

  1. Install make and the library zlib that vmdktool depends on:
  • Ubuntu and similar: sudo apt-get install make, sudo apt-get install zlib1g-dev
  • CentOS and similar: sudo yum install make, sudo yum install zlib-devel
  1. Download the latest source distribution from http://people.freebsd.org/~brian/vmdktool:

    wget http://people.freebsd.org/~brian/vmdktool/vmdktool-1.4.tar.gz
    
  2. Compile vmdktool:

    tar zxf vmdktool-1.4.tar.gz
    cd vmdktool-1.4/
    make CFLAGS="-D_GNU_SOURCE"
    
  3. Install vmdktool:

    sudo mkdir -p /usr/local/man/man8
    sudo make install
    
Install fatdisk (optional)

You only need fatdisk if you are planning to use cot inject-config to inject bootstrap configuration for a platform that requires a hard disk image rather than a CD-ROM image for its bootstrap disk. Currently the only such platform known to COT is Cisco IOSv.

  1. Download the latest source distribution.

    git clone git://github.com/goblinhack/fatdisk
    cd fatdisk
    

    or (if you didn’t install git or it is blocked for you)

    wget -O fatdisk.tgz https://github.com/goblinhack/fatdisk/archive/master.tar.gz
    tar zxf fatdisk.tgz
    cd fatdisk-master
    
  2. Compile fatdisk

    ./RUNME
    
  3. Install the fatdisk binary to somewhere in your $PATH, for example:

    sudo cp ./fatdisk /usr/local/bin/fatdisk
    
Install mkisofs or genisoimage (optional)

mkisofs or the similar genisoimage are standard on most Linux distributions. These are used by COT primarily for creation of ISO images as part of the cot inject-config command for various platforms, so if you are not using that command, these tools are optional.

  • Ubuntu and similar: sudo apt-get install genisoimage
  • CentOS and similar: sudo yum install genisoimage
  • Others: http://cdrecord.org/
Install ovftool (optional)

If you want to validate OVFs against VMware’s expectations, or if you want to use the cot deploy esxi command, you need ovftool. Otherwise it is not required.

If desired, you can download ovftool from https://www.vmware.com/support/developer/ovf/ This will require creating a user account for VMware.com if you do not have one already. Once downloaded, install it according to the included instructions.

Install COT
  1. Before installing COT, if you want to, you can run its built-in unit tests as follows:

    > python ./setup.py test
    running test
    

    (verbose test case output omitted here for brevity)

    ----------------------------------------------------------------------
    Ran 136 tests in 41.130s
    
    OK
    

    Note that under Python 2.6 (i.e., CentOS) this test will report numerous test skips at present as the XML generated by Python 2.6 is structured differently (but still valid!) from the XML generated by 2.7 and later, and the unit tests do not presently support this variance.

    If any tests fail, likely due to missing optional dependencies described above, the failures will be reported here, giving you a chance to fix them or ignore them before installing COT.

  2. Install COT:

    > sudo python ./setup.py install
    Password:
    running install
    

    (verbose install output omitted)

    Installing cot script to /usr/local/bin
    
    Installed /usr/local/lib/python2.7/dist-packages/common_ovf_tool-1.2.1-py2.7.egg
    Processing dependencies for common-ovf-tool==1.2.1
    Finished processing dependencies for common-ovf-tool==1.2.1
    > which cot
    /usr/local/bin/cot
    

    (the specific installation path will depend on your OS and system)

    > cot -h
    usage:
      cot --help
      cot --version
      cot <command> --help
      cot [-f] [-v] <command> <options>
    
    Common OVF Tool (COT), version 1.2.1
    Copyright (C) 2013-2015 the COT project developers
    A tool for editing Open Virtualization Format (.ovf, .ova) virtual appliances,
    with a focus on virtualized network appliances such as the Cisco CSR 1000V and
    Cisco IOS XRv platforms.
    ...
    

Optionally, download ovftool from VMware and install it. (VMware requires a site login to download ovftool, which is the only reason I haven’t automated this too...)

Using COT

Getting CLI help

You can always get detailed help for COT by running cot --help, cot <command> --help, or cot help <command>.

> cot --help
usage:
  cot --help
  cot --version
  cot help <command>
  cot <command> --help
  cot <options> <command> <command-options>

Common OVF Tool (COT), version 1.2.1
Copyright (C) 2013-2015 the COT project developers.
A tool for editing Open Virtualization Format (.ovf, .ova) virtual
appliances, with a focus on virtualized network appliances such as the
Cisco CSR 1000V and Cisco IOS XRv platforms.

optional arguments:
  -h, --help        show this help message and exit
  -V, --version     show program's version number and exit
  -f, --force       Perform requested actions without prompting for
                    confirmation
  -q, --quiet       Quiet output and logging (warnings and errors only)
  -v, --verbose     Verbose output and logging
  -vv, -d, --debug  Debug (most verbose) output and logging

commands:
  <command>
    add-disk        Add a disk image to an OVF package and map it as a
                    disk in the guest environment
    add-file        Add a file to an OVF package
    deploy          Create a new VM on the target hypervisor from the
                    given OVF
    edit-hardware   Edit virtual machine hardware properties of an OVF
    edit-product    Edit product info in an OVF
    edit-properties
                    Edit environment properties of an OVF
    info            Generate a description of an OVF package
    inject-config   Inject a configuration file into an OVF package
    help            Print help for a command

Note: some subcommands rely on external software tools, including:
* qemu-img (http://www.qemu.org/)
* mkisofs  (http://cdrecord.org/)
* ovftool  (https://www.vmware.com/support/developer/ovf/)
* fatdisk  (http://github.com/goblinhack/fatdisk)
* vmdktool (http://www.freshports.org/sysutils/vmdktool/)

Inspecting OVF contents with cot info

> cot info -h
usage:
  cot info --help
  cot info [-b | -v] PACKAGE [PACKAGE ...]

Show a summary of the contents of the given OVF(s) and/or OVA(s).

positional arguments:
  PACKAGE [PACKAGE ...]
                        OVF descriptor(s) and/or OVA file(s) to describe

optional arguments:
  -h, --help            show this help message and exit
  -b, --brief           Brief output (shorter)
  -v, --verbose         Verbose output (longer)

Updating version information with cot edit-product

> cot edit-product --help
usage:
  cot edit-product --help
  cot <opts> edit-product PACKAGE [-o OUTPUT] [-v SHORT_VERSION]
                          [-V FULL_VERSION]

Edit product information attributes of the given OVF or OVA

positional arguments:
  PACKAGE               OVF descriptor or OVA file to edit

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Name/path of new OVF/OVA package to create instead
                        of updating the existing OVF
  -v SHORT_VERSION, --version SHORT_VERSION
                        Software short version string, such as "15.3(4)S"
                        or "5.2.0.01I"
  -V FULL_VERSION, --full-version FULL_VERSION
                        Software long version string, such as "Cisco IOS-
                        XE Software, Version 15.3(4)S"

Adding disks to an OVF with cot add-disk

> cot add-disk --help
usage:
  cot add-disk --help
  cot <opts> add-disk DISK_IMAGE PACKAGE [-o OUTPUT] [-f FILE_ID]
                      [-t {harddisk,cdrom}] [-c {ide,scsi}] [-s SUBTYPE]
                      [-a ADDRESS] [-d DESCRIPTION] [-n DISKNAME]

Add or replace a disk image in the specified OVF or OVA. If the specified
disk image, controller/address, file-id, and/or instance match an existing
entry in the OVF, will replace the existing disk with the provided file
(prompting for confirmation if --force was not set); otherwise, will
create a new disk entry.

positional arguments:
  DISK_IMAGE            Disk image file to add to the package
  PACKAGE               OVF descriptor or OVA file to edit

general options:
  -h, --help            Show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Name/path of new OVF/OVA package to create instead
                        of updating the existing OVF

disk-related options:
  -f FILE_ID, --file-id FILE_ID
                        Disk image file ID string within the OVF package
                        (default: use disk image filename)
  -t {harddisk,cdrom}, --type {harddisk,cdrom}
                        Disk type (default: files ending in
                        .vmdk/.raw/.qcow2/.img will use harddisk and files
                        ending in .iso will use cdrom)

controller-related options:
  -c {ide,scsi}, --controller {ide,scsi}
                        Disk controller type (default: determined by disk
                        type and platform)
  -a ADDRESS, --address ADDRESS
                        Address of the disk, such as "1:0". Requires that
                        --controller be explicitly set. (default: use
                        first unused address on the controller)
  -s SUBTYPE, --subtype SUBTYPE
                        Disk controller subtype such as "virtio" or
                        "lsilogic".

descriptive options:
  -d DESCRIPTION, --description DESCRIPTION
                        Description of this disk (optional)
  -n DISKNAME, --name DISKNAME
                        Name of this disk (default: "Hard disk #" or "CD-
                        ROM #" as appropriate)

Packaging additional files into an OVF with cot add-file

> cot add-file --help
usage:
  cot add-file --help
  cot <opts> add-file FILE PACKAGE [-o OUTPUT] [-f FILE_ID]

Add or replace a file in the given OVF. If the specified file and/or file-
id match existing package contents, will replace it (prompting for
confirmation if --force was not set); otherwise, will create a new file
entry.

positional arguments:
  FILE                  File to add to the package
  PACKAGE               Package, OVF descriptor or OVA file to edit

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Name/path of new VM package to create instead of
                        updating the existing package
  -f FILE_ID, --file-id FILE_ID
                        File ID string within the package (default: same
                        as filename)

Customizing hardware profiles with cot edit-hardware

> cot edit-hardware --help
usage:
  cot edit-hardware --help
  cot <opts> edit-hardware PACKAGE [-o OUTPUT] -v TYPE [TYPE2 ...]
  cot <opts> edit-hardware PACKAGE [-o OUTPUT] [-p PROFILE [PROFILE2 ...]]
                           [-c CPUS] [-m MEMORY] [-n NICS]
                           [--nic-type {e1000,virtio,vmxnet3}]
                           [-N NETWORK [NETWORK2 ...]] [-M MAC1 [MAC2 ...]]
                           [--nic-names NAME1 [NAME2 ...]] [-s SERIAL_PORTS]
                           [-S URI1 [URI2 ...]]
                           [--scsi-subtype SCSI_SUBTYPE]
                           [--ide-subtype IDE_SUBTYPE]

Edit hardware properties of the specified OVF or OVA

positional arguments:
  PACKAGE               OVF descriptor or OVA file to edit

general options:
  -h, --help            Show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Name/path of new OVF/OVA package to create instead
                        of updating the existing OVF
  -v TYPE [TYPE2 ...], --virtual-system-type TYPE [TYPE2 ...]
                        Change virtual system type(s) supported by this
                        OVF/OVA package.
  -p PROFILE [PROFILE2 ...], --profiles PROFILE [PROFILE2 ...]
                        Make hardware changes only under the given
                        configuration profile(s). (default: changes apply
                        to all profiles)

computational hardware options:
  -c CPUS, --cpus CPUS  Set the number of CPUs.
  -m MEMORY, --memory MEMORY
                        Set the amount of RAM. (Examples: "4096MB", "4GB")

network interface options:
  -n NICS, --nics NICS  Set the number of NICs.
  --nic-type {e1000,virtio,vmxnet3}
                        Set the hardware type for all NICs. (default: do
                        not change existing NICs, and new NICs added will
                        match the existing type.)
  -N NETWORK [NETWORK2 ...], --nic-networks NETWORK [NETWORK2 ...]
                        Specify a series of one or more network names to
                        map NICs to. If N network names are specified, the
                        first (N-1) NICs will be mapped to the first (N-1)
                        networks and all remaining NICs will be mapped to
                        the Nth network.
  -M MAC1 [MAC2 ...], --mac-addresses-list MAC1 [MAC2 ...]
                        Specify a list of MAC addresses for the NICs. If N
                        MACs are specified, the first (N-1) NICs will
                        receive the first (N-1) MACs, and all remaining
                        NICs will receive the Nth MAC
  --nic-names NAME1 [NAME2 ...]
                        Specify a list of one or more NIC names or
                        patterns to apply to NIC devices. If N
                        names/patterns are specified, the first (N-1) NICs
                        will receive the first (N-1) names and remaining
                        NICs will be named based on the name or pattern of
                        the Nth item. See examples.

serial port options:
  -s SERIAL_PORTS, --serial-ports SERIAL_PORTS
                        Set the number of serial ports.
  -S URI1 [URI2 ...], --serial-connectivity URI1 [URI2 ...]
                        Specify a series of connectivity strings (URIs
                        such as "telnet://localhost:9101") to map serial
                        ports to. If fewer URIs than serial ports are
                        specified, the remaining ports will be unmapped.

disk and disk controller options:
  --scsi-subtype SCSI_SUBTYPE
                        Set resource subtype (such as "lsilogic" or
                        "virtio") for all SCSI controllers. If an empty
                        string is provided, any existing subtype will be
                        removed.
  --ide-subtype IDE_SUBTYPE
                        Set resource subtype (such as "virtio") for all
                        IDE controllers. If an empty string is provided,
                        any existing subtype will be removed.

Examples:
  cot edit-hardware csr1000v.ova --output csr1000v_custom.ova \
        --profile 1CPU-4GB --cpus 1 --memory 8GB
    Create a new profile named "1CPU-8GB" with 1 CPU and 8 gigabytes of RAM

  cot edit-hardware input.ova -o output.ova --nic-names "mgmt" "eth{0}"
    Rename the NICs in the output OVA as 'mgmt', 'eth0', 'eth1', 'eth2'...

  cot edit-hardware input.ova -o output.ova --nic-names "Ethernet0/{10}"
    Rename the NICs in the output OVA as 'Ethernet0/10', 'Ethernet0/11',
    'Ethernet0/12', etc.

Customizing OVF environment settings with cot edit-properties

> cot edit-properties --help
usage:
  cot edit-properties --help
  cot <opts> edit-properties PACKAGE -p KEY1=VALUE1 [KEY2=VALUE2 ...]
                             [-o OUTPUT]
  cot <opts> edit-properties PACKAGE -c CONFIG_FILE [-o OUTPUT]
  cot <opts> edit-properties PACKAGE [-o OUTPUT]

Configure environment properties of the given OVF or OVA. The user may
specify key-value pairs as command-line arguments or may provide a config-
file to read from. If neither are specified, the program will run
interactively.

positional arguments:
  PACKAGE               OVF descriptor or OVA file to edit

general options:
  -h, --help            Show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Name/path of new OVF/OVA package to create instead
                        of updating the existing OVF

property setting options:
  -c CONFIG_FILE, --config-file CONFIG_FILE
                        Read configuration CLI from this text file and
                        generate generic properties for each line of CLI
  -p KEY1=VALUE1 [KEY2=VALUE2 ...], --properties KEY1=VALUE1 [KEY2=VALUE2 ...]
                        Set the given property key-value pair(s). This
                        argument may be repeated as needed to specify
                        multiple properties to edit.

Embedding bootstrap configuration with cot inject-config

> cot inject-config -h
usage:
  cot inject-config --help
  cot <opts> inject-config PACKAGE -c CONFIG_FILE [-o OUTPUT]
  cot <opts> inject-config PACKAGE -s SECONDARY_CONFIG_FILE [-o OUTPUT]
  cot <opts> inject-config PACKAGE -c CONFIG_FILE -s SECONDARY_CONFIG_FILE
                           [-o OUTPUT]

Add one or more "bootstrap" configuration file(s) to the given OVF or OVA.

positional arguments:
  PACKAGE               Package, OVF descriptor or OVA file to edit

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Name/path of new VM package to create instead of
                        updating the existing package
  -c CONFIG_FILE, --config-file CONFIG_FILE
                        Primary configuration text file to embed
  -s SECONDARY_CONFIG_FILE, --secondary-config-file SECONDARY_CONFIG_FILE
                        Secondary configuration text file to embed
                        (currently only supported in IOS XRv for admin
                        config)

Deploying an OVF to create a VM with cot deploy

> cot deploy --help
usage:
  cot deploy --help
  cot <opts> deploy PACKAGE esxi ...

Deploy a virtual machine to a specified server.

positional arguments:
  PACKAGE               OVF descriptor or OVA file
  hypervisors supported:
    esxi                Deploy to ESXi, vSphere, or vCenter

optional arguments:
  -h, --help            show this help message and exit

Creating a VM on VMware vCenter/vSphere with cot deploy esxi

> cot deploy PACKAGE esxi --help
usage:
  cot deploy PACKAGE esxi --help
  cot <opts> deploy PACKAGE esxi LOCATOR [-u USERNAME] [-p PASSWORD]
                                 [-c CONFIGURATION] [-n VM_NAME] [-P]
                                 [-N OVF1=HOST1 [-N OVF2=HOST2 ...]]
                                 [-d DATASTORE] [-o=OVFTOOL_ARGS]

Deploy OVF/OVA to ESXi/vCenter/vSphere hypervisor

positional arguments:
  LOCATOR               vSphere target locator. Examples: "192.0.2.100"
                        (deploy directly to ESXi server),
                        "192.0.2.101/mydatacenter/host/192.0.2.100"
                        (deploy via vCenter server)

optional arguments:
  -h, --help            show this help message and exit
  -u USERNAME, --username USERNAME
                        Server login username
  -p PASSWORD, --password PASSWORD
                        Server login password
  -c CONFIGURATION, --configuration CONFIGURATION
                        Use the specified configuration profile defined in
                        the OVF. If unspecified and the OVF has multiple
                        profiles, the user will be prompted or the default
                        configuration will be used.
  -n VM_NAME, --vm-name VM_NAME
                        Name to use for the VM (if applicable) and any
                        files created. If unspecified, the name of the OVF
                        will be used.
  -P, --power-on        Power on the created VM to begin booting
                        immediately.
  -N OVF_NET1=HOST_NET1 [OVF_NET2=HOST_NET2 ...]
                        Map networks named in the OVF to networks
                        (bridges, vSwitches, etc.) in the hypervisor
                        environment. This argument may be repeated as
                        needed to specify multiple mappings.
  -d DATASTORE, -ds DATASTORE, --datastore DATASTORE
                        ESXi datastore to use for the new VM
  -o OVFTOOL_ARGS, --ovftool-args OVFTOOL_ARGS
                        Quoted string describing additional CLI parameters
                        to pass through to "ovftool". Examples:
                        -o="--foo", --ovftool-args="--foo --bar"

Examples:
  cot deploy foo.ova esxi 192.0.2.100 -u admin -p admin -n test_vm
    Deploy to vSphere/ESXi server 192.0.2.100 with credentials admin/admin,
    creating a VM named 'test_vm' from foo.ova.

  cot deploy foo.ova esxi 192.0.2.100 -u admin -c 1CPU-2.5GB
    Deploy to vSphere/ESXi server 192.0.2.100, with username admin
    (prompting the user to input a password at runtime), creating a VM
    based on profile '1CPU-2.5GB' in foo.ova.

  cot deploy foo.ova esxi "192.0.2.100/mydc/host/192.0.2.1" \
        -u administrator -N "GigabitEthernet1=VM Network" \
        -N "GigabitEthernet2=myvswitch"
    Deploy to vSphere server 192.0.2.1 which belongs to datacenter 'mydc'
    on vCenter server 192.0.2.100, and map the two NIC networks to
    vSwitches. Note that in this case -u specifies the vCenter login
    username.

  cot deploy foo.ova esxi 192.0.2.100 -u admin -p password \
        --ovftool-args="--overwrite --acceptAllEulas"
    Deploy with passthrough arguments to ovftool.

Contributing to COT

Please do contribute! We only have a few simple requirements for diffs and pull requests.

Follow coding guidelines

Logging level usage

ERROR
Something is wrong (such as a violation of the OVF specification) but COT was able to attempt to recover. If recovery is not possible, you should raise an Error of appropriate type instead of logging an ERROR message.
WARNING
Something unexpected or risky happened that the user needs a heads-up about. This includes cases where the software had to make an uncertain choice on its own due to lack of information from the user.
INFO
Important status updates about normal operation of the software. As this is the lowest logging level enabled by default, you should keep the logs generated at this level relatively brief but meaningful.
VERBOSE
Detailed information of interest to an advanced or inquisitive user.
DEBUG
Highly detailed information only useful to a developer familiar with the code.

Coding style

To verify that your code meets applicable Python coding standards, use flake8 (pip install flake8):

cot/$ flake8
./COT/tests/ovf.py:180:80: E501 line too long (80 > 79 characters)
./COT/tests/ovf.py:184:77: F841 local variable 'ovf' is assigned to but never used
./COT/tests/ovf.py:184:80: E501 line too long (80 > 79 characters)
./COT/tests/ovf.py:196:40: F841 local variable 'ova' is assigned to but never used
./COT/tests/ovf.py:210:75: F841 local variable 'ovf' is assigned to but never used
./COT/ovf.py:776:5: E303 too many blank lines (2)

Fix any errors it reports, and run again until no errors are reported.

Add automated unit tests

Whether adding new functionality or fixing a bug, please add appropriate unit test case(s) under COT/tests/ to cover your changes. Your changes must pass all existing and new automated test cases before your code will be accepted.

You can run the COT automated tests under a single Python version by running python ./setup.py test.

For full testing under all supported versions as well as verifying code coverage for your tests, you should install tox (pip install tox) and coverage (pip install coverage) then run tox from the COT directory:

cot/$ tox
...
py26 runtests: commands[0] | coverage run --append setup.py test --quiet
...
py27 runtests: commands[0] | coverage run --append setup.py test --quiet
...
py32 runtests: commands[0] | coverage run --append setup.py test --quiet
...
py33 runtests: commands[0] | coverage run --append setup.py test --quiet
...
py34 runtests: commands[0] | coverage run --append setup.py test --quiet
...
pypy runtests: commands[0] | coverage run --append setup.py test --quiet
...
stats runtests: commands[0] | coverage combine
stats runtests: commands[1] | coverage report -i
Name                        Stmts   Miss  Cover
-----------------------------------------------
COT/__init__.py                 4      0   100%
COT/add_disk.py               147      1    99%
COT/add_file.py                50      0   100%
COT/cli.py                    143      6    96%
COT/data_validation.py         69      0   100%
COT/deploy.py                 142      5    96%
COT/edit_hardware.py          159      0   100%
COT/edit_product.py            36      0   100%
COT/edit_properties.py        104     40    62%
COT/helper_tools.py           171      3    98%
COT/info.py                    41      0   100%
COT/inject_config.py           87      2    98%
COT/ovf.py                   1586     52    96%
COT/platforms.py              173      0   100%
COT/submodule.py               80      2    98%
COT/ui_shared.py               24      0   100%
COT/vm_context_manager.py      12      0   100%
COT/vm_description.py         119      1    99%
COT/vm_factory.py              25      0   100%
COT/xml_file.py               112      0   100%
-----------------------------------------------
TOTAL                        3284    112    96%
stats runtests: commands[2] | coverage html -i
...
flake8 runtests: commands[0] | flake8
_______________ summary _______________
  clean: commands succeeded
  py26: commands succeeded
  py27: commands succeeded
  py32: commands succeeded
  py33: commands succeeded
  py34: commands succeeded
  pypy: commands succeeded
  stats: commands succeeded
  flake8: commands succeeded
  congratulations :)

After running tox you can check the code coverage details by opening htmlcov/index.html in a web browser.

Update documentation

If you add or change any COT CLI or APIs, or add or remove any external dependencies, please update the relevant documentation.

Add yourself as a contributor

If you haven’t contributed to COT previously, be sure to add yourself as a contributor in the COPYRIGHT.txt file.

Credits

We would like to thank:

  • For evangelization, user feedback and bug reports:
    • Mark Coverdill
    • Jonathan Muslow
    • Rick Ogg
    • David Rosenfeld
    • Perumal Venkatesh
  • For initial design review and comments:
    • Andy Dalton
    • Jusheng Feng
    • Doug Gordon
    • Lina Long
    • Neil McGill
    • Vinod Pandarinathan
    • Rich Wellum
  • For providing managerial support for the development and release of COT as open source:
    • Ray Romney
    • Sanjeev Tondale
    • Taskin Ucpinar
  • Rich Wellum, for creating “Build, Deploy, Execute OVA” (bdeo.sh), the precursor to COT.
  • Neil McGill, for creating and maintaining fatdisk
  • Brian Somers, for creating and maintaining vmdktool

COT package reference

The below documents describe in depth the code structure and APIs of COT. These are not generally of interest to the end users of the COT script, but are provided for reference of developers wishing to integrate the COT package directly into their code.

Package implementing the Common OVF Tool.

Virtual machine definition modules

COT.vm_description Abstract superclass for reading, editing, and writing VMs.
COT.vm_factory Factory for virtual machine objects.
COT.vm_context_manager Context manager for virtual machine definitions.
COT.xml_file Reading, editing, and writing XML files.
COT.ovf Module for handling OVF and OVA virtual machine description files.

Command modules

COT.submodule Parent classes for implementing COT subcommands.
COT.add_disk Module for adding disks to VMs.
COT.add_file Module for adding files to VM definitions.
COT.deploy Module for deploying VM descriptions to a hypervisor to instantiate VMs.
COT.edit_hardware Module for editing hardware details of a VM.
COT.edit_product Module for editing product information in a VM description.
COT.edit_properties Module for managing VM environment configuration properties.
COT.help Provide ‘help’ keyword for COT CLI.
COT.info Implements “info” subcommand.
COT.inject_config Implements “inject-config” command.

Helper library modules

COT.data_validation Various helpers for data sanity checks.
COT.helper_tools Third-party helper tools.
COT.platforms Handles behavior that varies between guest platforms.

User interface modules

COT.ui_shared Abstract user interface superclass.
COT.cli CLI entry point for the Common OVF Tool (COT) suite.

Indices and tables