Téléverser les fichiers vers "workstation-setup/src"

This commit is contained in:
2026-08-19 08:48:11 +02:00
parent d37ca8fafe
commit 9fe105bae8
3 changed files with 98 additions and 19 deletions
+92 -15
View File
@@ -1,16 +1,38 @@
#include "ProvisioningBackend.h"
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfo>
#include <QGuiApplication>
#include <QIcon>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQuickStyle>
#include <QString>
#include <cstring>
#include <sys/resource.h>
int main(int argc, char *argv[])
{
// Les champs contiennent temporairement des secrets : pas de core dump.
// --diagnose doit aussi fonctionner depuis un TTY sans session graphique.
// QGuiApplication reste utilisé pour partager exactement le même parsing,
// mais la plate-forme Qt passe alors en mode offscreen si rien n'est imposé.
bool diagnoseRequested = false;
for (int i = 1; i < argc; ++i) {
if (std::strcmp(argv[i], "--diagnose") == 0) {
diagnoseRequested = true;
break;
}
}
if (diagnoseRequested && qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) {
qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("offscreen"));
}
// Les champs contiennent temporairement des secrets : aucun core dump.
rlimit coreLimit { 0, 0 };
setrlimit(RLIMIT_CORE, &coreLimit);
@@ -19,34 +41,89 @@ int main(int argc, char *argv[])
QGuiApplication::setOrganizationName(QStringLiteral("Raspot"));
QGuiApplication::setOrganizationDomain(QStringLiteral("raspot.in"));
QGuiApplication::setApplicationName(QStringLiteral("NixOS Workstations Setup"));
QGuiApplication::setApplicationVersion(QStringLiteral("1.1.0"));
QGuiApplication::setDesktopFileName(QStringLiteral("org.raspot.nixosworkstations.setup"));
QCommandLineParser parser;
parser.setApplicationDescription(QStringLiteral("Assistant de finalisation NixOS Workstations"));
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption targetUserOption(
QStringList { QStringLiteral("u"), QStringLiteral("target-user") },
QStringLiteral("Compte autorisé à exécuter l'assistant."),
QStringLiteral("user"));
parser.addOption(targetUserOption);
QCommandLineOption diagnoseOption(
QStringList { QStringLiteral("diagnose") },
QStringLiteral("Affiche l'état de l'assistant puis quitte."));
parser.addOption(diagnoseOption);
QCommandLineOption forceUiOption(
QStringList { QStringLiteral("force-ui") },
QStringLiteral("Affiche l'interface même si la configuration est déjà terminée."));
parser.addOption(forceUiOption);
parser.process(app);
const QString targetUser = parser.value(targetUserOption).trimmed();
if (targetUser.isEmpty()) {
qCritical().noquote()
<< "ERREUR: --target-user est obligatoire. Exemple:"
<< QCoreApplication::applicationName()
<< "--target-user alice";
return 2;
}
ProvisioningBackend provisioning(targetUser);
if (parser.isSet(diagnoseOption)) {
qInfo().noquote() << "version=1.1.0";
qInfo().noquote() << "current_user=" + provisioning.currentUser();
qInfo().noquote() << "target_user=" + provisioning.targetUser();
qInfo().noquote() << "authorized=" + (provisioning.authorizedUser() ? QStringLiteral("yes") : QStringLiteral("no"));
qInfo().noquote() << "state_dir=" + provisioning.stateDirectory();
qInfo().noquote() << "password_marker=" + provisioning.passwordMarker();
qInfo().noquote() << "password_done=" + (provisioning.passwordDone() ? QStringLiteral("yes") : QStringLiteral("no"));
qInfo().noquote() << "pin_marker=" + provisioning.pinMarker();
qInfo().noquote() << "pin_done=" + (provisioning.pinDone() ? QStringLiteral("yes") : QStringLiteral("no"));
qInfo().noquote() << "log=" + provisioning.diagnosticLogPath();
return provisioning.authorizedUser() ? 0 : 3;
}
// Le lanceur filtre déjà le compte, mais le backend vérifie également.
// Contrairement à la V1, on ne quitte plus sans explication.
if (!provisioning.authorizedUser()) {
qCritical().noquote()
<< "ERREUR: l'assistant est prévu pour"
<< provisioning.targetUser()
<< "mais il est exécuté par"
<< provisioning.currentUser();
return 3;
}
if (provisioning.complete() && !parser.isSet(forceUiOption)) {
qInfo().noquote()
<< "NixOS Workstations Setup: configuration déjà terminée."
<< "Utilisez --force-ui pour afficher l'écran récapitulatif.";
return 0;
}
QIcon::setThemeName(QStringLiteral("breeze"));
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
QQuickStyle::setStyle(QStringLiteral("Basic"));
}
ProvisioningBackend provisioning;
// Défense en profondeur : le lanceur filtre déjà l'utilisateur, mais
// le backend refuse également toute opération pour un autre compte.
if (!provisioning.authorizedUser()) {
return 0;
}
// Si les deux marqueurs existent, l'assistant n'a plus rien à faire.
if (provisioning.complete()) {
return 0;
}
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty(QStringLiteral("provisioning"), &provisioning);
engine.loadFromModule(QStringLiteral("org.raspot.nixosworkstations.setup"),
QStringLiteral("Main"));
if (engine.rootObjects().isEmpty()) {
return 1;
qCritical() << "ERREUR: impossible de charger l'interface QML.";
return 4;
}
return app.exec();