Como parte de um fluxo que instala o Ubuntu 16.04 (do zero até totalmente configurado, com muitos softwares extras instalados e alterações feitas após a instalação), preciso de uma maneira de executar scripts (que são baixados durante a instalação) após a próxima reinicialização (e apenas a próxima reinicialização) e remova os scripts e termine com outra reinicialização.
Já tenho um serviço que utilizo para executar scripts após a primeira inicialização, mas sem excluí-los (isso pode ser acionado novamente posteriormente, se necessário), mas agora descobri que preciso executar scripts que devem ser excluídos posteriormente, como eles contêm informações confidenciais.
O serviço systemd que estou usando para os outros scripts é assim:
[Unit]
Description=First run specifics
After=network-online.target
Requires=network-online.target
[Service]
Type=simple
EnvironmentFile=/etc/default/firstrun
ExecStart=/root/bin/firstrun-wrapper "${PASSWORD}"
[Install]
WantedBy=multi-user.target
/etc/default/firstrun e /root/bin/firstrun-wrapper são adicionados durante a instalação. /etc/default/firstrun contém uma senha e é excluído pelo script firstrun-wrapper, evitando que o serviço seja iniciado novamente após uma reinicialização. firstrun-wrapper executa vários scripts adicionados durante a instalação e termina com uma reinicialização.
O serviço pode ser usado novamente posteriormente para executar a mesma configuração (adicionando o arquivo /etc/default/firstrun)
Então minha pergunta é.Como posso executar um script após a próxima reinicialização, removendo o script após sua execução e, após removê-lo, acionar uma reinicialização?
Não importa para mim se isso usa o systemd ou não, e estou bem com um arquivo 'vazio' (significado vazio que não contém informações relevantes/sensíveis) sendo deixado no sistema depois disso.
Meu pensamento inicial foi modificar meu serviço atual. Eu pensei em adicionar outro script no firstrun-wrapper que remove certos arquivos e modifica o firstrun-wrapper para não incluí-los mais, e executar esse script através do ExecStopPost, mas isso não é acionado pelo serviço terminar por conta própria (pelo que eu pode dizer). Mesmo que eu possa modificar o arquivo firstrun-wrapper enquanto ele está sendo executado, entendo que seria uma má prática, então estou tentando evitar isso.
Responder1
Você precisa executar crontab -e
para o usuário que irá executar o script - sudo crontab -e
pararaizou sudo -u user_name -e
para editar o crontab paranome de usuário. Inserir @reboot /path/to/file
(NB! Não esqueça a nova linha vazia). O script em si deve ficar assim:
#!/bin/bash
do_your_stuff
# remove from root specific crontab setting all the information about the script
sed -i '/@reboot \/path\/to\/file/d' /var/spool/cron/crontabs/root
# remove the script file itself
rm -- "$0"
# reboot the machine in 2 minutes
shutdown -r +2
Para automatizar esse processo você pode usar Ansible. Aqui está um exemplo de um manual simples, que executei em meu host local:
---
- hosts: localhost
tasks:
- name: cron job
cron:
name: "a job for reboot"
special_time: reboot
job: "/path/to/file"
Primeiro, você precisa executar o playbook, ele atualiza as tarefas cron para root
. Após a reinicialização, o script deve ser excluído assim como a /var/spool/cron/crontabs/root
entrada do arquivo com@reiníciocorda. Você está livre para modificar o arquivo para excluir totalmente o crontab para root, se necessário.