- Timestamp:
- Nov 1, 2023 10:41:27 AM (17 months ago)
- svn:sync-xref-src-repo-rev:
- 159789
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/UnattendedInstaller.h
r101356 r101695 553 553 */ 554 554 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); 555 563 }; 556 564 … … 605 613 */ 606 614 HRESULT editDebianMenuCfg(GeneralTextScript *pEditor); 607 /**608 * Performs basic edits on grub configuration file (grub.cfg).609 *610 * @returns COM status code611 * @param pEditor Editor with the grub.cfg file loaded and parsed.612 */613 HRESULT editDebianGrubCfg(GeneralTextScript *pEditor);614 615 615 616 /** -
trunk/src/VBox/Main/src-server/UnattendedInstaller.cpp
r101685 r101695 994 994 995 995 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) 996 HRESULT UnattendedLinuxInstaller::editGrubCfg(GeneralTextScript *pEditor) 1291 997 { 1292 998 /* Default menu entry of grub.cfg is set in /etc/deafult/grub file. */ … … 1376 1082 } 1377 1083 1084 1378 1085 ////////////////////////////////////////////////////////////////////////////////////////////////////// 1379 1086 /* 1380 1087 * 1381 1088 * 1382 * Implementation Unattended Rhel6Installer functions1089 * Implementation UnattendedDebianInstaller functions 1383 1090 * 1384 1091 */ 1385 1092 ////////////////////////////////////////////////////////////////////////////////////////////////////// 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 */ 1098 static 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 1105 HRESULT 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; 1390 1138 try 1391 1139 { 1392 #if 11393 1140 /* Remaster ISO. */ 1394 1141 rVecArgs.append() = "--no-file-mode"; … … 1401 1148 rVecArgs.append() = "--dir-mode=0555"; 1402 1149 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 } 1438 1177 } 1439 1178 catch (std::bad_alloc &) … … 1443 1182 1444 1183 /* 1445 * Edit isolinux.cfg and save it. 1446 */ 1184 * Edit the isolinux.cfg file if it is there. 1185 */ 1186 if (fIsoLinuxCfgExists) 1447 1187 { 1448 1188 GeneralTextScript Editor(mpParent); 1449 1189 HRESULT hrc = loadAndParseFileFromIso(hVfsOrgIso, "/isolinux/isolinux.cfg", &Editor); 1450 1190 if (SUCCEEDED(hrc)) 1451 hrc = editIsoLinuxCfg(&Editor );1191 hrc = editIsoLinuxCfg(&Editor, RTPathFilename(pszMenuConfigFilename)); 1452 1192 if (SUCCEEDED(hrc)) 1453 1193 { … … 1471 1211 1472 1212 /* 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 1253 HRESULT 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 1302 HRESULT 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 1352 bool 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 ////////////////////////////////////////////////////////////////////////////////////////////////////// 1388 HRESULT 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 /* 1473 1475 * Call parent to add the ks.cfg file from mAlg. 1474 1476 */
Note:
See TracChangeset
for help on using the changeset viewer.