Script lancé au premier boot

Bonjour,

Y-a-t-il un moyen prévu dans Debian pour lancer un script au premier bot suivant? ( run-once )
je n’ai trouvé que deux solutions:

  • des script plus ou moins complexes et plus ou moins portables.
  • utiliser crontab avec @reboot : la question que je me pose c’est de savoir si cette option disparait après le premier reboot?
    merci de votre aide

A première vue je dirais Cloud-init qui permet à coup sûr ce type de comportement.
De simple script bash ou autre peuvent être alors utilisé à chaque boot, au premier boot etc …
Cloud-init est un outil largement utilisé dans l’industrialisation de ressources dans le cloud, il est bien documenté … par contre plusieurs modules dont celui pour l’agrandissement automatique de partition nécessite un système en anglais (pas les locales mais le système … pour un obscure problème d’unités :confused: ).

On peut aussi utiliser une tâche cron qui s’autodétruit. Le script appelé fait ce qu’il a à faire et vérifie que c’est bien fait puis supprime la tâche cron.

Anacron avec ses tâches /etc/cron.daily est fait pour ça

@grandtoubab : encore une réponse à côté de la plaque. À se demander si ce n’est juste pour faire la promo de ton site…

Non anacron ne permet pas de faire ce qui est demandé. C’est juste une surcouche à cron pour que les tâches programmées s’exécutent sur une machine qui n’est pas allumée 24/7, typiquement une machine de bureau.

Désolé de contredire mais le titre c’est « script lancé au premier boot »
Anacron lance les scripts posés dans /etc/cron.daily au premier boot at uniquement au premier boot grâce à l’horodatage
daily ça veut dire quotidien et quotidien ça veut dire une fois par jour

On peut aussi se faire très facilement un service systemd avec la condition
ConditionFirstBoot=

Takes a boolean argument. This condition may be used to conditionalize units on whether the system is booting up for the first time. This roughly means that /etc/ is unpopulated (for details, see "First Boot Semantics" in machine-id(5)). This may be used to populate /etc/ on the first boot after factory reset, or when a new system instance boots up for the first time.

For robustness, units with ConditionFirstBoot=yes should order themselves before first-boot-complete.target and pull in this passive target with Wants=. This ensures that in a case of an aborted first boot, these units will be re-run during the next system startup.

If the systemd.condition-first-boot= option is specified on the kernel command line (taking a boolean), it will override the result of this condition check, taking precedence over /etc/machine-id existence checks.

https://www.freedesktop.org/software/systemd/man/systemd.unit.html#

De ce que j’ai compris de la question de @Zargos, c’est qu’il voulait lancer son script au premier redémarrage et plus jamais ensuite.
Ce que tu proposes ne permet pas cela. Le script serait lancé à chaque démarrage quotidien.

EDIT : pour systemd, je n’ai pas creusé mais cela me semble correspondre à des conditions vraiment très particulières.

C’est ce à quoi j’en étais finalement arrivé.
Une tâche reboot dans crontab, qui ensuite s’auto-détruit, ainsi que la configuration dans crontab (je vais tout de même tester pour voir si crontab efface lui même)…

MAJ test: la tâche @reboot de crontab ne disparait pas d’elle même et est rejouée à chaque reboot. Il faut donc supprimer la tâche crontab si on ne la veut qu’une seule fois.

J’ai fait un test avec le script suivant:

#!/bin/bash
touch /root/job_done
sed -i '/@reboot/d' /var/spool/cron/crontabs/root

Après avoir mis l’entrée suivante dans crontab avec:
echo "@reboot bash /root/text_crontab.sh > /var/spool/cron/crontabs/root

mais je ne suis pas sur que ce soit propre.

Tu as mis ta tâche dans le crontab de l’utilisateur root (/var/spool/cron/crontabs/root) . Si c’est la seule, tu peux simplement faire :

crontab -r

Un autre façon de faire serait de créer un fichier /etc/cron.d/truc :

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
@reboot root bash /root/text_crontab.sh

Et dans le script :

#!/bin/bash
touch /root/job_done
rm /etc/cron.d/truc

On pourrait aussi utiliser un timer systemd qui appelle un script qui fait ce qu’il a à faire et finalement désactive ce timer.

