/* $Id$ */
/** @file
* VirtualBox Main - OVF reader declarations.
*
* Depends only on IPRT, including the RTCString and IPRT XML classes.
*/
/*
* Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#ifndef ____H_OVFREADER
#define ____H_OVFREADER
#include <map>
{
////////////////////////////////////////////////////////////////////////////////
//
// Errors
//
////////////////////////////////////////////////////////////////////////////////
/**
* Thrown by OVFReader for any kind of error that is not an XML error but
* still makes the OVF impossible to parse. Based on xml::LogicError so
* that one catch() for all xml::LogicError can handle all possible errors.
*/
{
OVFLogicError(const char *aFormat, ...);
};
////////////////////////////////////////////////////////////////////////////////
//
// Enumerations
//
////////////////////////////////////////////////////////////////////////////////
/**
* CIM OS values.
*
* The OVF 1.10 spec refers to some CIM_OperatingSystem.mof doc. Could this be it:
*
* @todo r=bird: Why are the values are repeating 'CIMOS'. CIMOSType_T is also
* repeating it self, 'Type' and '_T'. Why not call it kCIOMOpSys,
* easier to read as well.
* Then also apply: s/CIMOSType_CIMOS_/kCIMOpSys_/g
*/
enum CIMOSType_T
{
// types added with CIM 2.25.0 follow:
// no new types added with CIM 2.26.0
};
enum OVFVersion_T
{
};
////////////////////////////////////////////////////////////////////////////////
//
// Envelope data
//
////////////////////////////////////////////////////////////////////////////////
struct EnvelopeData
{
{
return version;
}
{
if (version == OVFVersion_0_9)
return "0.9";
else if (version == OVFVersion_1_0)
return "1.0";
else if (version == OVFVersion_2_0)
return "2.0";
else
return "";
}
{
version = v;
}
};
struct FileReference
{
};
////////////////////////////////////////////////////////////////////////////////
//
// Hardware definition structs
//
////////////////////////////////////////////////////////////////////////////////
struct DiskImage
{
// fields from /DiskSection/Disk
// (maximum size for dynamic images, I guess; we always translate this to bytes)
// (actual used size of disk, always in bytes; can be an estimate of used disk
// space, but cannot be larger than iCapacity; -1 if not set)
// typically http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized
// then this has the UUID with which the disk was registered
// fields from /References/File; the spec says the file reference from disk can be empty,
// so in that case, strFilename will be empty, then a new disk should be created
RTCString strHref; // value from /References/File/@href (filename); if empty, then the remaining fields are ignored
int64_t iSize; // value from /References/File/@size (optional according to spec; then we set -1 here)
RTCString strCompression; // value from /References/File/@compression (optional, can be "gzip" according to spec)
// additional field which has a descriptive size in megabytes derived from the above; this can be used for progress reports
};
enum ResourceType_T
};
enum StorageAccessType_T
{ StorageAccessType_Unknown = 0,
};
enum ComplianceType_T
{ ComplianceType_No = 0,
};
{
bool fResourceRequired;
RTCString strHostResource; // "Abstractly specifies how a device shall connect to a resource on the deployment platform.
// Not all devices need a backing." Used with disk items, for which this references a virtual
// disk from the Disks section.
bool fAutomaticAllocation;
bool fAutomaticDeallocation;
RTCString strConnection; // "All Ethernet adapters that specify the same abstract network connection name within an OVF
// package shall be deployed on the same network. The abstract network connection name shall be
// listed in the NetworkSection at the outermost envelope level." We ignore this and only set up
// a network adapter depending on the network name.
RTCString strAddress; // "Device-specific. For an Ethernet adapter, this specifies the MAC address."
RTCString strAllocationUnits; // "Specifies the units of allocation used. For example, “byte * 2^20”."
uint64_t ullVirtualQuantity; // "Specifies the quantity of resources presented. For example, “256”."
uint64_t ullReservation; // "Specifies the minimum quantity of resources guaranteed to be available."
uint64_t ullWeight; // "Specifies a relative priority for this allocation in relation to other allocations."
: ulInstanceID(0),
fAutomaticAllocation(false),
fAutomaticDeallocation(false),
ullReservation(0),
ullLimit(0),
ullWeight(0),
ulBusNumber(0),
ulLineNumber(0)
{
itemName = "Item";
};
void setDefaultFlag()
{
fDefault = true;
}
bool isThereDefaultValues() const
{
return fDefault;
}
{
}
{
return _getItemName();
}
bool fDefault;//true means that some fields were absent in the XML and some default values were assigned to.
{
return itemName;
}
};
{
//see DMTF Schema Documentation http://schemas.dmtf.org/wbem/cim-html/2/
hostExtentNameFormat(-1),
limit(-1),
reservation(-1),
virtualQuantity(-1),
{
itemName = "StorageItem";
};
{
return itemName;
}
};
{
//see DMTF Schema Documentation http://schemas.dmtf.org/wbem/cim-html/2/
bool Promiscuous;
{
itemName = "EthernetPortItem";
};
{
return itemName;
}
};
struct VirtualSystem;
struct HardDiskController
{
// controller subtype (Item/ResourceSubType); e.g. "LsiLogic"; can be empty (esp. for IDE)
// note that we treat LsiLogicSAS as a SCSI controller (system == SCSI) even though VirtualBox
// treats it as a fourth class besides IDE, SATA, SCSI
// be true for the first controller of this type (e.g. IDE primary ctler) or
// false for the next (e.g. IDE secondary ctler)
: idController(0),
lAddress(0),
fPrimary(true)
{ }
};
struct VirtualDisk
{
// this must match HardDiskController.idController and
// points into VirtualSystem.mapControllers
// and possibly higher for disks attached to SCSI controllers (untested)
// this receives the <id> component; points to one of the
// references in Appliance::Data.mapDisks
bool fEmpty;//true - empty disk, e.g. the component <rasd:HostResource>...</rasd:HostResource> is absent.
};
/**
* A list of EthernetAdapters is contained in VirtualSystem, representing the
* ethernet adapters in the virtual system.
*/
struct EthernetAdapter
{
};
/**
* A list of VirtualSystem structs is created by OVFReader::read(). Each refers to
* a <VirtualSystem> block in the OVF file.
*/
struct VirtualSystem
{
RTCString strVirtualSystemType; // generic hardware description; OVF says this can be something like "vmx-4" or "xen";
// VMware Workstation 6.5 is "vmx-07"
EthernetAdaptersList llEthernetAdapters; // (one for each VirtualSystem/Item[@ResourceType=10]element)
// list of hard disk controllers
// (one for each VirtualSystem/Item[@ResourceType=6] element with accumulated data from children)
// (one for each VirtualSystem/Item[@ResourceType=17] element with accumulated data from children)
bool fHasCdromDrive; // true if there's a CD-ROM item in mapHardwareItems; ISO images are not yet supported by OVFtool
RTCString strSoundCardType; // if not empty, then the system wants a soundcard; this then specifies the hardware;
// VMware Workstation 6.5 uses "ensoniq1371" for example
RTCString strLicenseText; // license info if any; receives contents of VirtualSystem/EulaSection/License
RTCString strProduct; // product info if any; receives contents of VirtualSystem/ProductSection/Product
RTCString strVendor; // product info if any; receives contents of VirtualSystem/ProductSection/Vendor
RTCString strVersion; // product info if any; receives contents of VirtualSystem/ProductSection/Version
RTCString strProductUrl; // product info if any; receives contents of VirtualSystem/ProductSection/ProductUrl
RTCString strVendorUrl; // product info if any; receives contents of VirtualSystem/ProductSection/VendorUrl
const xml::ElementNode *pelmVBoxMachine; // pointer to <vbox:Machine> element under <VirtualSystem> element or NULL if not present
ullMemorySize(0),
cCPUs(1),
fHasFloppyDrive(false),
fHasCdromDrive(false),
fHasUsbController(false),
{
}
};
////////////////////////////////////////////////////////////////////////////////
//
// Class OVFReader
//
////////////////////////////////////////////////////////////////////////////////
/**
* OVFReader attempts to open, read in and parse an OVF XML file. This is all done
* in the constructor; if there is any kind of error in the file -- filesystem error
* from IPRT, XML parsing errors from libxml, or OVF logical errors --, exceptions
* are thrown. These are all based on xml::Error.
*
* Hence, use this class as follows:
<code>
OVFReader *pReader = NULL;
try
{
}
catch (xml::Error &e)
{
printf("A terrible thing happened: %s", e.what());
}
// now go look at pReader->m_llVirtualSystem and what's in there
if (pReader)
delete pReader;
</code>
*/
{
// Data fields
std::list<VirtualSystem> m_llVirtualSystems; // list of virtual systems, created by and valid after read()
void parse();
void HandleDiskSection(const xml::ElementNode *pReferencesElem, const xml::ElementNode *pSectionElem);
};
} // end namespace ovf
#endif // !____H_OVFREADER