125 lines
3.9 KiB
Lua
125 lines
3.9 KiB
Lua
local DEFAULT_INSTALLER_LABEL = 'TrapOS Installer';
|
|
local DEFAULT_INSTALL_URL = 'https://os.trapcloud.fr/install';
|
|
local DEFAULT_SETTINGS_SOURCE_PATH = '/.settings';
|
|
|
|
local function writeFile(path, body)
|
|
local file = fs.open(path, 'w');
|
|
if not file then return false; end
|
|
file.write(body);
|
|
file.close();
|
|
return true;
|
|
end
|
|
|
|
local function createInstallerDisk(opts)
|
|
opts = opts or {};
|
|
local peripheralApi = opts.peripheral or peripheral;
|
|
local settingsApi = opts.settings or settings;
|
|
local settingsSourcePath = opts.settingsSourcePath or DEFAULT_SETTINGS_SOURCE_PATH;
|
|
local installerLabel = opts.installerLabel or DEFAULT_INSTALLER_LABEL;
|
|
local installUrl = opts.installUrl or DEFAULT_INSTALL_URL;
|
|
|
|
local api = {};
|
|
|
|
function api.buildAutorun()
|
|
return '-- TrapOS installer disk autorun (generated; do not edit)\n'
|
|
.. "local INSTALLER_LABEL = '" .. installerLabel .. "';\n"
|
|
.. "local INSTALL_URL = '" .. installUrl .. "';\n"
|
|
.. '\n'
|
|
.. "if fs.exists('/trapos') then return; end\n"
|
|
.. '\n'
|
|
.. 'local function installerMount()\n'
|
|
.. ' for _, name in ipairs(peripheral.getNames()) do\n'
|
|
.. " if peripheral.getType(name) == 'drive' then\n"
|
|
.. ' local drive = peripheral.wrap(name);\n'
|
|
.. ' if drive.isDiskPresent() and drive.getDiskLabel() == INSTALLER_LABEL then\n'
|
|
.. ' return drive.getMountPath();\n'
|
|
.. ' end\n'
|
|
.. ' end\n'
|
|
.. ' end\n'
|
|
.. 'end\n'
|
|
.. '\n'
|
|
.. 'local mount = installerMount();\n'
|
|
.. 'if mount then\n'
|
|
.. " local src = fs.combine(mount, '.settings');\n"
|
|
.. ' if fs.exists(src) then\n'
|
|
.. " fs.delete('/.settings');\n"
|
|
.. " fs.copy(src, '/.settings');\n"
|
|
.. ' settings.load();\n'
|
|
.. ' end\n'
|
|
.. 'end\n'
|
|
.. '\n'
|
|
.. "print('TrapOS Installer: installing TrapOS...');\n"
|
|
.. "shell.run('wget', 'run', INSTALL_URL);\n";
|
|
end
|
|
|
|
function api.findTargetDrive()
|
|
local names = peripheralApi.getNames and peripheralApi.getNames() or {};
|
|
local presentCount = 0;
|
|
local nonEmptyCount = 0;
|
|
local empty = {};
|
|
|
|
for _, name in ipairs(names) do
|
|
if peripheralApi.getType(name) == 'drive' then
|
|
local drive = peripheralApi.wrap(name);
|
|
if drive.isDiskPresent() and drive.hasData() then
|
|
presentCount = presentCount + 1;
|
|
local mountPath = drive.getMountPath();
|
|
if mountPath and #fs.list(mountPath) == 0 then
|
|
empty[#empty + 1] = { name = name, mountPath = mountPath, drive = drive };
|
|
else
|
|
nonEmptyCount = nonEmptyCount + 1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if #empty > 1 then
|
|
return false, 'multiple blank disks found, remove all but one';
|
|
end
|
|
if #empty == 1 then
|
|
return true, empty[1];
|
|
end
|
|
if presentCount > 0 or nonEmptyCount > 0 then
|
|
return false, 'disk not empty; insert a blank floppy';
|
|
end
|
|
return false, 'insert a blank floppy';
|
|
end
|
|
|
|
function api.create()
|
|
local ok, target = api.findTargetDrive();
|
|
if not ok then return false, target; end
|
|
|
|
target.drive.setDiskLabel(installerLabel);
|
|
|
|
local result = {
|
|
name = target.name,
|
|
mountPath = target.mountPath,
|
|
label = installerLabel,
|
|
settingsCopied = false,
|
|
settingsWarning = false,
|
|
};
|
|
|
|
if fs.exists(settingsSourcePath) then
|
|
settingsApi.save();
|
|
local dest = fs.combine(target.mountPath, '.settings');
|
|
fs.delete(dest);
|
|
fs.copy(settingsSourcePath, dest);
|
|
result.settingsCopied = true;
|
|
else
|
|
result.settingsWarning = true;
|
|
end
|
|
|
|
local startupPath = fs.combine(target.mountPath, 'startup.lua');
|
|
fs.delete(startupPath);
|
|
if not writeFile(startupPath, api.buildAutorun()) then
|
|
return false, 'failed to write ' .. startupPath;
|
|
end
|
|
|
|
return true, result;
|
|
end
|
|
|
|
return api;
|
|
end
|
|
|
|
return createInstallerDisk;
|