j’avoue que je ne suis pas très à l’aise avec les timers. Je ne connais pas très bien, ne les utilisant quasiment pas.

Il y en a au moins une troisième: utilisation de /etc/rc.local, qui pourrait contenir:

#!/bin/sh
source ./script_init
exit 0

et /etc/script_init

#!/bin/sh
... mes commandes init ....

# effacement ligne source de  /etc/rc.local
sed -i '/source/d' /etc/rc.local
exit 0

En fait, le problème est que rc.local doit maintenant être activé par systemd, alors que systématiquement exécuté auparavant, avant que systemd ne soit introduit.

Question: quel est ton besoin réel de ce script qui s’exécute une seule fois ?
Quel est le problème de l 'exécuter manuellement qu’une seule fois ??
Pourquoi rechercher cette complication ?

A part implanter un virus, je vois pas

C’est un script de post-installation qui suit une installation preseed. L’objectif est d’avoir une machine entièrement configurée et opérationnelle immédiatement à la fin de l’installation, sans aucune opération manuelle à réaliser.
Certaines commandes ne peuvent pas être réalisée en late_command:

  • En particulier les commandes liées à systemd, car l’installer de debian est sur sysinitv.
  • Il y a aussi l’initialisation de aide qui n’est pas concluante en mode in-target, ainsi que l’utilisation d’un aidecheck.service et un aidecheck.timer.
  • De la même façon, la mise en place de Shorewall et Shorewall6 n’est pas propre.
  • et enfin, la désactivation de rsync, ainsi que la modification de la configuration de journald.

Pour ce qui est de /etc/rc.local, pas possible non plus. car effectivement il n’est possible qu’avec systemd, et donc nécessiterait deux redémarrage: le premier après l’installation, le deuxième après l’activation de rc.local.

Donc si tu n’a pas qu’une opération à effectuer et que tu cherche à automatiser, Cloud-init ou l’utilisation de Ansible en méthode pull semble convenir, ou bien du Puppet qui ira chercher les fact nécessaire après le premier démarrage.

Il ne s’agit que d’une seule machine, avec des contraintes de sécurité.
Elle n’est pas reliée à internet lors de son installation (elle est destinée à servir de Box en lieu et place de celle d’orange, et en remplacement de l’actuel OPNsense.

Le premier démarrage est en fait celui de la post-installation après que le preseed ait été joué. Tout se trouve sur l’iso utilisée en fait.

Et pourquoi pas dans le preseed ??? Pourquoi ‹ après › le preseed ?
Tu peux rajouter des commandes de fin d’installation dans un preseed.

Exemple: gistfile1.sh

C’est déjà ce que je fait. Mais certaines commandes ne passent pas correctement dans le preseed comme je le disais précédemment:

  • les commandes systemctl par exemple ne passe pas correctement à cause de sysinitv utilisé par l’installer: un simple systemctl enable shorewall par exemple
  • le shorewall compile génère aussi des erreurs

Et du fait de l’utilisation de Storage=persistent dans la conf de journald génère un bug du à systemd qui génère une erreur au shutdown du démontage de /var/log. Le package systemd stable n’est pas compatible, le bug est corrigé dans la version 423. Il me faut donc utiliser le package backport en 426.

C’est clair que déjà chatouiller systemd en post-install, ça complique un peu.
Ce pourrait être directement dans les fichiers de configuration par défaut de systemd qu’il faudrait agir (écrire) ?
Ta demande est trop pointue sans pouvoir facilement expérimenter.
Tu risques de te sentir un peu seul.

j’ai fait près de 15 test d’install preseed :smiley:

malheureusement non, le bug est directement lié au paramétrage storage.
en fait, ce paramètre détermine la volatilité des messages de journald . en mode persistent, le system flush les messages dans les fichier de log de /var/log.
Hors à l’arrêt ou au redémarrage, lors du démontage de /var/log (ou de /var), le lancement du processus de démontage voit le point monté encore en mode busy.
le bug a été corrigé dans systemd version 423.

sinon le seul moyen de bypass le bug c est de dégrader la volatilité. Mais Store=persistent est un paramètre voulu pour des raisons de sécurité.

J’ai vu ça déjà en cherchant sur internet. je me suis paluché un paquet de page de bugs et de leurs commentaires.