VirtualBox

Changeset 27918 in vbox


Ignore:
Timestamp:
Mar 31, 2010 5:10:40 PM (14 years ago)
Author:
vboxsync
Message:

Main/OVF: import vbox:Machine XML within OVF, first batch (XML is parsed and machine config created, but COM Machine can't handle it yet)

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/settings.h

    r27857 r27918  
    350350 };
    351351 typedef std::list<NATRule> NATRuleList;
    352  
     352
    353353 struct NAT
    354354 {
     
    824824{
    825825public:
     826    com::Guid               uuid;
     827    com::Utf8Str            strName;
     828    bool                    fNameSync;
     829    com::Utf8Str            strDescription;
     830    com::Utf8Str            strOsType;
     831    com::Utf8Str            strStateFile;
     832    com::Guid               uuidCurrentSnapshot;
     833    com::Utf8Str            strSnapshotFolder;
     834    bool                    fTeleporterEnabled;
     835    uint32_t                uTeleporterPort;
     836    com::Utf8Str            strTeleporterAddress;
     837    com::Utf8Str            strTeleporterPassword;
     838    bool                    fRTCUseUTC;
     839
     840    bool                    fCurrentStateModified;      // optional, default is true
     841    RTTIMESPEC              timeLastStateChange;        // optional, defaults to now
     842    bool                    fAborted;                   // optional, default is false
     843
     844    Hardware                hardwareMachine;
     845    Storage                 storageMachine;
     846
     847    ExtraDataItemsMap       mapExtraDataItems;
     848
     849    SnapshotsList           llFirstSnapshot;            // first snapshot or empty list if there's none
     850
    826851    MachineConfigFile(const com::Utf8Str *pstrFilename);
    827852
    828853    bool operator==(const MachineConfigFile &m) const;
    829854
     855    void importMachineXML(const xml::ElementNode &elmMachine);
     856
     857    void write(const com::Utf8Str &strFilename);
     858    void buildMachineXML(xml::ElementNode &elmMachine);
     859
     860private:
    830861    void readNetworkAdapters(const xml::ElementNode &elmHardware, NetworkAdaptersList &ll);
    831862    void readCpuIdTree(const xml::ElementNode &elmCpuid, CpuIdLeafsList &ll);
     
    846877    void buildStorageControllersXML(xml::ElementNode &elmParent, const Storage &st);
    847878    void buildSnapshotXML(xml::ElementNode &elmParent, const Snapshot &snap);
    848     void buildMachineXML(xml::ElementNode &elmMachine);
    849879
    850880    void bumpSettingsVersionIfNeeded();
    851     void write(const com::Utf8Str &strFilename);
    852 
    853     com::Guid               uuid;
    854     com::Utf8Str            strName;
    855     bool                    fNameSync;
    856     com::Utf8Str            strDescription;
    857     com::Utf8Str            strOsType;
    858     com::Utf8Str            strStateFile;
    859     com::Guid               uuidCurrentSnapshot;
    860     com::Utf8Str            strSnapshotFolder;
    861     bool                    fTeleporterEnabled;
    862     uint32_t                uTeleporterPort;
    863     com::Utf8Str            strTeleporterAddress;
    864     com::Utf8Str            strTeleporterPassword;
    865     bool                    fRTCUseUTC;
    866 
    867     bool                    fCurrentStateModified;      // optional, default is true
    868     RTTIMESPEC              timeLastStateChange;        // optional, defaults to now
    869     bool                    fAborted;                   // optional, default is false
    870 
    871     Hardware                hardwareMachine;
    872     Storage                 storageMachine;
    873 
    874     ExtraDataItemsMap       mapExtraDataItems;
    875 
    876     SnapshotsList           llFirstSnapshot;            // first snapshot or empty list if there's none
    877 };
    878 
    879 
     881};
    880882
    881883} // namespace settings
  • trunk/include/iprt/cpp/xml.h

    r27418 r27918  
    438438
    439439    const char* getName() const;
    440     bool nameEquals(const char *pcsz) const;
     440    bool nameEquals(const char *pcszNamespace, const char *pcsz) const;
     441    bool nameEquals(const char *pcsz) const
     442    {
     443        return nameEquals(NULL, pcsz);
     444    }
    441445
    442446    const char* getValue() const;
     
    474478                         const char *pcszMatch = NULL) const;
    475479
    476     const ElementNode* findChildElement(const char *pcszMatch) const;
     480    const ElementNode* findChildElement(const char *pcszNamespace,
     481                                        const char *pcszMatch) const;
     482    const ElementNode* findChildElement(const char *pcszMatch) const
     483    {
     484        return findChildElement(NULL, pcszMatch);
     485    }
    477486    const ElementNode* findChildElementFromId(const char *pcszId) const;
    478487
  • trunk/src/VBox/Main/ApplianceImpl.cpp

    r27908 r27918  
    964964    /* Initialize data */
    965965    m = new Data();
     966    m->pConfig = NULL;
    966967
    967968    /* Confirm a successful initialization */
     
    976977void VirtualSystemDescription::uninit()
    977978{
     979    if (m->pConfig)
     980        delete m->pConfig;
    978981    delete m;
    979982    m = NULL;
     
    13231326}
    13241327
     1328/**
     1329 * Method called from Appliance::Interpret() if the source OVF for a virtual system
     1330 * contains a <vbox:Machine> element. This method then attempts to parse that and
     1331 * create a MachineConfigFile instance from it which is stored in this instance data
     1332 * and can then be used to create a machine.
     1333 *
     1334 * This must only be called once per instance.
     1335 *
     1336 * This rethrows all XML and logic errors from MachineConfigFile.
     1337 *
     1338 * @param elmMachine <vbox:Machine> element with attributes and subelements from some
     1339 *                  DOM tree.
     1340 */
     1341void VirtualSystemDescription::importVboxMachineXML(const xml::ElementNode &elmMachine)
     1342{
     1343    settings::MachineConfigFile *pConfig = NULL;
     1344
     1345    Assert(m->pConfig == NULL);
     1346
     1347    try
     1348    {
     1349        pConfig = new settings::MachineConfigFile(NULL);
     1350        pConfig->importMachineXML(elmMachine);
     1351
     1352        m->pConfig = pConfig;
     1353    }
     1354    catch (...)
     1355    {
     1356        if (pConfig)
     1357            delete pConfig;
     1358        throw;
     1359    }
     1360}
     1361
     1362/**
     1363 * Returns the machine config created by importVboxMachineXML() or NULL if there's none.
     1364 * @return
     1365 */
     1366const settings::MachineConfigFile* VirtualSystemDescription::getMachineConfig() const
     1367{
     1368    return m->pConfig;
     1369}
     1370
  • trunk/src/VBox/Main/ApplianceImplImport.cpp

    r27908 r27918  
    4242#include <VBox/param.h>
    4343#include <VBox/version.h>
     44#include <VBox/settings.h>
    4445
    4546using namespace std;
     
    158159            if (FAILED(rc)) throw rc;
    159160
     161            // if the virtual system in OVF had a <vbox:Machine> element, have the
     162            // VirtualBox settings code parse that XML now
     163            if (vsysThis.pelmVboxMachine)
     164                pNewDesc->importVboxMachineXML(*vsysThis.pelmVboxMachine);
     165
    160166            /* Guest OS type */
    161167            Utf8Str strOsTypeVBox,
     
    254260            if (    ullMemSizeVBox != 0
    255261                 && (    ullMemSizeVBox < MM_RAM_MIN_IN_MB
    256                       || ullMemSizeVBox > MM_RAM_MAX_IN_MB)
     262                      || ullMemSizeVBox > MM_RAM_MAX_IN_MB
     263                    )
    257264               )
    258265            {
     
    712719
    713720/**
    714  * Worker code for writing out OVF to the cloud. This is called from Appliance::taskThreadImportOrExport()
     721 * Worker code for reading OVF from the cloud. This is called from Appliance::taskThreadImportOrExport()
    715722 * in S3 mode and therefore runs on the OVF read worker thread. This then starts a second worker
    716723 * thread to create temporary files (see Appliance::readFS()).
     
    10751082        try
    10761083        {
     1084            // there are two ways in which we can create
     1085
    10771086            /* Guest OS type */
    10781087            std::list<VirtualSystemDescriptionEntry*> vsdeOS;
     
    10951104                               tr("Missing VM name"));
    10961105            const Utf8Str &strNameVBox = vsdeName.front()->strVbox;
    1097             rc = mVirtualBox->CreateMachine(Bstr(strNameVBox), Bstr(strOsTypeVBox),
    1098                                                  Bstr(), Bstr(), FALSE,
    1099                                                  pNewMachine.asOutParam());
     1106            rc = mVirtualBox->CreateMachine(Bstr(strNameVBox),
     1107                                            Bstr(strOsTypeVBox),
     1108                                            NULL,
     1109                                            NULL,
     1110                                            FALSE,
     1111                                            pNewMachine.asOutParam());
    11001112            if (FAILED(rc)) throw rc;
    11011113
  • trunk/src/VBox/Main/MachineImpl.cpp

    r27914 r27918  
    264264 *  @param aConfigFile  Local file system path to the VM settings file (can
    265265 *                      be relative to the VirtualBox config directory).
    266  *  @param aMode        Init_New, Init_Existing or Init_Registered
     266 *  @param aMode        Init_New: called from VirtualBox::CreateMachine() or VirtualBox::CreateLegacyMachine() to create an empty machine
     267 *                      Init_Import: called from VirtualBox::OpenMachine()
     268 *                      Init_Registered: called from VirtualBox::initMachines() during startup
    267269 *  @param aName        name for the machine when aMode is Init_New
    268270 *                      (ignored otherwise)
     
    332334    if (aMode == Init_Registered)
    333335    {
     336        // Init_Registered: called from VirtualBox::initMachines() during startup
     337
    334338        mData->mRegistered = TRUE;
    335339
     
    345349        if (aMode == Init_Import)
    346350        {
     351            // Init_Import: called from VirtualBox::OpenMachine()
     352
    347353            // we're reading the settings file below
    348354        }
    349355        else if (aMode == Init_New)
    350356        {
     357            // Init_New: called from VirtualBox::CreateMachine() or VirtualBox::CreateLegacyMachine() to create an empty machine
     358
    351359            /* check for the file existence */
    352360            RTFILE f = NIL_RTFILE;
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r27908 r27918  
    4343}
    4444
     45namespace settings
     46{
     47    class MachineConfigFile;
     48}
     49
    4550class ATL_NO_VTABLE Appliance :
    4651    public VirtualBoxBase,
     
    243248    const VirtualSystemDescriptionEntry* findControllerFromID(uint32_t id);
    244249
     250    void importVboxMachineXML(const xml::ElementNode &elmMachine);
     251    const settings::MachineConfigFile* getMachineConfig() const;
     252
    245253    /* private instance data */
    246254private:
  • trunk/src/VBox/Main/include/ApplianceImplPrivate.h

    r27908 r27918  
    143143    std::list<VirtualSystemDescriptionEntry>
    144144                            llDescriptions;     // item descriptions
     145
    145146    ComPtr<Machine>         pMachine;           // VirtualBox machine this description was exported from (export only)
     147
     148    settings::MachineConfigFile
     149                            *pConfig;           // machine config created from <vbox:Machine> element if found (import only)
    146150};
    147151
  • trunk/src/VBox/Main/include/ovfreader.h

    r27908 r27918  
    230230
    231231    VirtualHardwareItem()
    232         : ulInstanceID(0), fAutomaticAllocation(false), fAutomaticDeallocation(false), ullVirtualQuantity(0), ullReservation(0), ullLimit(0), ullWeight(0), ulBusNumber(0), ulLineNumber(0)
     232        : ulInstanceID(0),
     233          fAutomaticAllocation(false),
     234          fAutomaticDeallocation(false),
     235          ullVirtualQuantity(0),
     236          ullReservation(0),
     237          ullLimit(0),
     238          ullWeight(0),
     239          ulBusNumber(0),
     240          ulLineNumber(0)
    233241    {};
    234242};
     
    327335    iprt::MiniString    strVendorUrl;           // product info if any; receives contents of VirtualSystem/ProductSection/VendorUrl
    328336
     337    const xml::ElementNode                      // pointer to <vbox:Machine> element under <VirtualSystem> element or NULL if not present
     338                        *pelmVboxMachine;
     339
    329340    VirtualSystem()
    330         : ullMemorySize(0), cCPUs(1), fHasFloppyDrive(false), fHasCdromDrive(false), fHasUsbController(false)
     341        : ullMemorySize(0),
     342          cCPUs(1),
     343          fHasFloppyDrive(false),
     344          fHasCdromDrive(false),
     345          fHasUsbController(false),
     346          pelmVboxMachine(NULL)
    331347    {
    332348    }
     
    366382public:
    367383    OVFReader(const iprt::MiniString &path);
    368     ~OVFReader();
    369384
    370385    void LoopThruSections(const xml::ElementNode *pReferencesElem, const xml::ElementNode *pCurElem);
     
    374389
    375390    // Data fields
    376     iprt::MiniString         m_strPath;            // file name given to constructor
    377     DiskImagesMap            m_mapDisks;           // map of DiskImage structs, sorted by DiskImage.strDiskId
    378     std::list<VirtualSystem> m_llVirtualSystems;   // list of virtual systems, created by and valid after read()
     391    iprt::MiniString            m_strPath;            // file name given to constructor
     392    DiskImagesMap               m_mapDisks;           // map of DiskImage structs, sorted by DiskImage.strDiskId
     393    std::list<VirtualSystem>    m_llVirtualSystems;   // list of virtual systems, created by and valid after read()
     394
     395private:
     396    xml::Document               m_doc;
    379397};
    380398
  • trunk/src/VBox/Main/xml/Settings.cpp

    r27857 r27918  
    16761676
    16771677/**
     1678 * Public routine which allows for importing machine XML from an external DOM tree.
     1679 * Use this after having called the constructor with a NULL argument.
     1680 *
     1681 * This is used by the OVF code if a <vbox:Machine> element has been encountered
     1682 * in an OVF VirtualSystem element.
     1683 *
     1684 * @param elmMachine
     1685 */
     1686void MachineConfigFile::importMachineXML(const xml::ElementNode &elmMachine)
     1687{
     1688    readMachine(elmMachine);
     1689}
     1690
     1691/**
    16781692 * Comparison operator. This gets called from Machine::saveSettings to figure out
    16791693 * whether machine settings have really changed and thus need to be written out to disk.
     
    33313345                            pelmTFTP->setAttribute("next-server", nic.nat.strTftpNextServer);
    33323346                    }
    3333                     for(NATRuleList::const_iterator rule = nic.nat.llRules.begin(); 
     3347                    for(NATRuleList::const_iterator rule = nic.nat.llRules.begin();
    33343348                            rule != nic.nat.llRules.end(); ++rule)
    33353349                    {
     
    38273841    if (m->sv < SettingsVersion_v1_10)
    38283842    {
    3829         NetworkAdaptersList::const_iterator netit; 
     3843        NetworkAdaptersList::const_iterator netit;
    38303844        for (netit = hardwareMachine.llNetworkAdapters.begin();
    38313845             netit != hardwareMachine.llNetworkAdapters.end(); ++netit)
    3832             if (    netit->fEnabled 
     3846            if (    netit->fEnabled
    38333847                 && netit->mode == NetworkAttachmentType_NAT
    38343848                 && (   netit->nat.u32Mtu != 0
  • trunk/src/VBox/Main/xml/ovfreader.cpp

    r27908 r27918  
    3434////////////////////////////////////////////////////////////////////////////////
    3535
     36/**
     37 * Constructor. This opens the given XML file and parses it. Throws lots of exceptions
     38 * on XML or OVF invalidity.
     39 * @param path
     40 */
    3641OVFReader::OVFReader(const MiniString &path)
    3742    : m_strPath(path)
    3843{
    3944    xml::XmlFileParser parser;
    40     xml::Document doc;
    4145    parser.read(m_strPath,
    42                 doc);
    43 
    44     const xml::ElementNode *pRootElem = doc.getRootElement();
    45     if (pRootElem && strcmp(pRootElem->getName(), "Envelope"))
     46                m_doc);
     47
     48    const xml::ElementNode *pRootElem = m_doc.getRootElement();
     49    if (    !pRootElem
     50         || strcmp(pRootElem->getName(), "Envelope")
     51       )
    4652        throw OVFLogicError(N_("Root element in OVF file must be \"Envelope\"."));
    4753
     
    6369    // now go though the sections
    6470    LoopThruSections(pReferencesElem, pRootElem);
    65 }
    66 
    67 OVFReader::~OVFReader()
    68 {
    6971}
    7072
     
    269271    VirtualSystem vsys;
    270272
     273    // peek under the <VirtualSystem> node whether we have a <vbox:Machine> node;
     274    // that case case, the caller can completely ignore the OVF but only load the VBox machine XML
     275    vsys.pelmVboxMachine = pelmVirtualSystem->findChildElement("vbox", "Machine");
     276
     277    // now look for real OVF
    271278    const xml::AttributeNode *pIdAttr = pelmVirtualSystem->findAttribute("id");
    272279    if (pIdAttr)
  • trunk/src/VBox/Runtime/r3/xml.cpp

    r27418 r27918  
    506506}
    507507
    508 bool Node::nameEquals(const char *pcsz) const
     508/**
     509 * Variant of nameEquals that checks the namespace as well.
     510 * @param pcszNamespace
     511 * @param pcsz
     512 * @return
     513 */
     514bool Node::nameEquals(const char *pcszNamespace, const char *pcsz) const
    509515{
    510516    if (m->pcszName == pcsz)
     
    514520    if (pcsz == NULL)
    515521        return false;
    516     return !strcmp(m->pcszName, pcsz);
    517 }
    518 
     522    if (strcmp(m->pcszName, pcsz))
     523        return false;
     524
     525    // name matches: then check namespaces as well
     526    if (!pcszNamespace)
     527        return true;
     528    // caller wants namespace:
     529    if (    !m->plibNode->ns
     530         || !m->plibNode->ns->prefix
     531         || !*m->plibNode->ns->prefix
     532       )
     533        // but node has no namespace:
     534        return false;
     535    return !strcmp((const char*)m->plibNode->ns->prefix, pcszNamespace);
     536}
    519537
    520538/**
     
    663681/**
    664682 * Returns the first child element whose name matches pcszMatch.
    665  * @param pcszMatch
     683 *
     684 * @param pcszNamespace Namespace prefix (e.g. "vbox") or NULL to match any namespace.
     685 * @param pcszMatch Element name to match.
    666686 * @return
    667687 */
    668 const ElementNode* ElementNode::findChildElement(const char *pcszMatch)
     688const ElementNode* ElementNode::findChildElement(const char *pcszNamespace,
     689                                                 const char *pcszMatch)
    669690    const
    670691{
     
    679700        {
    680701            ElementNode *pelm = static_cast<ElementNode*>((*it).get());
    681             if (!strcmp(pcszMatch, pelm->getName())) // the element name matches
     702            if (pelm->nameEquals(pcszNamespace, pcszMatch))
    682703                return pelm;
    683704        }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette