VirtualBox

Changeset 101695 in vbox for trunk


Ignore:
Timestamp:
Nov 1, 2023 10:41:27 AM (17 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159789
Message:

Main/UnattendedInstaller: Move editDebianGrubCfg() to the base UnattendedLinuxInstaller as it will come in handy for other distributions as well, bugref:10516

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/UnattendedInstaller.h

    r101356 r101695  
    553553     */
    554554    virtual HRESULT editIsoLinuxCommon(GeneralTextScript *pEditor);
     555
     556    /**
     557     * Performs basic edits on grub configuration file (grub.cfg).
     558     *
     559     * @returns COM status code
     560     * @param   pEditor                 Editor with the grub.cfg file loaded and parsed.
     561     */
     562    virtual HRESULT editGrubCfg(GeneralTextScript *pEditor);
    555563};
    556564
     
    605613     */
    606614    HRESULT editDebianMenuCfg(GeneralTextScript *pEditor);
    607     /**
    608      * Performs basic edits on grub configuration file (grub.cfg).
    609      *
    610      * @returns COM status code
    611      * @param   pEditor                 Editor with the grub.cfg file loaded and parsed.
    612      */
    613     HRESULT editDebianGrubCfg(GeneralTextScript *pEditor);
    614615
    615616    /**
  • trunk/src/VBox/Main/src-server/UnattendedInstaller.cpp

    r101685 r101695  
    994994
    995995
    996 //////////////////////////////////////////////////////////////////////////////////////////////////////
    997 /*
    998 *
    999 *
    1000 *  Implementation UnattendedDebianInstaller functions
    1001 *
    1002 */
    1003 //////////////////////////////////////////////////////////////////////////////////////////////////////
    1004 
    1005 /**
    1006  * Helper for checking if a file exists.
    1007  * @todo promote to IPRT?
    1008  */
    1009 static bool hlpVfsFileExists(RTVFS hVfs, const char *pszPath)
    1010 {
    1011     RTFSOBJINFO ObjInfo;
    1012     int vrc = RTVfsQueryPathInfo(hVfs, pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
    1013     return RT_SUCCESS(vrc) && RTFS_IS_FILE(ObjInfo.Attr.fMode);
    1014 }
    1015 
    1016 HRESULT UnattendedDebianInstaller::addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
    1017                                                             RTVFS hVfsOrgIso, bool fOverwrite)
    1018 {
    1019     /*
    1020      * Figure out the name of the menu config file that we have to edit.
    1021      */
    1022     bool        fMenuConfigIsGrub     = false;
    1023     const char *pszMenuConfigFilename = "/isolinux/txt.cfg";
    1024     if (!hlpVfsFileExists(hVfsOrgIso, pszMenuConfigFilename))
    1025     {
    1026         /* On Debian Live ISOs (at least from 9 to 11) the there is only menu.cfg. */
    1027         if (hlpVfsFileExists(hVfsOrgIso, "/isolinux/menu.cfg"))
    1028             pszMenuConfigFilename     =  "/isolinux/menu.cfg";
    1029         /* On Linux Mint 20.3, 21, and 19 (at least) there is only isolinux.cfg. */
    1030         else if (hlpVfsFileExists(hVfsOrgIso, "/isolinux/isolinux.cfg"))
    1031             pszMenuConfigFilename     =  "/isolinux/isolinux.cfg";
    1032         /* Ubuntus 21.10+ are UEFI only. No isolinux directory. We modify grub.cfg. */
    1033         else if (hlpVfsFileExists(hVfsOrgIso, "/boot/grub/grub.cfg"))
    1034         {
    1035             pszMenuConfigFilename     =       "/boot/grub/grub.cfg";
    1036             fMenuConfigIsGrub         = true;
    1037         }
    1038     }
    1039 
    1040     /* Check for existence of isolinux.cfg since UEFI-only ISOs do not have this file.  */
    1041     bool const fIsoLinuxCfgExists = hlpVfsFileExists(hVfsOrgIso, "isolinux/isolinux.cfg");
    1042     Assert(!fIsoLinuxCfgExists || !fMenuConfigIsGrub); /** @todo r=bird: Perhaps prefix the hlpVfsFileExists call with 'fIsoLinuxCfgExists &&' above ? */
    1043 
    1044     /*
    1045      * VISO bits and filenames.
    1046      */
    1047     RTCString strIsoLinuxCfg;
    1048     RTCString strTxtCfg;
    1049     try
    1050     {
    1051         /* Remaster ISO. */
    1052         rVecArgs.append() = "--no-file-mode";
    1053         rVecArgs.append() = "--no-dir-mode";
    1054 
    1055         rVecArgs.append() = "--import-iso";
    1056         rVecArgs.append(mpParent->i_getIsoPath());
    1057 
    1058         rVecArgs.append() = "--file-mode=0444";
    1059         rVecArgs.append() = "--dir-mode=0555";
    1060 
    1061         /* Replace the isolinux.cfg configuration file. */
    1062         if (fIsoLinuxCfgExists)
    1063         {
    1064             /* First remove. */
    1065             rVecArgs.append() = "isolinux/isolinux.cfg=:must-remove:";
    1066             /* Then add the modified file. */
    1067             strIsoLinuxCfg = mpParent->i_getAuxiliaryBasePath();
    1068             strIsoLinuxCfg.append("isolinux-isolinux.cfg");
    1069             rVecArgs.append().append("isolinux/isolinux.cfg=").append(strIsoLinuxCfg);
    1070         }
    1071 
    1072         /*
    1073          * Replace menu configuration file as well.
    1074          * Some distros (Linux Mint) has only isolinux.cfg. No menu.cfg or txt.cfg.
    1075          */
    1076         if (RTStrICmp(pszMenuConfigFilename, "/isolinux/isolinux.cfg") != 0)
    1077         {
    1078 
    1079             /* Replace menu configuration file as well. */
    1080             rVecArgs.append().assign(pszMenuConfigFilename).append("=:must-remove:");
    1081             strTxtCfg = mpParent->i_getAuxiliaryBasePath();
    1082             if (fMenuConfigIsGrub)
    1083                 strTxtCfg.append("grub.cfg");
    1084             else
    1085                 strTxtCfg.append("isolinux-txt.cfg");
    1086             rVecArgs.append().assign(pszMenuConfigFilename).append("=").append(strTxtCfg);
    1087         }
    1088     }
    1089     catch (std::bad_alloc &)
    1090     {
    1091         return E_OUTOFMEMORY;
    1092     }
    1093 
    1094     /*
    1095      * Edit the isolinux.cfg file if it is there.
    1096      */
    1097     if (fIsoLinuxCfgExists)
    1098     {
    1099         GeneralTextScript Editor(mpParent);
    1100         HRESULT hrc = loadAndParseFileFromIso(hVfsOrgIso, "/isolinux/isolinux.cfg", &Editor);
    1101         if (SUCCEEDED(hrc))
    1102             hrc = editIsoLinuxCfg(&Editor, RTPathFilename(pszMenuConfigFilename));
    1103         if (SUCCEEDED(hrc))
    1104         {
    1105             hrc = Editor.save(strIsoLinuxCfg, fOverwrite);
    1106             if (SUCCEEDED(hrc))
    1107             {
    1108                 try
    1109                 {
    1110                     rVecFiles.append(strIsoLinuxCfg);
    1111                 }
    1112                 catch (std::bad_alloc &)
    1113                 {
    1114                     RTFileDelete(strIsoLinuxCfg.c_str());
    1115                     hrc = E_OUTOFMEMORY;
    1116                 }
    1117             }
    1118         }
    1119         if (FAILED(hrc))
    1120             return hrc;
    1121     }
    1122 
    1123     /*
    1124      * Edit the menu config file.
    1125      * Some distros (Linux Mint) has only isolinux.cfg. No menu.cfg or txt.cfg.
    1126     */
    1127     if (RTStrICmp(pszMenuConfigFilename, "/isolinux/isolinux.cfg") != 0)
    1128     {
    1129         GeneralTextScript Editor(mpParent);
    1130         HRESULT hrc = loadAndParseFileFromIso(hVfsOrgIso, pszMenuConfigFilename, &Editor);
    1131         if (SUCCEEDED(hrc))
    1132         {
    1133             if (fMenuConfigIsGrub)
    1134                 hrc = editDebianGrubCfg(&Editor);
    1135             else
    1136                     hrc = editDebianMenuCfg(&Editor);
    1137             if (SUCCEEDED(hrc))
    1138             {
    1139                 hrc = Editor.save(strTxtCfg, fOverwrite);
    1140                 if (SUCCEEDED(hrc))
    1141                 {
    1142                     try
    1143                     {
    1144                         rVecFiles.append(strTxtCfg);
    1145                     }
    1146                     catch (std::bad_alloc &)
    1147                     {
    1148                         RTFileDelete(strTxtCfg.c_str());
    1149                         hrc = E_OUTOFMEMORY;
    1150                     }
    1151                 }
    1152             }
    1153         }
    1154         if (FAILED(hrc))
    1155             return hrc;
    1156     }
    1157 
    1158     /*
    1159      * Call parent to add the preseed file from mAlg.
    1160      */
    1161     return UnattendedLinuxInstaller::addFilesToAuxVisoVectors(rVecArgs, rVecFiles, hVfsOrgIso, fOverwrite);
    1162 }
    1163 
    1164 HRESULT UnattendedDebianInstaller::editIsoLinuxCfg(GeneralTextScript *pEditor, const char *pszMenuConfigFileName)
    1165 {
    1166     try
    1167     {
    1168         /* Include menu config file. Since it can be txt.cfg, menu.cfg or something else we need to parametrize this. */
    1169         if (pszMenuConfigFileName && pszMenuConfigFileName[0] != '\0')
    1170         {
    1171             std::vector<size_t> vecLineNumbers = pEditor->findTemplate("include", RTCString::CaseInsensitive);
    1172             for (size_t i = 0; i < vecLineNumbers.size(); ++i)
    1173             {
    1174                 if (pEditor->getContentOfLine(vecLineNumbers[i]).startsWithWord("include", RTCString::CaseInsensitive))
    1175                 {
    1176                     Utf8Str strIncludeLine("include ");
    1177                     strIncludeLine.append(pszMenuConfigFileName);
    1178                     HRESULT hrc = pEditor->setContentOfLine(vecLineNumbers.at(i), strIncludeLine);
    1179                     if (FAILED(hrc))
    1180                         return hrc;
    1181                 }
    1182             }
    1183         }
    1184 
    1185         /* Comment out default directives since in Debian case default is handled in menu config file. */
    1186         std::vector<size_t> vecLineNumbers =  pEditor->findTemplate("default", RTCString::CaseInsensitive);
    1187         for (size_t i = 0; i < vecLineNumbers.size(); ++i)
    1188             if (pEditor->getContentOfLine(vecLineNumbers[i]).startsWithWord("default", RTCString::CaseInsensitive)
    1189                 && !pEditor->getContentOfLine(vecLineNumbers[i]).contains("default vesa", RTCString::CaseInsensitive))
    1190             {
    1191                 HRESULT hrc = pEditor->prependToLine(vecLineNumbers.at(i), "#");
    1192                 if (FAILED(hrc))
    1193                     return hrc;
    1194             }
    1195 
    1196         /* Comment out "ui gfxboot bootlogo" line as it somehow messes things up on Kubuntu 20.04 (possibly others as well). */
    1197         vecLineNumbers =  pEditor->findTemplate("ui gfxboot", RTCString::CaseInsensitive);
    1198         for (size_t i = 0; i < vecLineNumbers.size(); ++i)
    1199             if (pEditor->getContentOfLine(vecLineNumbers[i]).startsWithWord("ui gfxboot", RTCString::CaseInsensitive))
    1200             {
    1201                 HRESULT hrc = pEditor->prependToLine(vecLineNumbers.at(i), "#");
    1202                 if (FAILED(hrc))
    1203                     return hrc;
    1204             }
    1205     }
    1206     catch (std::bad_alloc &)
    1207     {
    1208         return E_OUTOFMEMORY;
    1209     }
    1210     return UnattendedLinuxInstaller::editIsoLinuxCfg(pEditor);
    1211 }
    1212 
    1213 HRESULT UnattendedDebianInstaller::editDebianMenuCfg(GeneralTextScript *pEditor)
    1214 {
    1215     /*
    1216      * Unlike Redhats, Debian variants define boot menu not in isolinux.cfg but some other
    1217      * menu configuration files. They are mostly called txt.cfg and/or menu.cfg (and possibly some other names)
    1218      * In this functions we attempt to set menu's default label (default menu item) to the one containing the word 'install',
    1219      * failing to find such a label (on Kubuntu 20.04 for example) we pick the first label with name 'live'.
    1220      */
    1221     try
    1222     {
    1223         HRESULT hrc = S_OK;
    1224         std::vector<size_t> vecLineNumbers = pEditor->findTemplate("label", RTCString::CaseInsensitive);
    1225         const char *pszNewLabelName = "VBoxUnatendedInstall";
    1226         bool fLabelFound = modifyLabelLine(pEditor, vecLineNumbers, "install", pszNewLabelName);
    1227         if (!fLabelFound)
    1228             fLabelFound = modifyLabelLine(pEditor, vecLineNumbers, "live", pszNewLabelName);
    1229 
    1230         if (!fLabelFound)
    1231             hrc = E_FAIL;;
    1232 
    1233         if (SUCCEEDED(hrc))
    1234         {
    1235             /* Modify the content of default lines so that they point to label we have chosen above. */
    1236             Utf8Str strNewContent("default ");
    1237             strNewContent.append(pszNewLabelName);
    1238 
    1239             std::vector<size_t> vecDefaultLineNumbers = pEditor->findTemplate("default", RTCString::CaseInsensitive);
    1240             if (!vecDefaultLineNumbers.empty())
    1241             {
    1242                 for (size_t j = 0; j < vecDefaultLineNumbers.size(); ++j)
    1243                 {
    1244                     hrc = pEditor->setContentOfLine(vecDefaultLineNumbers[j], strNewContent);
    1245                     if (FAILED(hrc))
    1246                         break;
    1247                 }
    1248             }
    1249             /* Add a defaul label line. */
    1250             else
    1251                 hrc = pEditor->appendLine(strNewContent);
    1252         }
    1253         if (FAILED(hrc))
    1254             return hrc;
    1255     }
    1256     catch (std::bad_alloc &)
    1257     {
    1258         return E_OUTOFMEMORY;
    1259     }
    1260     return UnattendedLinuxInstaller::editIsoLinuxCommon(pEditor);
    1261 }
    1262 
    1263 bool UnattendedDebianInstaller::modifyLabelLine(GeneralTextScript *pEditor, const std::vector<size_t> &vecLineNumbers,
    1264                                                 const char *pszKeyWord, const char *pszNewLabelName)
    1265 {
    1266     if (!pEditor)
    1267         return false;
    1268     Utf8Str strNewLabel("label ");
    1269     strNewLabel.append(pszNewLabelName);
    1270     HRESULT hrc = S_OK;
    1271     for (size_t i = 0; i < vecLineNumbers.size(); ++i)
    1272     {
    1273         RTCString const &rContent = pEditor->getContentOfLine(vecLineNumbers[i]);
    1274         /* Skip this line if it does not start with the word 'label'. */
    1275         if (!RTStrIStartsWith(rContent.c_str(), "label"))
    1276             continue;
    1277         /* Use the first menu item starting with word label and includes pszKeyWord.*/
    1278         if (RTStrIStr(rContent.c_str(), pszKeyWord) != NULL)
    1279         {
    1280             /* Set the content of the line. It looks like multiple word labels (like label Debian Installer)
    1281              * does not work very well in some cases. */
    1282             hrc = pEditor->setContentOfLine(vecLineNumbers[i], strNewLabel);
    1283             if (SUCCEEDED(hrc))
    1284                 return true;
    1285         }
    1286     }
    1287     return false;
    1288 }
    1289 
    1290 HRESULT UnattendedDebianInstaller::editDebianGrubCfg(GeneralTextScript *pEditor)
     996HRESULT UnattendedLinuxInstaller::editGrubCfg(GeneralTextScript *pEditor)
    1291997{
    1292998    /* Default menu entry of grub.cfg is set in /etc/deafult/grub file. */
     
    13761082}
    13771083
     1084
    13781085//////////////////////////////////////////////////////////////////////////////////////////////////////
    13791086/*
    13801087*
    13811088*
    1382 *  Implementation UnattendedRhel6Installer functions
     1089*  Implementation UnattendedDebianInstaller functions
    13831090*
    13841091*/
    13851092//////////////////////////////////////////////////////////////////////////////////////////////////////
    1386 HRESULT UnattendedRhelInstaller::addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
    1387                                                           RTVFS hVfsOrgIso, bool fOverwrite)
    1388 {
    1389     Utf8Str strIsoLinuxCfg;
     1093
     1094/**
     1095 * Helper for checking if a file exists.
     1096 * @todo promote to IPRT?
     1097 */
     1098static bool hlpVfsFileExists(RTVFS hVfs, const char *pszPath)
     1099{
     1100    RTFSOBJINFO ObjInfo;
     1101    int vrc = RTVfsQueryPathInfo(hVfs, pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     1102    return RT_SUCCESS(vrc) && RTFS_IS_FILE(ObjInfo.Attr.fMode);
     1103}
     1104
     1105HRESULT UnattendedDebianInstaller::addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
     1106                                                            RTVFS hVfsOrgIso, bool fOverwrite)
     1107{
     1108    /*
     1109     * Figure out the name of the menu config file that we have to edit.
     1110     */
     1111    bool        fMenuConfigIsGrub     = false;
     1112    const char *pszMenuConfigFilename = "/isolinux/txt.cfg";
     1113    if (!hlpVfsFileExists(hVfsOrgIso, pszMenuConfigFilename))
     1114    {
     1115        /* On Debian Live ISOs (at least from 9 to 11) the there is only menu.cfg. */
     1116        if (hlpVfsFileExists(hVfsOrgIso, "/isolinux/menu.cfg"))
     1117            pszMenuConfigFilename     =  "/isolinux/menu.cfg";
     1118        /* On Linux Mint 20.3, 21, and 19 (at least) there is only isolinux.cfg. */
     1119        else if (hlpVfsFileExists(hVfsOrgIso, "/isolinux/isolinux.cfg"))
     1120            pszMenuConfigFilename     =  "/isolinux/isolinux.cfg";
     1121        /* Ubuntus 21.10+ are UEFI only. No isolinux directory. We modify grub.cfg. */
     1122        else if (hlpVfsFileExists(hVfsOrgIso, "/boot/grub/grub.cfg"))
     1123        {
     1124            pszMenuConfigFilename     =       "/boot/grub/grub.cfg";
     1125            fMenuConfigIsGrub         = true;
     1126        }
     1127    }
     1128
     1129    /* Check for existence of isolinux.cfg since UEFI-only ISOs do not have this file.  */
     1130    bool const fIsoLinuxCfgExists = hlpVfsFileExists(hVfsOrgIso, "isolinux/isolinux.cfg");
     1131    Assert(!fIsoLinuxCfgExists || !fMenuConfigIsGrub); /** @todo r=bird: Perhaps prefix the hlpVfsFileExists call with 'fIsoLinuxCfgExists &&' above ? */
     1132
     1133    /*
     1134     * VISO bits and filenames.
     1135     */
     1136    RTCString strIsoLinuxCfg;
     1137    RTCString strTxtCfg;
    13901138    try
    13911139    {
    1392 #if 1
    13931140        /* Remaster ISO. */
    13941141        rVecArgs.append() = "--no-file-mode";
     
    14011148        rVecArgs.append() = "--dir-mode=0555";
    14021149
    1403         /* We replace isolinux.cfg with our edited version (see further down). */
    1404         rVecArgs.append() = "isolinux/isolinux.cfg=:must-remove:";
    1405         strIsoLinuxCfg = mpParent->i_getAuxiliaryBasePath();
    1406         strIsoLinuxCfg.append("isolinux-isolinux.cfg");
    1407         rVecArgs.append().append("isolinux/isolinux.cfg=").append(strIsoLinuxCfg);
    1408 
    1409 #else
    1410         /** @todo Maybe we should just remaster the ISO for redhat derivatives too?
    1411          *        One less CDROM to mount. */
    1412         /* Name the ISO. */
    1413         rVecArgs.append() = "--volume-id=VBox Unattended Boot";
    1414 
    1415         /* Copy the isolinux directory from the original install ISO. */
    1416         rVecArgs.append().append("--push-iso=").append(mpParent->i_getIsoPath());
    1417         rVecArgs.append() = "/isolinux=/isolinux";
    1418         rVecArgs.append() = "--pop";
    1419 
    1420         /* We replace isolinux.cfg with our edited version (see further down). */
    1421         rVecArgs.append() = "/isolinux/isolinux.cfg=:must-remove:";
    1422 
    1423         strIsoLinuxCfg = mpParent->i_getAuxiliaryBasePath();
    1424         strIsoLinuxCfg.append("isolinux-isolinux.cfg");
    1425         rVecArgs.append().append("/isolinux/isolinux.cfg=").append(strIsoLinuxCfg);
    1426 
    1427         /* Configure booting /isolinux/isolinux.bin. */
    1428         rVecArgs.append() = "--eltorito-boot";
    1429         rVecArgs.append() = "/isolinux/isolinux.bin";
    1430         rVecArgs.append() = "--no-emulation-boot";
    1431         rVecArgs.append() = "--boot-info-table";
    1432         rVecArgs.append() = "--boot-load-seg=0x07c0";
    1433         rVecArgs.append() = "--boot-load-size=4";
    1434 
    1435         /* Make the boot catalog visible in the file system. */
    1436         rVecArgs.append() = "--boot-catalog=/isolinux/vboxboot.cat";
    1437 #endif
     1150        /* Replace the isolinux.cfg configuration file. */
     1151        if (fIsoLinuxCfgExists)
     1152        {
     1153            /* First remove. */
     1154            rVecArgs.append() = "isolinux/isolinux.cfg=:must-remove:";
     1155            /* Then add the modified file. */
     1156            strIsoLinuxCfg = mpParent->i_getAuxiliaryBasePath();
     1157            strIsoLinuxCfg.append("isolinux-isolinux.cfg");
     1158            rVecArgs.append().append("isolinux/isolinux.cfg=").append(strIsoLinuxCfg);
     1159        }
     1160
     1161        /*
     1162         * Replace menu configuration file as well.
     1163         * Some distros (Linux Mint) has only isolinux.cfg. No menu.cfg or txt.cfg.
     1164         */
     1165        if (RTStrICmp(pszMenuConfigFilename, "/isolinux/isolinux.cfg") != 0)
     1166        {
     1167
     1168            /* Replace menu configuration file as well. */
     1169            rVecArgs.append().assign(pszMenuConfigFilename).append("=:must-remove:");
     1170            strTxtCfg = mpParent->i_getAuxiliaryBasePath();
     1171            if (fMenuConfigIsGrub)
     1172                strTxtCfg.append("grub.cfg");
     1173            else
     1174                strTxtCfg.append("isolinux-txt.cfg");
     1175            rVecArgs.append().assign(pszMenuConfigFilename).append("=").append(strTxtCfg);
     1176        }
    14381177    }
    14391178    catch (std::bad_alloc &)
     
    14431182
    14441183    /*
    1445      * Edit isolinux.cfg and save it.
    1446      */
     1184     * Edit the isolinux.cfg file if it is there.
     1185     */
     1186    if (fIsoLinuxCfgExists)
    14471187    {
    14481188        GeneralTextScript Editor(mpParent);
    14491189        HRESULT hrc = loadAndParseFileFromIso(hVfsOrgIso, "/isolinux/isolinux.cfg", &Editor);
    14501190        if (SUCCEEDED(hrc))
    1451             hrc = editIsoLinuxCfg(&Editor);
     1191            hrc = editIsoLinuxCfg(&Editor, RTPathFilename(pszMenuConfigFilename));
    14521192        if (SUCCEEDED(hrc))
    14531193        {
     
    14711211
    14721212    /*
     1213     * Edit the menu config file.
     1214     * Some distros (Linux Mint) has only isolinux.cfg. No menu.cfg or txt.cfg.
     1215    */
     1216    if (RTStrICmp(pszMenuConfigFilename, "/isolinux/isolinux.cfg") != 0)
     1217    {
     1218        GeneralTextScript Editor(mpParent);
     1219        HRESULT hrc = loadAndParseFileFromIso(hVfsOrgIso, pszMenuConfigFilename, &Editor);
     1220        if (SUCCEEDED(hrc))
     1221        {
     1222            if (fMenuConfigIsGrub)
     1223                hrc = editGrubCfg(&Editor);
     1224            else
     1225                    hrc = editDebianMenuCfg(&Editor);
     1226            if (SUCCEEDED(hrc))
     1227            {
     1228                hrc = Editor.save(strTxtCfg, fOverwrite);
     1229                if (SUCCEEDED(hrc))
     1230                {
     1231                    try
     1232                    {
     1233                        rVecFiles.append(strTxtCfg);
     1234                    }
     1235                    catch (std::bad_alloc &)
     1236                    {
     1237                        RTFileDelete(strTxtCfg.c_str());
     1238                        hrc = E_OUTOFMEMORY;
     1239                    }
     1240                }
     1241            }
     1242        }
     1243        if (FAILED(hrc))
     1244            return hrc;
     1245    }
     1246
     1247    /*
     1248     * Call parent to add the preseed file from mAlg.
     1249     */
     1250    return UnattendedLinuxInstaller::addFilesToAuxVisoVectors(rVecArgs, rVecFiles, hVfsOrgIso, fOverwrite);
     1251}
     1252
     1253HRESULT UnattendedDebianInstaller::editIsoLinuxCfg(GeneralTextScript *pEditor, const char *pszMenuConfigFileName)
     1254{
     1255    try
     1256    {
     1257        /* Include menu config file. Since it can be txt.cfg, menu.cfg or something else we need to parametrize this. */
     1258        if (pszMenuConfigFileName && pszMenuConfigFileName[0] != '\0')
     1259        {
     1260            std::vector<size_t> vecLineNumbers = pEditor->findTemplate("include", RTCString::CaseInsensitive);
     1261            for (size_t i = 0; i < vecLineNumbers.size(); ++i)
     1262            {
     1263                if (pEditor->getContentOfLine(vecLineNumbers[i]).startsWithWord("include", RTCString::CaseInsensitive))
     1264                {
     1265                    Utf8Str strIncludeLine("include ");
     1266                    strIncludeLine.append(pszMenuConfigFileName);
     1267                    HRESULT hrc = pEditor->setContentOfLine(vecLineNumbers.at(i), strIncludeLine);
     1268                    if (FAILED(hrc))
     1269                        return hrc;
     1270                }
     1271            }
     1272        }
     1273
     1274        /* Comment out default directives since in Debian case default is handled in menu config file. */
     1275        std::vector<size_t> vecLineNumbers =  pEditor->findTemplate("default", RTCString::CaseInsensitive);
     1276        for (size_t i = 0; i < vecLineNumbers.size(); ++i)
     1277            if (pEditor->getContentOfLine(vecLineNumbers[i]).startsWithWord("default", RTCString::CaseInsensitive)
     1278                && !pEditor->getContentOfLine(vecLineNumbers[i]).contains("default vesa", RTCString::CaseInsensitive))
     1279            {
     1280                HRESULT hrc = pEditor->prependToLine(vecLineNumbers.at(i), "#");
     1281                if (FAILED(hrc))
     1282                    return hrc;
     1283            }
     1284
     1285        /* Comment out "ui gfxboot bootlogo" line as it somehow messes things up on Kubuntu 20.04 (possibly others as well). */
     1286        vecLineNumbers =  pEditor->findTemplate("ui gfxboot", RTCString::CaseInsensitive);
     1287        for (size_t i = 0; i < vecLineNumbers.size(); ++i)
     1288            if (pEditor->getContentOfLine(vecLineNumbers[i]).startsWithWord("ui gfxboot", RTCString::CaseInsensitive))
     1289            {
     1290                HRESULT hrc = pEditor->prependToLine(vecLineNumbers.at(i), "#");
     1291                if (FAILED(hrc))
     1292                    return hrc;
     1293            }
     1294    }
     1295    catch (std::bad_alloc &)
     1296    {
     1297        return E_OUTOFMEMORY;
     1298    }
     1299    return UnattendedLinuxInstaller::editIsoLinuxCfg(pEditor);
     1300}
     1301
     1302HRESULT UnattendedDebianInstaller::editDebianMenuCfg(GeneralTextScript *pEditor)
     1303{
     1304    /*
     1305     * Unlike Redhats, Debian variants define boot menu not in isolinux.cfg but some other
     1306     * menu configuration files. They are mostly called txt.cfg and/or menu.cfg (and possibly some other names)
     1307     * In this functions we attempt to set menu's default label (default menu item) to the one containing the word 'install',
     1308     * failing to find such a label (on Kubuntu 20.04 for example) we pick the first label with name 'live'.
     1309     */
     1310    try
     1311    {
     1312        HRESULT hrc = S_OK;
     1313        std::vector<size_t> vecLineNumbers = pEditor->findTemplate("label", RTCString::CaseInsensitive);
     1314        const char *pszNewLabelName = "VBoxUnatendedInstall";
     1315        bool fLabelFound = modifyLabelLine(pEditor, vecLineNumbers, "install", pszNewLabelName);
     1316        if (!fLabelFound)
     1317            fLabelFound = modifyLabelLine(pEditor, vecLineNumbers, "live", pszNewLabelName);
     1318
     1319        if (!fLabelFound)
     1320            hrc = E_FAIL;;
     1321
     1322        if (SUCCEEDED(hrc))
     1323        {
     1324            /* Modify the content of default lines so that they point to label we have chosen above. */
     1325            Utf8Str strNewContent("default ");
     1326            strNewContent.append(pszNewLabelName);
     1327
     1328            std::vector<size_t> vecDefaultLineNumbers = pEditor->findTemplate("default", RTCString::CaseInsensitive);
     1329            if (!vecDefaultLineNumbers.empty())
     1330            {
     1331                for (size_t j = 0; j < vecDefaultLineNumbers.size(); ++j)
     1332                {
     1333                    hrc = pEditor->setContentOfLine(vecDefaultLineNumbers[j], strNewContent);
     1334                    if (FAILED(hrc))
     1335                        break;
     1336                }
     1337            }
     1338            /* Add a defaul label line. */
     1339            else
     1340                hrc = pEditor->appendLine(strNewContent);
     1341        }
     1342        if (FAILED(hrc))
     1343            return hrc;
     1344    }
     1345    catch (std::bad_alloc &)
     1346    {
     1347        return E_OUTOFMEMORY;
     1348    }
     1349    return UnattendedLinuxInstaller::editIsoLinuxCommon(pEditor);
     1350}
     1351
     1352bool UnattendedDebianInstaller::modifyLabelLine(GeneralTextScript *pEditor, const std::vector<size_t> &vecLineNumbers,
     1353                                                const char *pszKeyWord, const char *pszNewLabelName)
     1354{
     1355    if (!pEditor)
     1356        return false;
     1357    Utf8Str strNewLabel("label ");
     1358    strNewLabel.append(pszNewLabelName);
     1359    HRESULT hrc = S_OK;
     1360    for (size_t i = 0; i < vecLineNumbers.size(); ++i)
     1361    {
     1362        RTCString const &rContent = pEditor->getContentOfLine(vecLineNumbers[i]);
     1363        /* Skip this line if it does not start with the word 'label'. */
     1364        if (!RTStrIStartsWith(rContent.c_str(), "label"))
     1365            continue;
     1366        /* Use the first menu item starting with word label and includes pszKeyWord.*/
     1367        if (RTStrIStr(rContent.c_str(), pszKeyWord) != NULL)
     1368        {
     1369            /* Set the content of the line. It looks like multiple word labels (like label Debian Installer)
     1370             * does not work very well in some cases. */
     1371            hrc = pEditor->setContentOfLine(vecLineNumbers[i], strNewLabel);
     1372            if (SUCCEEDED(hrc))
     1373                return true;
     1374        }
     1375    }
     1376    return false;
     1377}
     1378
     1379
     1380//////////////////////////////////////////////////////////////////////////////////////////////////////
     1381/*
     1382*
     1383*
     1384*  Implementation UnattendedRhel6Installer functions
     1385*
     1386*/
     1387//////////////////////////////////////////////////////////////////////////////////////////////////////
     1388HRESULT UnattendedRhelInstaller::addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
     1389                                                          RTVFS hVfsOrgIso, bool fOverwrite)
     1390{
     1391    Utf8Str strIsoLinuxCfg;
     1392    try
     1393    {
     1394#if 1
     1395        /* Remaster ISO. */
     1396        rVecArgs.append() = "--no-file-mode";
     1397        rVecArgs.append() = "--no-dir-mode";
     1398
     1399        rVecArgs.append() = "--import-iso";
     1400        rVecArgs.append(mpParent->i_getIsoPath());
     1401
     1402        rVecArgs.append() = "--file-mode=0444";
     1403        rVecArgs.append() = "--dir-mode=0555";
     1404
     1405        /* We replace isolinux.cfg with our edited version (see further down). */
     1406        rVecArgs.append() = "isolinux/isolinux.cfg=:must-remove:";
     1407        strIsoLinuxCfg = mpParent->i_getAuxiliaryBasePath();
     1408        strIsoLinuxCfg.append("isolinux-isolinux.cfg");
     1409        rVecArgs.append().append("isolinux/isolinux.cfg=").append(strIsoLinuxCfg);
     1410
     1411#else
     1412        /** @todo Maybe we should just remaster the ISO for redhat derivatives too?
     1413         *        One less CDROM to mount. */
     1414        /* Name the ISO. */
     1415        rVecArgs.append() = "--volume-id=VBox Unattended Boot";
     1416
     1417        /* Copy the isolinux directory from the original install ISO. */
     1418        rVecArgs.append().append("--push-iso=").append(mpParent->i_getIsoPath());
     1419        rVecArgs.append() = "/isolinux=/isolinux";
     1420        rVecArgs.append() = "--pop";
     1421
     1422        /* We replace isolinux.cfg with our edited version (see further down). */
     1423        rVecArgs.append() = "/isolinux/isolinux.cfg=:must-remove:";
     1424
     1425        strIsoLinuxCfg = mpParent->i_getAuxiliaryBasePath();
     1426        strIsoLinuxCfg.append("isolinux-isolinux.cfg");
     1427        rVecArgs.append().append("/isolinux/isolinux.cfg=").append(strIsoLinuxCfg);
     1428
     1429        /* Configure booting /isolinux/isolinux.bin. */
     1430        rVecArgs.append() = "--eltorito-boot";
     1431        rVecArgs.append() = "/isolinux/isolinux.bin";
     1432        rVecArgs.append() = "--no-emulation-boot";
     1433        rVecArgs.append() = "--boot-info-table";
     1434        rVecArgs.append() = "--boot-load-seg=0x07c0";
     1435        rVecArgs.append() = "--boot-load-size=4";
     1436
     1437        /* Make the boot catalog visible in the file system. */
     1438        rVecArgs.append() = "--boot-catalog=/isolinux/vboxboot.cat";
     1439#endif
     1440    }
     1441    catch (std::bad_alloc &)
     1442    {
     1443        return E_OUTOFMEMORY;
     1444    }
     1445
     1446    /*
     1447     * Edit isolinux.cfg and save it.
     1448     */
     1449    {
     1450        GeneralTextScript Editor(mpParent);
     1451        HRESULT hrc = loadAndParseFileFromIso(hVfsOrgIso, "/isolinux/isolinux.cfg", &Editor);
     1452        if (SUCCEEDED(hrc))
     1453            hrc = editIsoLinuxCfg(&Editor);
     1454        if (SUCCEEDED(hrc))
     1455        {
     1456            hrc = Editor.save(strIsoLinuxCfg, fOverwrite);
     1457            if (SUCCEEDED(hrc))
     1458            {
     1459                try
     1460                {
     1461                    rVecFiles.append(strIsoLinuxCfg);
     1462                }
     1463                catch (std::bad_alloc &)
     1464                {
     1465                    RTFileDelete(strIsoLinuxCfg.c_str());
     1466                    hrc = E_OUTOFMEMORY;
     1467                }
     1468            }
     1469        }
     1470        if (FAILED(hrc))
     1471            return hrc;
     1472    }
     1473
     1474    /*
    14731475     * Call parent to add the ks.cfg file from mAlg.
    14741476     */
Note: See TracChangeset for help on using the changeset viewer.

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