Atribuição: de quem é um processo
Ao terminar esta página você sabe como o ambiente descobre a que app pertence cada processo do
servidor, por que essa descoberta não usa a linha de comando, e o que ela decide na tela: o
agrupamento do gerenciador de tarefas, o botão que aparece ao lado de cada entidade e o que um
stop alcança.
A marca
Todo processo que o vssh-app-run sobe carrega VSSH_APP_ID=<id> no ambiente. O exec que
substitui o script pelo runtime mantém o PID e o environ, e cada filho que o app gerar herda a
variável. É essa marca, lida de /proc/<pid>/environ, que diz de quem é um processo.
A linha de comando não serve para isso. Depois do exec, o cmdline do processo é o do runtime
(python3 backend/main.py, node backend/server.js, o binário), e um pgrep -f "vssh-app-run <id>" para de casar segundos depois da subida. Um PID reciclado também engana: o run.pid diz
onde procurar, e o environ confirma que quem está lá é mesmo este app.
Para conferir à mão, no servidor:
pid=$(sudo -u <usuario> cat ~<usuario>/.vssh-apps/<id>/run.pid)
tr '\0' '\n' < /proc/$pid/environ | grep '^VSSH_APP_ID='
É a verificação que o portal e o vssh-app-install --force fazem antes de agir sobre um processo.
Um --force sinaliza SIGTERM só ao que responde por este app.
O que o gerenciador de tarefas faz com ela
O gerenciador de tarefas do ambiente lista entidades, e o agrupamento é a marca. Um app é a árvore
de processos que carrega o seu VSSH_APP_ID, com o consumo somado. O que não tem marca fica fora
da lista agrupada; a busca continua alcançando tudo.
A segunda fonte da lista é o registro de apps: quem é kind: service e tem pacote aparece parado
quando não está de pé, porque um serviço que caiu não tem processo para ser listado.
Quatro regras decidem o botão que aparece no rodapé para a entidade selecionada, e as quatro são lidas de declarações:
- um app vai pelo ciclo de vida: parar é
POST /api/apps/:id/stop, e o sinal fica para os outros casos; - a árvore de quem declara
provides: terminal/v1é o trabalho da pessoa, e vai por sinal. Umpython3 treina.pynascido num terminal é da pessoa, e o gerenciador não o trata como parte do app de terminal; - quem não tem pacote no servidor (o Supervisor de Apps) não tem ciclo de vida do ambiente e não ganha botão nenhum;
- o que o ciclo de vida não alcança vai por sinal. Um processo marcado fora da árvore do
run.pidsobrevive aostop, que ainda assim responde 200. O caso se reconhece pela contradição entre as duas fontes (o supervisor dizstoppedoufailed, e há processos com a marca), e a janela confere numa segunda leitura antes de virar veredito, porque o supervisor varre a cada 10 s e o par também é verdadeiro em todo start.
Por que o terminal é um app próprio
O agente do sistema serve arquivos, portas e a lista de processos, e um PTY caberia nele. Ele não
o serve, e o motivo é a atribuição: um shell nascido do agente carregaria VSSH_APP_ID=sistema, e
o python3 treina.py de alguém apareceria no gerenciador como "Agente do sistema". O PTY é do app
de terminal, um vssh-app com daemon próprio, e a árvore dele é lida como o trabalho da pessoa.
A mesma regra vale para o seu app. Se ele lança um processo que é da pessoa (um kernel de notebook,
um build que ela pediu), esse processo aparece como parte do seu app no gerenciador, e o stop do
app o leva junto, porque ele está na árvore do run.pid. Um app que quer ser dono de sessão de
terceiro declara aoFechar: manter, para o backend não morrer com a janela; e um app que quer
que o trabalho da pessoa apareça como dela declara provides: ["terminal/v1"].
O que a marca não é
A marca é atribuição, e o escopo do systemd é contenção. Os dois costumam coincidir: o exec
acontece dentro de um systemd-run --user --scope, então a árvore inteira do app fica no mesmo
escopo, e é sobre o escopo que os tetos de memória e de tarefas valem. Mas um servidor sem
gerenciador systemd do usuário sobe o app fora de escopo, e a marca continua lá: o gerenciador de
tarefas ainda sabe de quem é o processo, só não pode dizer que ele está contido. Os dois fatos
saem separados em ~/.vssh-apps/<id>/limits.json.
A marca também não é fronteira de segurança. Ela é lida por quem tem acesso ao /proc do dono, e
o próprio dono pode exportar VSSH_APP_ID no que quiser. O que ela dá é uma resposta uniforme à
pergunta "de quem é isto", que o ambiente inteiro lê do mesmo lugar.