VirtualBox

Changeset 86659 in vbox


Ignore:
Timestamp:
Oct 20, 2020 6:28:06 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
141035
Message:

bugref:9781. Added the placeholder @@VBOX_COND_GUEST_VERSION[>(required version)]@@. Updated the templates. Removed the obsolete function getGuestOSConditional().

Location:
trunk/src/VBox/Main
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/UnattendedTemplates/ol_ks.cfg

    r86650 r86659  
    8282glibc-headers
    8383gcc
    84 @@VBOX_GUEST_OS_COND_VERSION@@**8.0.0**
     84@@VBOX_COND_GUEST_VERSION[>8.0.0]@@
    8585elfutils-libelf-devel
    86 @@VBOX_GUEST_OS_COND_END@@
     86@@VBOX_COND_END@@
    8787dkms
    8888make
  • trunk/src/VBox/Main/UnattendedTemplates/ol_postinstall.sh

    r86650 r86659  
    202202log_command_in_target yum -y install binutils
    203203log_command_in_target yum -y install make
    204 @@VBOX_GUEST_OS_COND_VERSION@@**8.0.0**
     204@@VBOX_COND_GUEST_VERSION[>8.0.0]@@
    205205log_command_in_target yum -y install elfutils-libelf-devel
    206 @@VBOX_GUEST_OS_COND_END@@
     206@@VBOX_COND_END@@
    207207log_command_in_target yum -y install dkms
    208208log_command_in_target yum -y install make
  • trunk/src/VBox/Main/UnattendedTemplates/redhat67_ks.cfg

    r86650 r86659  
    8282glibc-headers
    8383gcc
    84 @@VBOX_GUEST_OS_COND_VERSION@@**8.0.0**
     84@@VBOX_COND_GUEST_VERSION[>8.0.0]@@
    8585elfutils-libelf-devel
    86 @@VBOX_GUEST_OS_COND_END@@
     86@@VBOX_COND_END@@
    8787dkms
    8888make
  • trunk/src/VBox/Main/UnattendedTemplates/redhat_postinstall.sh

    r86650 r86659  
    178178log_command_in_target yum -y install binutils
    179179log_command_in_target yum -y install make
    180 @@VBOX_GUEST_OS_COND_VERSION@@**8.0.0**
     180@@VBOX_COND_GUEST_VERSION[>8.0.0]@@
    181181log_command_in_target yum -y install elfutils-libelf-devel
    182 @@VBOX_GUEST_OS_COND_END@@
     182@@VBOX_COND_END@@
    183183log_command_in_target yum -y install dkms
    184184log_command_in_target yum -y install make
  • trunk/src/VBox/Main/include/UnattendedInstaller.h

    r86650 r86659  
    520520/**
    521521 * RHEL 7 installer (same as RHEL 6).
     522 * The class was added for better handling any possible subtle difference between RHEL6 and RHEL7.
    522523 */
    523524class UnattendedRhel7Installer : public UnattendedRhel6Installer
     
    540541/**
    541542 * RHEL 8 installer (same as RHEL 7).
     543 * The class was added for better handling any possible subtle difference between RHEL7 and RHEL8.
    542544 */
    543545class UnattendedRhel8Installer : public UnattendedRhel7Installer
     
    605607
    606608/**
    607  * Oracle Linux 6 installer.
     609 * Oracle Linux 6 installer. Same as RHEL 6, except for the templates.
     610 * The reason of adding new class is to sepatate the RHEL from OL.
    608611 */
    609612class UnattendedOracleLinux6Installer : public UnattendedRhel6Installer
     
    621624
    622625/**
    623  * Oracle Linux 7 installer.
     626 * Oracle Linux 7 installer. Same as OL 6.
     627 * The class was added for better handling any possible subtle difference between OL6 and OL7.
    624628 */
    625629class UnattendedOracleLinux7Installer : public UnattendedOracleLinux6Installer
     
    641645
    642646/**
    643  * Oracle Linux 8 installer.
     647 * Oracle Linux 8 installer. Same as OL 7.
     648 * The class was added for better handling any possible subtle difference between OL7 and OL8.
    644649 */
    645650class UnattendedOracleLinux8Installer : public UnattendedOracleLinux7Installer
  • trunk/src/VBox/Main/include/UnattendedScript.h

    r86650 r86659  
    9696    virtual HRESULT getConditional(const char *pachPlaceholder, size_t cchPlaceholder, bool *pfOutputting);
    9797
    98 
    99     /**
    100      * Get the result of a conditional for special version of guest OS.
    101      *
    102      * @returns COM status code.
    103      * @param   pachPlaceholder     The placholder string.  Not zero terminated.
    104      * @param   cchPlaceholder      The length of the placeholder.
    105      * @param   cchContent          The length of placeholder content.
    106      * @param   pcchCorrect         The length of part which must be excluded from the final content of
    107      *                              the placeholder.
    108      * @param   pfOutputting        Where to return the result of the conditional.
    109      *                              This holds the current outputting state on input
    110      *                              in case someone want to sanity check anything.
    111      */
    112     virtual HRESULT getGuestOSConditional(const char *pachPlaceholder,
    113                                           size_t cchPlaceholder,
    114                                           size_t cchContent,
    115                                           size_t *pcchCorrect,
    116                                           bool *pfOutputting);
    11798};
    11899
  • trunk/src/VBox/Main/src-server/UnattendedScript.cpp

    r86650 r86659  
    5959    static const char s_szPrefixCond[]     = "@@VBOX_COND_";
    6060    static const char s_szPrefixCondEnd[]  = "@@VBOX_COND_END@@";
    61     static const char s_szPrefixCondGuestOs[]     = "@@VBOX_GUEST_OS_COND_";
    62     static const char s_szPrefixCondGuestOsEnd[]  = "@@VBOX_GUEST_OS_COND_END@@";
    6361
    6462    struct
     
    7169    size_t      offTemplate = 0;
    7270    size_t      cchTemplate = mStrScriptFullContent.length();
    73     size_t      cchInternalCorrect = 0;//used in logic handling the placeholder @@VBOX_GUEST_OS_COND_XXX@@
    7471    rStrDst.setNull();
    7572    for (;;)
     
    8683                try
    8784                {
    88                     rStrDst.append(mStrScriptFullContent, offTemplate + cchInternalCorrect, cchToCopy - + cchInternalCorrect);
     85                    rStrDst.append(mStrScriptFullContent, offTemplate , cchToCopy);
    8986                }
    9087                catch (std::bad_alloc &)
     
    9592            }
    9693            offTemplate += cchToCopy;
    97             cchInternalCorrect = 0;//don't forget to reset
    9894        }
    9995
     
    112108                   && (ch = pszPlaceholder[cchPlaceholder]) != '\0'
    113109                   && (   ch == '_'
     110                       || ch == '['
     111                       || ch == ']'
     112                       || ch == '.'
     113                       || ch == '>'
     114                       || ch == '<'
    114115                       || RT_C_IS_UPPER(ch)
    115116                       || RT_C_IS_DIGIT(ch)) )
     
    128129                || pszPlaceholder[cchPlaceholder - 2] != '@'
    129130                || (   strncmp(pszPlaceholder, s_szPrefixInsert, sizeof(s_szPrefixInsert) - 1) != 0
    130                     && strncmp(pszPlaceholder, s_szPrefixCond,   sizeof(s_szPrefixCond)   - 1) != 0
    131                     && strncmp(pszPlaceholder, s_szPrefixCondGuestOs,   sizeof(s_szPrefixCondGuestOs) - 1) != 0) )
     131                    && strncmp(pszPlaceholder, s_szPrefixCond,   sizeof(s_szPrefixCond)   - 1) != 0 ) )
    132132            {
    133133                hrc = mpSetError->setError(E_FAIL, mpSetError->tr("Malformed template placeholder '%.*s'"),
     
    188188             *                    one from the condition.
    189189             */
    190             else if ( strncmp(pszPlaceholder, s_szPrefixCond, sizeof(s_szPrefixCond) - 1U) == 0 )
    191             {
     190            else
     191            {
     192                Assert(strncmp(pszPlaceholder, s_szPrefixCond, sizeof(s_szPrefixCond) - 1) == 0);
    192193                if (cConds + 1 < RT_ELEMENTS(aConds))
    193194                {
     
    195196                    bool fNewOutputting = fOutputting;
    196197                    hrc = getConditional(pszPlaceholder, cchPlaceholder, &fNewOutputting);
    197                     if (SUCCEEDED(hrc))
    198                         fOutputting = fOutputting && fNewOutputting;
    199                     else
    200                         break;
    201                     cConds++;
    202                 }
    203                 else
    204                 {
    205                     hrc = mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR,
    206                                                    mpSetError->tr("Too deep conditional nesting at offset %zu (%#zx)"),
    207                                                    offPlaceholder, offPlaceholder);
    208                     break;
    209                 }
    210             }
    211             /*
    212              * @@VBOX_GUEST_OS_COND_END@@: Pop one item of the conditional stack.
    213              */
    214             else if ( strncmp(pszPlaceholder, s_szPrefixCondGuestOsEnd, sizeof(s_szPrefixCondGuestOsEnd) - 1U) == 0 )
    215             {
    216                 if (cConds > 0)
    217                 {
    218                     cConds--;
    219                     fOutputting = aConds[cConds].fSavedOutputting;
    220                 }
    221                 else
    222                 {
    223                     hrc = mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR,
    224                                                    mpSetError->tr("%s without @@VBOX_GUEST_OS_COND_XXX@@ at offset %zu (%#zx)"),
    225                                                    s_szPrefixCondGuestOsEnd, offPlaceholder, offPlaceholder);
    226                     break;
    227                 }
    228             }
    229             /*
    230              * @@VBOX_GUEST_OS_COND_XXX@@: Push the previous outputting state and combine it with the
    231              *                             one from the condition.
    232              */
    233             else
    234             {
    235                 Assert(strncmp(pszPlaceholder, s_szPrefixCondGuestOs, sizeof(s_szPrefixCondGuestOs) - 1) == 0);
    236                 if (cConds + 1 < RT_ELEMENTS(aConds))
    237                 {
    238                     aConds[cConds].fSavedOutputting = fOutputting;
    239                     bool fNewOutputting = fOutputting;
    240 
    241                     //offTemplate is the beginning of content, offEndContent is the end of content
    242                     //@@PLACEHOLDER_BEGIN@@Content@@PLACEHOLDER_END@@
    243                     //                    ^       ^
    244                     //                    |       |
    245                     //             offTemplate  offEndContent
    246                     size_t offEndContent = mStrScriptFullContent.find(s_szPrefix, offTemplate);
    247                     size_t cchContent = offEndContent - offTemplate - 1;
    248                     hrc = getGuestOSConditional(pszPlaceholder, cchPlaceholder, cchContent, &cchInternalCorrect, &fNewOutputting);
    249198                    if (SUCCEEDED(hrc))
    250199                        fOutputting = fOutputting && fNewOutputting;
     
    499448}
    500449
    501 HRESULT UnattendedScriptTemplate::getGuestOSConditional(const char *pachPlaceholder,
    502                                                         size_t cchPlaceholder,
    503                                                         size_t cchContent,
    504                                                         size_t *cchCorrect,
    505                                                         bool *pfOutputting)
    506 {
    507 #define IS_PLACEHOLDER_MATCH(a_szMatch) \
    508         (   cchPlaceholder == sizeof("@@VBOX_GUEST_OS_COND_" a_szMatch "@@") - 1U \
    509          && memcmp(pachPlaceholder, "@@VBOX_GUEST_OS_COND_" a_szMatch "@@", sizeof("@@VBOX_GUEST_OS_COND_" a_szMatch "@@") - 1U) == 0)
    510 
    511     if ( IS_PLACEHOLDER_MATCH("VERSION") )
    512     {
    513         Utf8Str strT(pachPlaceholder + cchPlaceholder, cchContent);
    514         RTCList<RTCString> partList = strT.split("**");
    515         Utf8Str strRequiredOSVersion;
    516         if (partList.size() == 2)//when the version is placed together with the placeholder in one line in the file
    517         {
    518             //The case when the string has been splitted on the 2 parts:
    519             //1. OS version
    520             //2. Actual content
    521             strRequiredOSVersion.assign(partList.at(0));
    522             //cchCorrect = "**" + length of OS version string + "**"
    523             *cchCorrect = 2 + partList.at(0).length() + 2;// must be subtracted from the cchContent
    524         }
    525         else if (partList.size() == 3)//when the version is placed on a standalone line in the file
    526         {
    527             //The case when the string has been splitted on the 3 parts:
    528             //1. Empty string or string with only "\n"
    529             //2. OS version
    530             //3. Actual content
    531             strRequiredOSVersion.assign(partList.at(1));
    532             *cchCorrect = 2 + partList.at(0).length() + partList.at(1).length() + 2;// must be subtracted from the cchContent
    533         }
    534         else//case with wrong string syntax
    535         {
    536             *cchCorrect = 0;
    537             *pfOutputting = false;
    538             LogRel(("Malformed content of the template @@VBOX_GUEST_OS_COND_VERSION@@\n"));
    539             return S_OK;
    540         }
    541 
    542         if (strRequiredOSVersion.isEmpty())
    543             *pfOutputting = false;
    544         else
    545         {
    546             Utf8Str strDetectedOSVersion = mpUnattended->i_getDetectedOSVersion();
    547             RTCList<RTCString> partListRequired = strRequiredOSVersion.split(".");
    548             RTCList<RTCString> partListDetected = strDetectedOSVersion.split(".");
    549             *pfOutputting = false;//initially is set to "false"
    550 
    551             /** @todo r=vvp: Should we check the string with a requested OS version for digits?
    552              *        (with RTLocCIsDigit()) */
    553             //Major version must be presented
    554             if ( partListDetected.at(0).toUInt32() >= partListRequired.at(0).toUInt32() )//comparison major versions
    555             {
    556                 //OS major versions are equal or detected guest OS major version is greater. Go further.
    557                 if (partListDetected.size() > 1 && partListRequired.size() > 1)//comparison minor versions
    558                 {
    559                     if (partListDetected.at(1).toUInt32() >= partListRequired.at(1).toUInt32())
    560                         //OS minor versions are equal or detected guest OS minor version is greater. Go further.
    561                         *pfOutputting = true;
    562                     else
    563                         //The detected guest OS minor version is less than the requested one.
    564                         *pfOutputting = false;
    565                 }
    566                 else
    567                     //OS minor versions are absent.
    568                     *pfOutputting = true;
    569             }
    570             else
    571                 //The detected guest OS major version is less than the requested one.
    572                 *pfOutputting = false;
    573         }
    574     }
    575     else
    576         return mpSetError->setErrorBoth(E_FAIL, VERR_NOT_FOUND, mpSetError->tr("Unknown conditional placeholder '%.*s'"),
    577                                         cchPlaceholder, pachPlaceholder);
    578     return S_OK;
    579 #undef IS_PLACEHOLDER_MATCH
    580 }
    581 
    582450HRESULT UnattendedScriptTemplate::getConditional(const char *pachPlaceholder, size_t cchPlaceholder, bool *pfOutputting)
    583451{
     
    585453        (   cchPlaceholder == sizeof("@@VBOX_COND_" a_szMatch "@@") - 1U \
    586454         && memcmp(pachPlaceholder, "@@VBOX_COND_" a_szMatch "@@", sizeof("@@VBOX_COND_" a_szMatch "@@") - 1U) == 0)
     455#define IS_PLACEHOLDER_PARTIALLY_MATCH(a_szMatch) \
     456                (memcmp(pachPlaceholder, "@@VBOX_COND_" a_szMatch, sizeof("@@VBOX_COND_" a_szMatch) - 1U) == 0)
    587457
    588458    /* Install Guest Additions: */
     
    623493    else if (IS_PLACEHOLDER_MATCH("HAS_PROXY"))
    624494        *pfOutputting = mpUnattended->i_getProxy().isNotEmpty();
     495    else if (IS_PLACEHOLDER_PARTIALLY_MATCH("GUEST_VERSION"))
     496    {
     497        //parse the placeholder and extract the OS version from there
     498        RTCString strPlaceHolder(pachPlaceholder);
     499        size_t startPos = sizeof("@@VBOX_COND_GUEST_VERSION") - 1;//-1 is for '\n'
     500        size_t endPos = strPlaceHolder.find("@@", startPos + 2);
     501        //next part should look like [>8.0.0] for example where:
     502        // - "[,]" is just the brackets to wrap up the condition;
     503        // - ">" is "greater". Also possible comparison is "<";
     504        // - 8.0.0 is required guest OS version.
     505        //The end of placeholder is "@@" like for others.
     506
     507        if ( strPlaceHolder[endPos] == '@'
     508             && strPlaceHolder[endPos+1] == '@' )
     509        {
     510            if ( strPlaceHolder[startPos++] == '[' && strPlaceHolder[--endPos] == ']' )
     511            {
     512                char chComp = strPlaceHolder[startPos++];
     513                RTCString strRequiredOSVersion = strPlaceHolder.substr(startPos, endPos - startPos);
     514                RTCString strDetectedOSVersion = mpUnattended->i_getDetectedOSVersion();
     515                int res = RTStrVersionCompare(strDetectedOSVersion.c_str(), strRequiredOSVersion.c_str());
     516                if ( res >= 0 && chComp == '>' )
     517                        *pfOutputting = true;
     518                else if ( res < 0 && chComp == '<' )
     519                        *pfOutputting = true;
     520                else
     521                    *pfOutputting = false;
     522            }
     523        }
     524        else
     525            *pfOutputting = false;//initially is set to "false"
     526    }
    625527    else
    626528        return mpSetError->setErrorBoth(E_FAIL, VERR_NOT_FOUND, mpSetError->tr("Unknown conditional placeholder '%.*s'"),
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