Essa questãotalvez esteja relacionado com o que estou perguntando aqui.
Isto está no contexto dehttps://github.com/bstarynk/helpcovid/(um software GPLv3+ para Linux, atualmente -abril de 2020- emativodesenvolvimento, que é um aplicativo da web multithreaded C++ especializado para Linux, entãotrabalho em progressoem 8 de abril de 2020)
Estou alugando um VPS em host b-star-y.tech
rodando Linux/Debian/Buster.
Estou desenvolvendo com outrosajudacovid, um software de aplicação web multithread GPLv3+ codificado para Linux em C++17.
Eu não estou familiarizado comsystemd
, que é usado pelo Debian/Buster naquele host, ou comdocker
Eu gostaria de implementaro seguinte loop infinitoem uma git clone
árvore de arquivos d.
git pull
make
- execute
./helpcovid -D -T2
com stderr e stdout redirecionados para algum arquivo. sleep 5
erepetir indefinidamente.
Estou tentado a usar umcrontabtrabalho, ou talvez atd
combatch
Existe uma maneira melhor com systemd
?
Você pode me enviar um e-mail para[email protected]
Responder1
Há cerca de um quarto de século, temos conjuntos de ferramentas que permitem que usuários sem privilégios executem serviços nonce ad hoc. Daemontools de Daniel J. Bernsteiné um dos primeiros. Um nãoterpara configurar diretórios de varredura e outras infraestruturas. Pode-se simplesmente executar um programa sobsupervise
diretamente. Conjunto de ferramentas UCSPI-TCP de M. BernsteinAlém disso, é um exemplo dos vários conjuntos de ferramentas que temos há um período semelhante que lidam com serviços que precisam aceitar conexões TCP e fazer outras coisas.
Existem outros conjuntos de ferramentas que fazem o mesmo, sem a necessidade do systemd, e claro, com o systemd pode-setambémconfigurar serviços ad hoc por usuário.
Estamos em 2020. Não há um bom motivo para escrever novos programas que usem o frágil e perigoso mecanismo de arquivo PID. Não há necessidade de nenhum código de arquivo PID que você escreveu.
Da mesma forma, é uma boa ideia escrever um servidor TCP para que ele possaherdarseu soquete de escuta, como um descritor de arquivo já aberto. Esta é na verdade a maneira queNo âmbito do sistemaOs serviços, executados pela Inted, operam convencionalmente desde a década de 1980. Isso também pode ser feito com serviços por usuário. Os conjuntos de ferramentas s6 e nosh, e de fato o systemd, fornecem maneiras pelas quais um serviço pode receber seu soquete de escuta. Não há necessidade dequalquerdaquele código de análise de URL nonce que você escreveu, que, como muitos analisadores improvisados, não lida com todos os formatos que um URL pode assumir.
Infelizmente, como eu disse, sua cpp-httplib
biblioteca não possui um construtor ou membro de função onde possa serdadoo descritor de arquivo para o soquete de escuta. Este é um grande descuido no design dessa biblioteca, visto que herdar descritores de arquivos de soquete tem sido uma prática normal por três décadas e pouco.
algooutro que não sejasistema
Ambosmeu conjunto de ferramentas nosheConjunto de ferramentas s6 de Laurent Bercotfornecer maneiras de executar programas nonce como serviços ad hoc por usuário.
No conjunto de ferramentas nosh, teríamos um helpcovid
subdiretório, com um service
subdiretório abaixo contendo os vários programas para lidar com o serviço.
helpcovid/service/start
e helpcovid/service/stop
são bastante mínimos:
#!/bin/nosh
#Start file generated from ./helpcovid.socketand ./helpcovid.service
true
#!/bin/nosh
#Stop file generated from ./helpcovid.socketand ./helpcovid.service
true
A carne está dentro helpcovid/service/run
e helpcovid/service/service
:
#!/bin/nosh
#Run file generated from ./helpcovid.socketand ./helpcovid.service
#Starynkevitch helpcovid listening socket
tcp-socket-listen --systemd-compatibility ::0 50002
envdir env
setenv LC_ALL fr_FR.UTF-8
chdir /home/basile/dev/helpcovid/test
./service
#!/bin/nosh
#Service file generated from ./helpcovid.service
#Starynkevitch helpcovid service
sh -c 'exec /home/basile/dev/helpcovid/work/helpcovid ${flags}'
E helpcovid/service/restart
controla a lógica de reinicialização:
#!/bin/sh
#Restart file generated from ./helpcovid.service
sleep 5
exec true # ignore script arguments
Este seria executado fornecendo-o a uma instância por usuário do service-manager
. O conjunto de ferramentas faz a ligação e escuta no soquete, lê a configuração da variável de ambiente de um envdir e passa o descritor de arquivo aberto para o programa eventual usando o LISTEN_FDS
protocolo, tendo mudado o diretório de trabalho para o local onde reside seu diretório de teste webroot/
.
Uma estrutura semelhante é empregada pelo s6, embora os nomes das ferramentas sejam diferentes (por exemplos6-tcpserver6-socketbinder
em vez detcp-socket-listen
) e a lógica de reinicialização é tratada de maneira diferente. s6 não requer um gerenciador de serviços. Como os daemontools originais, basta executars6-supervise
manualmente para invocar um serviço:
s6-supervisionar ./helpcovid/service/
Não vou entrar em muitos detalhes, pois o ponto principal é que não ter o systemd não é desculpa para um mau design do daemon (na verdade, bons princípios de design do daemonoriginado commecanismos não-systemd muito mais antigos) e que os mecanismos para passar descritores de arquivos abertos para soquetes de escuta se aplicam e podem ser usados com mais do que apenas o systemd.
sistema
Os programas acima mencionados foram na verdade convertidos de um systemdunidade de soqueteeunidade de serviçoque eu rapidamente juntei. Eles mostram como configurar um serviço por usuário no systemd, com arquivos em ~/.config/systemd/user/
:
# helpcovid.socket
[Unit]
Description=Starynkevitch helpcovid listening socket
[Socket]
ListenStream=50002
Accept=No
[Install]
Wanted-By=default.target
# helpcovid.service
[Unit]
Description=Starynkevitch helpcovid service
[Service]
Environment=LC_ALL=fr_FR.UTF-8
Restart=always
RestartSec=5
ExecStart=/home/basile/dev/helpcovid/work/helpcovid ${flags}
WorkingDirectory=/home/basile/dev/helpcovid/test
#This has no meaning for systemd.
EnvironmentDirectory=env
Isso é controlado com nomes como systemctl --user start helpcovid.socket
.
No mundo do systemd, essessãoos arquivos de configuração. O usuário deseja alterar o número da porta TCP? O usuário altera a ListenStream=
configuração. Não há necessidade de variáveis de ambiente extras redundantes para definir a localidade. O usuário apenas define a LC_ALL
variável real (ou qualquer outra) da maneira mostrada.
exploração madeireira
O registro em log também é tratado pelo gerenciamento de serviços. O conjunto de ferramentas nosh e a maneira s6 é alimentar a saída padrão e o erro padrão através de um canal para um serviço secundário em execução cyclog
, s6-log
ou algo assim. O systemd armazena a saída do log na parte do usuário do diário centralizado do systemd, que você usa journalctl --user
para ler.
seu programa
Seu programa precisa fazer logon std::clog
(ou seja, erro padrão), chamar setlocale()
com NULL
para ler as variáveis de ambiente padrão e ter código que lide com o LISTEN_FDS
mecanismo. Existem muitas opções para esse último, desde uma biblioteca de funções auxiliares não portátil que vem com o systemd até soluções mais portáteis de outras pessoas.
Definitivamente, é muito menos código para inserir do que todo aquele código de análise de número de porta TCP, código de arquivo PID frágil e perigoso e HELPCOVID_LOCALE
código --locale
que pode ser retirado dessa maneira. ☺
Leitura adicional
- Jonathan de Boyne Pollard (2001). Erros a evitar ao projetar programas daemon Unix. Respostas dadas com frequência.
- https://github.com/jdebp/nosh/blob/ddb422c9e6db11aee1c22a171bcc729edc7fe1c3/source/listen.cpp#L1
- Problemas: