VirtualBox

source: vbox/trunk/src/VBox/Main/include/UnattendedInstaller.h

Last change on this file was 102342, checked in by vboxsync, 6 months ago

Main/Unattended: Implemented support for subiquity-/cloud-init-based installers. This enables installing guest newer Linux-based OSes like Ubuntu >= 22.10 in Unattended mode. More detection code for other variants will follow. Extended testcases [build fix, Windows installer does not accept dashes (-) as file keys]. bugref:10551

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.9 KB
Line 
1/* $Id: UnattendedInstaller.h 102342 2023-11-27 17:56:10Z vboxsync $ */
2/** @file
3 * UnattendedInstaller class header
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef MAIN_INCLUDED_UnattendedInstaller_h
29#define MAIN_INCLUDED_UnattendedInstaller_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include "UnattendedScript.h"
35
36/* Forward declarations */
37class Unattended;
38class UnattendedInstaller;
39class BaseTextScript;
40
41
42/**
43 * The abstract UnattendedInstaller class declaration
44 *
45 * The class is intended to service a new VM that this VM will be able to
46 * execute an unattended installation
47 */
48class UnattendedInstaller : public RTCNonCopyable
49{
50/*data*/
51protected:
52 /** Main unattended installation script. */
53 UnattendedScriptTemplate mMainScript;
54 /** Full path to the main template file (set by initInstaller). */
55 Utf8Str mStrMainScriptTemplate;
56
57 /** Post installation (shell) script. */
58 UnattendedScriptTemplate mPostScript;
59 /** Full path to the post template file (set by initInstaller). */
60 Utf8Str mStrPostScriptTemplate;
61
62 /** Pointer to the parent object.
63 * We use this for setting errors and querying attributes. */
64 Unattended *mpParent;
65 /** The path of the extra ISO image we create (set by initInstaller).
66 * This is only valid when isAdditionsIsoNeeded() returns true. */
67 Utf8Str mStrAuxiliaryIsoFilePath;
68 /** The path of the extra floppy image we create (set by initInstaller)
69 * This is only valid when isAdditionsFloppyNeeded() returns true. */
70 Utf8Str mStrAuxiliaryFloppyFilePath;
71 /** The boot device. */
72 DeviceType_T const meBootDevice;
73 /** Default extra install kernel parameters (set by constructor).
74 * This can be overridden by the extraInstallKernelParameters attribute of
75 * IUnattended. */
76 Utf8Str mStrDefaultExtraInstallKernelParameters;
77 /** The directory of the post install script in the unattended install
78 * environment, i.e. when it gets started by the unattended installer
79 * of the respective guest OS. */
80 Utf8Str mStrAuxiliaryInstallDir;
81
82private:
83 UnattendedInstaller(); /* no default constructors */
84
85public:
86 DECLARE_TRANSLATE_METHODS(UnattendedInstaller)
87
88 /**
89 * Regular constructor.
90 *
91 * @param pParent The parent object. Used for setting
92 * errors and querying attributes.
93 * @param pszMainScriptTemplateName The name of the template file (no path)
94 * for the main unattended installer
95 * script.
96 * @param pszPostScriptTemplateName The name of the template file (no path)
97 * for the post installation script.
98 * @param pszMainScriptFilename The main unattended installer script
99 * filename (on aux media).
100 * @param pszPostScriptFilename The post installation script filename
101 * (on aux media).
102 * @param enmBootDevice The boot device type.
103 */
104 UnattendedInstaller(Unattended *pParent,
105 const char *pszMainScriptTemplateName, const char *pszPostScriptTemplateName,
106 const char *pszMainScriptFilename, const char *pszPostScriptFilename,
107 DeviceType_T enmBootDevice = DeviceType_DVD);
108 virtual ~UnattendedInstaller();
109
110 /**
111 * Instantiates the appropriate child class.
112 *
113 * @returns Pointer to the new instance, NULL if no appropriate installer.
114 * @param enmDetectedOSType The detected guest OS type value.
115 * @param strDetectedOSType The detected guest OS type string
116 * @param strDetectedOSVersion The detected guest OS version.
117 * @param strDetectedOSFlavor The detected guest OS flavor.
118 * @param strDetectedOSHints Hints about the detected guest OS.
119 * @param pParent The parent object. Used for setting errors
120 * and querying attributes.
121 * @throws std::bad_alloc
122 */
123 static UnattendedInstaller *createInstance(VBOXOSTYPE enmDetectedOSType, const Utf8Str &strDetectedOSType,
124 const Utf8Str &strDetectedOSVersion, const Utf8Str &strDetectedOSFlavor,
125 const Utf8Str &strDetectedOSHints, Unattended *pParent);
126
127 /**
128 * Initialize the installer.
129 *
130 * @note This is called immediately after instantiation and the caller will
131 * always destroy the unattended installer instance on failure, so it
132 * is not necessary to keep track of whether this succeeded or not.
133 */
134 virtual HRESULT initInstaller();
135
136#if 0 /* These are now in the AUX VISO. */
137 /**
138 * Whether the VBox Guest Additions ISO is needed or not.
139 *
140 * The default implementation always returns false when a VISO is used, see
141 * UnattendedInstaller::addFilesToAuxVisoVectors.
142 */
143 virtual bool isAdditionsIsoNeeded() const;
144
145 /**
146 * Whether the VBox validation kit ISO is needed or not.
147 *
148 * The default implementation always returns false when a VISO is used, see
149 * UnattendedInstaller::addFilesToAuxVisoVectors.
150 */
151 virtual bool isValidationKitIsoNeeded() const;
152#endif
153
154 /**
155 * Indicates whether an original installation ISO is needed or not.
156 */
157 virtual bool isOriginalIsoNeeded() const { return true; }
158
159 /**
160 * Indicates whether a floppy image is needed or not.
161 */
162 virtual bool isAuxiliaryFloppyNeeded() const { return false; }
163
164 /**
165 * Indicates whether an additional or replacement ISO image is needed or not.
166 */
167 virtual bool isAuxiliaryIsoNeeded() const;
168
169 /**
170 * Indicates whether we should boot from the auxiliary ISO image.
171 *
172 * Will boot from installation ISO if false.
173 */
174 virtual bool bootFromAuxiliaryIso() const { return isAuxiliaryIsoNeeded(); }
175
176 /**
177 * Indicates whether a the auxiliary ISO is a .viso-file rather than an
178 * .iso-file.
179 *
180 * Different worker methods are used depending on the return value. A
181 * .viso-file is generally only used when the installation media needs to
182 * be remastered with small changes and additions.
183 */
184 virtual bool isAuxiliaryIsoIsVISO() const { return true; }
185
186 /*
187 * Getters
188 */
189 DeviceType_T getBootableDeviceType() const { return meBootDevice; }
190 const Utf8Str &getTemplateFilePath() const { return mStrMainScriptTemplate; }
191 const Utf8Str &getPostTemplateFilePath() const { return mStrPostScriptTemplate; }
192 const Utf8Str &getAuxiliaryIsoFilePath() const { return mStrAuxiliaryIsoFilePath; }
193 const Utf8Str &getAuxiliaryFloppyFilePath() const { return mStrAuxiliaryFloppyFilePath; }
194 const Utf8Str &getDefaultExtraInstallKernelParameters() const { return mStrDefaultExtraInstallKernelParameters; }
195 const Utf8Str &getAuxiliaryInstallDir() const { return mStrAuxiliaryInstallDir; }
196
197 /*
198 * Setters
199 */
200 void setTemplatePath(const Utf8Str& data); /**< @todo r=bird: This is confusing as heck. Dir for a while, then it's a file. Not a comment about it. Brilliant. */
201
202 /**
203 * Prepares the unattended scripts, does all but write them to the installation
204 * media.
205 */
206 HRESULT prepareUnattendedScripts();
207
208 /**
209 * Prepares the media - floppy image, ISO image.
210 *
211 * This method calls prepareAuxFloppyImage() and prepareAuxIsoImage(), child
212 * classes may override these methods or methods they call.
213 *
214 * @returns COM status code.
215 * @param fOverwrite Whether to overwrite media files or fail if they
216 * already exist.
217 */
218 HRESULT prepareMedia(bool fOverwrite = true);
219
220protected:
221 /**
222 * Prepares (creates) the auxiliary floppy image.
223 *
224 * This is called by the base class prepareMedia() when
225 * isAuxiliaryFloppyNeeded() is true. The base class implementation puts the
226 * edited unattended script onto it.
227 */
228 HRESULT prepareAuxFloppyImage(bool fOverwrite);
229
230 /**
231 * Creates and formats (FAT12) a floppy image.
232 *
233 * This can be overridden to do more preparation work or/and create a different
234 * sized floppy.
235 *
236 * @returns COM status code.
237 * @param pszFilename The path to the image file.
238 * @param fOverwrite Whether to overwrite the file.
239 * @param phVfsFile Where to return a read-writable handle to the newly
240 * created image.
241 */
242 virtual HRESULT newAuxFloppyImage(const char *pszFilename, bool fOverwrite, PRTVFSFILE phVfsFile);
243
244 /**
245 * Copies files to the auxiliary floppy image.
246 *
247 * The base class implementation copies the main and post scripts to the root of
248 * the floppy using the default script names. Child classes may override this
249 * to add additional or different files.
250 *
251 * @returns COM status code.
252 * @param hVfs The floppy image VFS handle.
253 */
254 virtual HRESULT copyFilesToAuxFloppyImage(RTVFS hVfs);
255
256 /**
257 * Adds the given script to the root of the floppy image under the default
258 * script filename.
259 *
260 * @returns COM status code.
261 * @param pEditor The script to add.
262 * @param hVfs The VFS to add it to.
263 */
264 HRESULT addScriptToFloppyImage(BaseTextScript *pEditor, RTVFS hVfs);
265
266 /**
267 * Copy an arbritrary file onto the floopy image.
268 *
269 * @returns COM status code.
270 * @param hVfs The VFS to add it to.
271 * @param pszSrc The source filename.
272 * @param pszDst The destination filename (on @a hVfs).
273 */
274 HRESULT addFileToFloppyImage(RTVFS hVfs, const char *pszSrc, const char *pszDst);
275
276 /**
277 * Prepares (creates) the auxiliary ISO image.
278 *
279 * This is called by the base class prepareMedia() when isAuxiliaryIsoNeeded()
280 * is true. The base class implementation puts the edited unattended script
281 * onto it.
282 */
283 virtual HRESULT prepareAuxIsoImage(bool fOverwrite);
284
285 /**
286 * Opens the installation ISO image.
287 *
288 * @returns COM status code.
289 * @param phVfsIso Where to return the VFS handle for the ISO.
290 * @param fFlags RTFSISO9660_F_XXX flags to pass to the
291 * RTFsIso9660VolOpen API.
292 */
293 virtual HRESULT openInstallIsoImage(PRTVFS phVfsIso, uint32_t fFlags = 0);
294
295 /**
296 * Creates and configures the ISO maker instance.
297 *
298 * This can be overridden to set configure options.
299 *
300 * @returns COM status code.
301 * @param phIsoMaker Where to return the ISO maker.
302 */
303 virtual HRESULT newAuxIsoImageMaker(PRTFSISOMAKER phIsoMaker);
304
305 /**
306 * Adds files to the auxiliary ISO image maker.
307 *
308 * The base class implementation copies just the mMainScript and mPostScript
309 * files to root directory using the default filenames.
310 *
311 * @returns COM status code.
312 * @param hIsoMaker The ISO maker handle.
313 * @param hVfsOrgIso The VFS handle to the original ISO in case files
314 * needs to be added from it.
315 */
316 virtual HRESULT addFilesToAuxIsoImageMaker(RTFSISOMAKER hIsoMaker, RTVFS hVfsOrgIso);
317
318 /**
319 * Adds the given script to the ISO maker.
320 *
321 * @returns COM status code.
322 * @param pEditor The script to add.
323 * @param hIsoMaker The ISO maker to add it to.
324 * @param pszDstFilename The file name (w/ path) to add it under. If NULL,
325 * the default script filename is used to add it to the
326 * root.
327 */
328 HRESULT addScriptToIsoMaker(BaseTextScript *pEditor, RTFSISOMAKER hIsoMaker, const char *pszDstFilename = NULL);
329
330 /**
331 * Writes the ISO image to disk.
332 *
333 * @returns COM status code.
334 * @param hIsoMaker The ISO maker handle.
335 * @param pszFilename The filename.
336 * @param fOverwrite Whether to overwrite the destination file or not.
337 */
338 HRESULT finalizeAuxIsoImage(RTFSISOMAKER hIsoMaker, const char *pszFilename, bool fOverwrite);
339
340 /**
341 * Adds files to the .viso-file vectors.
342 *
343 * The base class implementation adds the script from mAlg, additions ISO
344 * content to '/vboxadditions', validation kit ISO to '/vboxvalidationkit',
345 * and user payload ISO to '/vboxuserpayload'.
346 *
347 * @returns COM status code.
348 * @param rVecArgs The ISO maker argument list that will be turned into
349 * a .viso-file.
350 * @param rVecFiles The list of files we've created. This is for
351 * cleaning up at the end.
352 * @param hVfsOrgIso The VFS handle to the original ISO in case files
353 * needs to be added from it.
354 * @param fOverwrite Whether to overwrite files or not.
355 */
356 virtual HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
357 RTVFS hVfsOrgIso, bool fOverwrite);
358
359 /**
360 * Saves the given script to disk and adds it to the .viso-file vectors.
361 *
362 * @returns COM status code.
363 * @param pEditor The script to add.
364 * @param rVecArgs The ISO maker argument list that will be turned into
365 * a .viso-file.
366 * @param rVecFiles The list of files we've created. This is for
367 * cleaning up at the end.
368 * @param fOverwrite Whether to overwrite files or not.
369 */
370 HRESULT addScriptToVisoVectors(BaseTextScript *pEditor, RTCList<RTCString> &rVecArgs,
371 RTCList<RTCString> &rVecFiles, bool fOverwrite);
372
373 /**
374 * Writes out the .viso-file to disk.
375 *
376 * @returns COM status code.
377 * @param rVecArgs The ISO maker argument list to write out.
378 * @param pszFilename The filename.
379 * @param fOverwrite Whether to overwrite the destination file or not.
380 */
381 HRESULT finalizeAuxVisoFile(RTCList<RTCString> const &rVecArgs, const char *pszFilename, bool fOverwrite);
382
383 /**
384 * Loads @a pszFilename from @a hVfsOrgIso into @a pEditor and parses it.
385 *
386 * @returns COM status code.
387 * @param hVfsOrgIso The handle to the original installation ISO.
388 * @param pszFilename The filename to open and load from the ISO.
389 * @param pEditor The editor instance to load the file into and
390 * do the parseing with.
391 */
392 HRESULT loadAndParseFileFromIso(RTVFS hVfsOrgIso, const char *pszFilename, AbstractScript *pEditor);
393};
394
395
396/**
397 * Windows installer, for versions up to xp 64 / w2k3.
398 */
399class UnattendedWindowsSifInstaller : public UnattendedInstaller
400{
401public:
402 DECLARE_TRANSLATE_METHODS(UnattendedWindowsSifInstaller)
403
404 UnattendedWindowsSifInstaller(Unattended *pParent)
405 : UnattendedInstaller(pParent,
406 "win_nt5_unattended.sif", "win_postinstall.cmd",
407 "WINNT.SIF", "VBOXPOST.CMD")
408 {
409 Assert(isOriginalIsoNeeded()); Assert(isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); Assert(!bootFromAuxiliaryIso());
410 mStrAuxiliaryInstallDir = "A:\\";
411 }
412 ~UnattendedWindowsSifInstaller() {}
413
414 bool isAuxiliaryFloppyNeeded() const { return true; }
415 bool bootFromAuxiliaryIso() const { return false; }
416
417};
418
419/**
420 * Windows installer, for versions starting with Vista.
421 */
422class UnattendedWindowsXmlInstaller : public UnattendedInstaller
423{
424public:
425 DECLARE_TRANSLATE_METHODS(UnattendedWindowsXmlInstaller)
426
427 UnattendedWindowsXmlInstaller(Unattended *pParent)
428 : UnattendedInstaller(pParent,
429 "win_nt6_unattended.xml", "win_postinstall.cmd",
430 "autounattend.xml", "VBOXPOST.CMD")
431 {
432 Assert(isOriginalIsoNeeded()); Assert(isAuxiliaryFloppyNeeded() || isAuxiliaryIsoNeeded()); Assert(isAuxiliaryIsoIsVISO()); Assert(!bootFromAuxiliaryIso());
433 if (isAuxiliaryFloppyNeeded())
434 mStrAuxiliaryInstallDir = "A:\\";
435 else if (bootFromAuxiliaryIso())
436 mStrAuxiliaryInstallDir = "D:\\";
437 else
438 mStrAuxiliaryInstallDir = "E:\\";
439 }
440 ~UnattendedWindowsXmlInstaller() {}
441
442 bool isAuxiliaryFloppyNeeded() const { return !mpParent->i_isFirmwareEFI(); }
443 bool isAuxiliaryIsoNeeded() const { return UnattendedInstaller::isAuxiliaryIsoNeeded() || mpParent->i_isFirmwareEFI(); }
444 bool isAuxiliaryIsoIsVISO() const { return true; }
445 bool bootFromAuxiliaryIso() const { return false; }
446};
447
448
449/**
450 * OS/2 installer.
451 */
452class UnattendedOs2Installer : public UnattendedInstaller
453{
454public:
455 DECLARE_TRANSLATE_METHODS(UnattendedOs2Installer)
456
457 UnattendedOs2Installer(Unattended *pParent, Utf8Str const &rStrHints);
458 ~UnattendedOs2Installer() {}
459
460 /* Remaster original ISO with auxiliary floppy used for el torito floppy emulation: */
461 bool isOriginalIsoNeeded() const RT_OVERRIDE { return false; }
462 bool isAuxiliaryFloppyNeeded() const RT_OVERRIDE { return true; }
463 bool isAuxiliaryIsoNeeded() const RT_OVERRIDE { return true; }
464
465protected:
466 HRESULT replaceAuxFloppyImageBootSector(RTVFSFILE hVfsFile) RT_NOEXCEPT;
467 HRESULT newAuxFloppyImage(const char *pszFilename, bool fOverwrite, PRTVFSFILE phVfsFile) RT_OVERRIDE;
468 HRESULT copyFilesToAuxFloppyImage(RTVFS hVfs) RT_OVERRIDE;
469 HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
470 RTVFS hVfsOrgIso, bool fOverwrite) RT_OVERRIDE;
471
472 HRESULT splitResponseFile() RT_NOEXCEPT;
473
474 /**
475 * Splits up the given file into sub-files and writes them out with the auxilary
476 * path base as prefix.
477 *
478 * The source file contains @@VBOX_SPLITTER_START[filename]@@ and
479 * @@VBOX_SPLITTER_END[filename]@@ markup that is used to split it up. Any
480 * text between END and START tags are ignored and can be used for comments.
481 *
482 * @returns COM status code (error info set).
483 * @param pszFileToSplit The name of the file to split.
484 * @param rVecSplitFiles Vector where names of the sub-files are appended
485 * (without any path or prefix).
486 */
487 HRESULT splitFile(const char *pszFileToSplit, RTCList<RTCString> &rVecSplitFiles) RT_NOEXCEPT;
488
489 /**
490 * Splits up the given editor output into sub-files and writes them out with the
491 * auxilary path base as prefix.
492 *
493 * The source file contains @@VBOX_SPLITTER_START[filename]@@ and
494 * @@VBOX_SPLITTER_END[filename]@@ markup that is used to split it up. Any
495 * text between END and START tags are ignored and can be used for comments.
496 *
497 * @returns COM status code (error info set).
498 * @param pEditor The editor which output should be split.
499 * @param rVecSplitFiles Vector where names of the sub-files are appended
500 * (without any path or prefix).
501 */
502 HRESULT splitFile(BaseTextScript *pEditor, RTCList<RTCString> &rVecSplitFiles) RT_NOEXCEPT;
503
504 HRESULT splitFileInner(const char *pszFileToSplit, RTCList<RTCString> &rVecSplitFiles,
505 const char *pszSrc, size_t cbLeft) RT_NOEXCEPT;
506
507 static int patchTestCfg(uint8_t *pbFile, size_t cbFile, const char *pszFilename, UnattendedOs2Installer *pThis);
508 static int patchOs2Ldr(uint8_t *pbFile, size_t cbFile, const char *pszFilename, UnattendedOs2Installer *pThis);
509
510 /** The OS2SE20.SRC path ("\\OS2IMAGES"). */
511 Utf8Str mStrOs2Images;
512 /** Files split out from os2_response_files.rsp (bare filenames, no paths). */
513 RTCList<RTCString> mVecSplitFiles;
514};
515
516
517
518/**
519 * Base class for the unattended linux installers.
520 */
521class UnattendedLinuxInstaller : public UnattendedInstaller
522{
523protected:
524 /** Array of linux parameter patterns that should be removed by editIsoLinuxCfg.
525 * The patterns are proceed by RTStrSimplePatternNMatch. */
526 RTCList<RTCString, RTCString *> mArrStrRemoveInstallKernelParameters;
527
528public:
529 DECLARE_TRANSLATE_METHODS(UnattendedLinuxInstaller)
530
531 UnattendedLinuxInstaller(Unattended *pParent,
532 const char *pszMainScriptTemplateName, const char *pszPostScriptTemplateName,
533 const char *pszMainScriptFilename, const char *pszPostScriptFilename = "vboxpostinstall.sh")
534 : UnattendedInstaller(pParent,
535 pszMainScriptTemplateName, pszPostScriptTemplateName,
536 pszMainScriptFilename, pszPostScriptFilename) {}
537 ~UnattendedLinuxInstaller() {}
538
539 bool isAuxiliaryIsoNeeded() const { return true; }
540
541protected:
542 /**
543 * Performs basic edits on a isolinux.cfg file.
544 *
545 * @returns COM status code
546 * @param pEditor Editor with the isolinux.cfg file loaded and parsed.
547 */
548 virtual HRESULT editIsoLinuxCfg(GeneralTextScript *pEditor);
549 /**
550 * Performs basic common edits on a isolinux.cfg and menu configuration file(s) (txt.cfg or menu.cfg etc).
551 *
552 * @returns COM status code
553 * @param pEditor Editor with the isolinux.cfg file loaded and parsed.
554 */
555 virtual HRESULT editIsoLinuxCommon(GeneralTextScript *pEditor);
556
557 /**
558 * Performs basic edits on grub configuration file (grub.cfg).
559 *
560 * @returns COM status code
561 * @param pEditor Editor with the grub.cfg file loaded and parsed.
562 */
563 virtual HRESULT editGrubCfg(GeneralTextScript *pEditor);
564};
565
566
567/**
568 * Debian installer.
569 *
570 * This will remaster the orignal ISO and therefore be producing a .viso-file.
571 */
572class UnattendedDebianInstaller : public UnattendedLinuxInstaller
573{
574public:
575 DECLARE_TRANSLATE_METHODS(UnattendedDebianInstaller)
576
577 UnattendedDebianInstaller(Unattended *pParent,
578 const char *pszMainScriptTemplateName = "debian_preseed.cfg",
579 const char *pszPostScriptTemplateName = "debian_postinstall.sh",
580 const char *pszMainScriptFilename = "preseed.cfg")
581 : UnattendedLinuxInstaller(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
582 {
583 Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded());
584 Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO());
585 mStrDefaultExtraInstallKernelParameters.setNull();
586 mStrDefaultExtraInstallKernelParameters += " auto=true";
587 mStrDefaultExtraInstallKernelParameters.append(" preseed/file=/cdrom/").append(pszMainScriptFilename);
588 mStrDefaultExtraInstallKernelParameters += " priority=critical";
589 mStrDefaultExtraInstallKernelParameters += " quiet";
590 mStrDefaultExtraInstallKernelParameters += " splash";
591 mStrDefaultExtraInstallKernelParameters += " noprompt"; /* no questions about things like CD/DVD ejections */
592 mStrDefaultExtraInstallKernelParameters += " noshell"; /* No shells on VT1-3 (debian, not ubuntu). */
593 mStrDefaultExtraInstallKernelParameters += " automatic-ubiquity"; // ubiquity
594 // the following can probably go into the preseed.cfg:
595 mStrDefaultExtraInstallKernelParameters.append(" debian-installer/locale=").append(pParent->i_getLocale());
596 mStrDefaultExtraInstallKernelParameters += " keyboard-configuration/layoutcode=us";
597 mStrDefaultExtraInstallKernelParameters += " languagechooser/language-name=English"; /** @todo fixme */
598 mStrDefaultExtraInstallKernelParameters.append(" localechooser/supported-locales=").append(pParent->i_getLocale()).append(".UTF-8");
599 mStrDefaultExtraInstallKernelParameters.append(" countrychooser/shortlist=").append(pParent->i_getCountry()); // ubiquity?
600 mStrDefaultExtraInstallKernelParameters += " --";
601 }
602 ~UnattendedDebianInstaller() {}
603
604 bool isOriginalIsoNeeded() const { return false; }
605
606protected:
607 HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
608 RTVFS hVfsOrgIso, bool fOverwrite);
609 /**
610 * Performs basic edits on menu configuration file(s) of isolinux (txt.cfg or menu.cfg etc).
611 *
612 * @returns COM status code
613 * @param pEditor Editor with the menu config. file loaded and parsed.
614 */
615 HRESULT editDebianMenuCfg(GeneralTextScript *pEditor);
616
617 /**
618 * Performs basic edits on a isolinux.cfg file.
619 *
620 * @returns COM status code
621 * @param pEditor Editor with the isolinux.cfg file loaded and parsed.
622 * @param pszMenuConfigFileName Name of the menu config file to include in isolinux.txt. On Debians (at least)
623 it includes the kernel command line with our preseed file and command line argument.
624 */
625 virtual HRESULT editIsoLinuxCfg(GeneralTextScript *pEditor, const char *pszMenuConfigFileName);
626
627private:
628
629 /**
630 * Tries to set label name of a label line.
631 *
632 * @returns true if label line is found and label name can be set.
633 * @param pEditor Editor with the menu configuration file loaded and parsed.
634 * @param vecLineNumbers Indices of the label lines (within pEditor data).
635 * @param pszKeyWord The keyword searched within the original label name.
636 * @param pszNewLabelName The new name of the label.
637 */
638 bool modifyLabelLine(GeneralTextScript *pEditor, const std::vector<size_t> &vecLineNumbers,
639 const char *pszKeyWord, const char *pszNewLabelName);
640};
641
642
643/**
644 * Ubuntu preseed installer (same as Debian, except for the template).
645 *
646 * Only for older Ubuntu desktop versions (<= 22.04).
647 */
648class UnattendedUbuntuPreseedInstaller : public UnattendedDebianInstaller
649{
650public:
651 DECLARE_TRANSLATE_METHODS(UnattendedUbuntuPreseedInstaller)
652
653 UnattendedUbuntuPreseedInstaller(Unattended *pParent)
654 : UnattendedDebianInstaller(pParent, "ubuntu_preseed.cfg")
655 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
656 ~UnattendedUbuntuPreseedInstaller() {}
657};
658
659/**
660 * Ubuntu autoinstall installer.
661 *
662 * Newer Ubuntu desktop versions (>= 22.10) as well as newer Ubuntu server versions(>= 20.04) use a different installer ("subiquity")
663 * which in turn uses the autoinstall / cloud-init installer. This is substantially different from the old preseed files,
664 * as this is now YAML-based along with a different scheme.
665 */
666class UnattendedUbuntuAutoInstallInstaller : public UnattendedDebianInstaller
667{
668public:
669 DECLARE_TRANSLATE_METHODS(UnattendedUbuntuAutoInstall)
670
671 UnattendedUbuntuAutoInstallInstaller(Unattended *pParent)
672 : UnattendedDebianInstaller(pParent,
673 /* pszMainScriptTemplateName = */ "ubuntu_autoinstall_user_data",
674 /* pszPostScriptTemplateName = */ "debian_postinstall.sh",
675 /* pszMainScriptFilename = */ "user-data")
676 {
677 Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded());
678 Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO());
679 mStrDefaultExtraInstallKernelParameters.setNull();
680 mStrDefaultExtraInstallKernelParameters += " autoinstall";
681 mStrDefaultExtraInstallKernelParameters += " ds=nocloud\\;s=/cdrom/";
682 mStrDefaultExtraInstallKernelParameters += " ---";
683 mStrDefaultExtraInstallKernelParameters += " quiet";
684 mStrDefaultExtraInstallKernelParameters += " splash";
685 mStrDefaultExtraInstallKernelParameters += " noprompt"; /* no questions about things like CD/DVD ejections */
686 mStrDefaultExtraInstallKernelParameters += " noshell"; /* No shells on VT1-3 (debian, not ubuntu). */
687 mStrDefaultExtraInstallKernelParameters += " automatic-ubiquity"; // ubiquity
688 // the following can probably go into the preseed.cfg:
689 mStrDefaultExtraInstallKernelParameters.append(" debian-installer/locale=").append(pParent->i_getLocale());
690 mStrDefaultExtraInstallKernelParameters += " keyboard-configuration/layoutcode=us";
691 mStrDefaultExtraInstallKernelParameters += " languagechooser/language-name=English"; /** @todo fixme */
692 mStrDefaultExtraInstallKernelParameters.append(" localechooser/supported-locales=").append(pParent->i_getLocale()).append(".UTF-8");
693 mStrDefaultExtraInstallKernelParameters.append(" countrychooser/shortlist=").append(pParent->i_getCountry()); // ubiquity?
694 mStrDefaultExtraInstallKernelParameters += " --";
695 }
696 ~UnattendedUbuntuAutoInstallInstaller() {}
697
698protected:
699 HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
700 RTVFS hVfsOrgIso, bool fOverwrite);
701};
702
703/**
704 * RHEL installer.
705 *
706 * This serves as a base for the kickstart based installers.
707 */
708class UnattendedRhelInstaller : public UnattendedLinuxInstaller
709{
710public:
711 DECLARE_TRANSLATE_METHODS(UnattendedRhelInstaller)
712
713 UnattendedRhelInstaller(Unattended *pParent,
714 const char *pszMainScriptTemplateName,
715 const char *pszPostScriptTemplateName,
716 const char *pszMainScriptFilename)
717 : UnattendedLinuxInstaller(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
718 {}
719 ~UnattendedRhelInstaller() {}
720
721 bool isAuxiliaryIsoIsVISO() { return true; }
722 bool isOriginalIsoNeeded() const { return false; }
723
724protected:
725 HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
726 RTVFS hVfsOrgIso, bool fOverwrite);
727};
728
729/**
730 * RHEL 6 installer.
731 *
732 */
733class UnattendedRhel6Installer : public UnattendedRhelInstaller
734{
735public:
736 DECLARE_TRANSLATE_METHODS(UnattendedRhel6Installer)
737
738 UnattendedRhel6Installer(Unattended *pParent,
739 const char *pszMainScriptTemplateName = "redhat67_ks.cfg",
740 const char *pszPostScriptTemplateName = "redhat_postinstall.sh",
741 const char *pszMainScriptFilename = "ks.cfg")
742 : UnattendedRhelInstaller(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
743 {
744 Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded());
745 Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO());
746 mStrDefaultExtraInstallKernelParameters.assign(" ks=cdrom:/").append(pszMainScriptFilename).append(' ');
747 mArrStrRemoveInstallKernelParameters.append("rd.live.check"); /* Disables the checkisomd5 step. Required for VISO. */
748 }
749 ~UnattendedRhel6Installer() {}
750};
751
752/**
753 * RHEL 7 installer (same as RHEL 6).
754 * The class was added for better handling any possible subtle difference between RHEL6 and RHEL7.
755 */
756class UnattendedRhel7Installer : public UnattendedRhel6Installer
757{
758public:
759 DECLARE_TRANSLATE_METHODS(UnattendedRhel7Installer)
760
761 UnattendedRhel7Installer(Unattended *pParent)
762 : UnattendedRhel6Installer(pParent)
763 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
764
765 UnattendedRhel7Installer(Unattended *pParent,
766 const char *pszMainScriptTemplateName,
767 const char *pszPostScriptTemplateName,
768 const char *pszMainScriptFilename)
769 : UnattendedRhel6Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
770 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
771 ~UnattendedRhel7Installer() {}
772};
773
774
775/**
776 * RHEL 8 installer (same as RHEL 7).
777 * The class was added for better handling any possible subtle difference between RHEL7 and RHEL8.
778 */
779class UnattendedRhel8Installer : public UnattendedRhel7Installer
780{
781public:
782 DECLARE_TRANSLATE_METHODS(UnattendedRhel8Installer)
783
784 UnattendedRhel8Installer(Unattended *pParent)
785 : UnattendedRhel7Installer(pParent)
786 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
787
788 UnattendedRhel8Installer(Unattended *pParent,
789 const char *pszMainScriptTemplateName,
790 const char *pszPostScriptTemplateName,
791 const char *pszMainScriptFilename)
792 : UnattendedRhel7Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
793 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
794 ~UnattendedRhel8Installer() {}
795};
796
797
798/**
799 * RHEL 5 installer (same as RHEL 6, except for the kickstart template).
800 */
801class UnattendedRhel5Installer : public UnattendedRhel6Installer
802{
803public:
804 DECLARE_TRANSLATE_METHODS(UnattendedRhel5Installer)
805
806 UnattendedRhel5Installer(Unattended *pParent) : UnattendedRhel6Installer(pParent, "rhel5_ks.cfg") {}
807 ~UnattendedRhel5Installer() {}
808};
809
810
811/**
812 * RHEL 4 installer (same as RHEL 6, except for the kickstart template).
813 */
814class UnattendedRhel4Installer : public UnattendedRhel6Installer
815{
816public:
817 DECLARE_TRANSLATE_METHODS(UnattendedRhel4Installer)
818
819 UnattendedRhel4Installer(Unattended *pParent) : UnattendedRhel6Installer(pParent, "rhel4_ks.cfg") {}
820 ~UnattendedRhel4Installer() {}
821};
822
823
824/**
825 * RHEL 3 installer (same as RHEL 6, except for the kickstart template).
826 */
827class UnattendedRhel3Installer : public UnattendedRhel6Installer
828{
829public:
830 DECLARE_TRANSLATE_METHODS(UnattendedRhel3Installer)
831
832 UnattendedRhel3Installer(Unattended *pParent) : UnattendedRhel6Installer(pParent, "rhel3_ks.cfg") {}
833 ~UnattendedRhel3Installer() {}
834};
835
836
837/**
838 * Fedora installer (same as RHEL 6, except for the template).
839 */
840class UnattendedFedoraInstaller : public UnattendedRhel6Installer
841{
842public:
843 DECLARE_TRANSLATE_METHODS(UnattendedFedoraInstaller)
844
845 UnattendedFedoraInstaller(Unattended *pParent)
846 : UnattendedRhel6Installer(pParent, "fedora_ks.cfg")
847 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
848 ~UnattendedFedoraInstaller() {}
849};
850
851
852/**
853 * Oracle Linux 6 installer. Same as RHEL 6, except for the templates.
854 * The reason of adding new class is to sepatate the RHEL from OL.
855 */
856class UnattendedOracleLinux6Installer : public UnattendedRhel6Installer
857{
858public:
859 DECLARE_TRANSLATE_METHODS(UnattendedOracleLinux6Installer)
860
861 UnattendedOracleLinux6Installer(Unattended *pParent,
862 const char *pszMainScriptTemplateName = "ol_ks.cfg",
863 const char *pszPostScriptTemplateName = "ol_postinstall.sh",
864 const char *pszMainScriptFilename = "ks.cfg")
865 : UnattendedRhel6Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
866 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
867 ~UnattendedOracleLinux6Installer() {}
868};
869
870
871/**
872 * Oracle Linux 7 installer. Same as OL 6.
873 * The class was added for better handling any possible subtle difference between OL6 and OL7.
874 */
875class UnattendedOracleLinux7Installer : public UnattendedOracleLinux6Installer
876{
877public:
878 DECLARE_TRANSLATE_METHODS(UnattendedOracleLinux7Installer)
879
880 UnattendedOracleLinux7Installer(Unattended *pParent)
881 : UnattendedOracleLinux6Installer(pParent)
882 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
883
884 UnattendedOracleLinux7Installer(Unattended *pParent,
885 const char *pszMainScriptTemplateName,
886 const char *pszPostScriptTemplateName,
887 const char *pszMainScriptFilename)
888 : UnattendedOracleLinux6Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
889 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
890 ~UnattendedOracleLinux7Installer() {}
891};
892
893
894/**
895 * Oracle Linux 8 installer. Using a different kickstart file than earlier OL versions.
896 */
897class UnattendedOracleLinux8Installer : public UnattendedOracleLinux7Installer
898{
899public:
900 DECLARE_TRANSLATE_METHODS(UnattendedOracleLinux8Installer)
901
902 UnattendedOracleLinux8Installer(Unattended *pParent,
903 const char *pszMainScriptTemplateName = "ol8_ks.cfg",
904 const char *pszPostScriptTemplateName = "ol_postinstall.sh",
905 const char *pszMainScriptFilename = "ks.cfg")
906
907 : UnattendedOracleLinux7Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
908 { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
909 ~UnattendedOracleLinux8Installer() {}
910};
911
912/**
913 * Oracle Linux 9 installer.
914 * Uses a different kickstart file since several commands/options are removed in OL9.
915 * See the ol9_ks.cfg file for comments. Also, as of OL9 kernel command argument 'ks' should have
916 * 'inst.' prefix.
917 */
918class UnattendedOracleLinux9Installer : public UnattendedRhelInstaller
919{
920public:
921 DECLARE_TRANSLATE_METHODS(UnattendedOracleLinux9Installer)
922
923 UnattendedOracleLinux9Installer(Unattended *pParent,
924 const char *pszMainScriptTemplateName = "ol9_ks.cfg",
925 const char *pszPostScriptTemplateName = "ol_postinstall.sh",
926 const char *pszMainScriptFilename = "ks.cfg")
927 : UnattendedRhelInstaller(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
928 {
929 Assert(!isOriginalIsoNeeded());
930 Assert(isAuxiliaryIsoNeeded());
931 Assert(!isAuxiliaryFloppyNeeded());
932 Assert(isAuxiliaryIsoIsVISO());
933 mStrDefaultExtraInstallKernelParameters.assign(" inst.ks=cdrom:/").append(pszMainScriptFilename).append(' ');
934 mArrStrRemoveInstallKernelParameters.append("rd.live.check"); /* Disables the checkisomd5 step. Required for VISO. */
935 }
936 ~UnattendedOracleLinux9Installer() {}
937};
938
939
940#if 0 /* fixme */
941/**
942 * SUSE linux installer.
943 *
944 * @todo needs fixing.
945 */
946class UnattendedSuseInstaller : public UnattendedLinuxInstaller
947{
948public:
949 DECLARE_TRANSLATE_METHODS(UnattendedSuseInstaller)
950
951 UnattendedSuseInstaller(BaseTextScript *pAlg, Unattended *pParent)
952 : UnattendedLinuxInstaller(pAlg, pParent, "suse_autoinstall.xml")
953 { Assert(isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(!isAuxiliaryIsoIsVISO()); }
954 ~UnattendedSuseInstaller() {}
955
956 HRESULT setupScriptOnAuxiliaryCD(const Utf8Str &path);
957};
958#endif
959
960/**
961 * Base class for the unattended FreeBSD installers.
962 */
963class UnattendedFreeBsdInstaller : public UnattendedInstaller
964{
965public:
966 UnattendedFreeBsdInstaller(Unattended *pParent)
967 : UnattendedInstaller(pParent,
968 "freebsd_installer.cfg", "freebsd_postinstall.sh",
969 "installerconfig", "vboxpostinstall.sh") {}
970 ~UnattendedFreeBsdInstaller() {}
971
972 bool isAuxiliaryIsoNeeded() const { return true; }
973 bool isOriginalIsoNeeded() const { return false; }
974
975protected:
976 HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
977 RTVFS hVfsOrgIso, bool fOverwrite);
978};
979
980#endif /* !MAIN_INCLUDED_UnattendedInstaller_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use