CH-J Toolsgerenciamento de servidor sobre SSH
E-mail

Salvamento remoto do editor e monitoramento de latência

Transferir ficheiro

A revisão linguística desta tradução está em curso. Em caso de dúvida, consulte o original em inglês.

Causas Raiz

O editor anterior carregou seu arquivo de trabalho para o diretório pai do alvo, que muitas vezes não pode ser escrito pela conta SSH sob /etc ou /var. SFTP renomeou não forneceu nenhum caminho de sudo autorizado, verificação de conflito de linha de base, verificação de metadados de segurança ou semântica de substituição confiável. Seu manipulador de erros excluiu a cópia temporária, removendo o material de recuperação mesmo quando a conclusão era incerta.

O status da sessão expôs anteriormente apenas o estado da conexão. Não houve medição de resposta ICMP ou SSH autenticada alimentando o indicador terminal.

Salvar protocolo

  1. Um auxiliar SSH fixo abre um arquivo regular de link único usando descritor-relativo operações e O_NOFOLLOW para cada componente de caminho. Ele captura o conteúdo, SHA-256 hash, dispositivo/inode, UID, GID, bits de permissão completos, tempos de modificação / alteração de nanosegundos e todos os atributos estendidos legíveis. O Core verifica o hash e decodifica um UTF-8 rigoroso, preservando uma BOM. Cada documento recebe um editId opaco, com escopo para seu plugin, sessão de terminal e identidade do servidor.
  2. Uma operação de preparação sem privilégios resolve a conta autenticada home através de pwd.getpwuid(os.getuid()), cria $HOME/ch-j-sm/ com o modo 0700 e cria um diário de recuperação privado e exclusivo. Uma casa insegura, um espaço de trabalho do symlink ou um espaço de trabalhos pertencente a outra conta são rejeitados.
  3. Core carrega um oculto, aleatório 128-bit .tmp arquivo de trabalho através SFTP com criação exclusiva (wx), modo 0600 e um tempo limite de canal/upload de sessenta segundos. A revista contém o alvo, a linha de base original e hash de trabalho esperado; não contém credenciais.
  4. One SSH executa toda a finalização, opcionalmente através do executor sudo existente. O ajudante abre com segurança e hash a cópia de trabalho privada e limpa-lo. Ele bloqueia o inode original, verifica sua linha de base, cria um arquivo de destino exclusivo ao lado do alvo, escreve todo o conteúdo, aplica e verifica metadados, verifica o original novamente e limpa a substituição.
  5. Um mesmo diretório os.replace substitui atomicamente o alvo. O pai diretório é flushed e o caminho final, hash, inode e metadados são verificados. O caminho original permanece disponível até a substituição. O arquivo de trabalho nunca é movido através de sistemas de arquivos e nunca é removido por finalização.
  6. Depois que o Core recebe um sucesso verificado, uma limpeza separada verifica novamente a versão final. metadados de conteúdo e segurança antes de remover o arquivo e o diário de trabalho. Falha de limpeza ainda relata um salvamento confirmado com recoveryAvailable: true.

Um upload com falha, sudo com falha, conflito, erro de metadados ou substituição com falha mantém o material original e qualquer material encenado. Uploads incompletos são identificados como tal e não podem ser recuperados como um documento editado completo. A comunicação perdida do SSH, o status de saída ausente, os tempos limite e os resultados inesperados da finalização são relatados como unknown. O Core bloqueia outro salvar em um documento incerto; não há nenhuma tentativa de substituição automática.

Metadados, privilégios e limites de segurança

O ajudante preserva e verifica UID, GID e todos os bits de permissão POSIX, incluindo executáveis, setuid, setgid e sticky bits. Ele reproduz os atributos estendidos Linux byte para byte, incluindo POSIX ACLs, recursos e rótulos SELinux. A propriedade e o conteúdo do arquivo são definidos antes dos atributos de segurança, porque a gravação/corte pode limpar recursos ou bits de permissão especiais. Os atributos de destino herdados que estão ausentes no original são removidos. O tempo de modificação reflete a nova escrita e não é copiado do original.

Um atributo ilegível ou irrepresentável aborta a operação; os metadados não são descartados silenciosamente. O assinatura da IMA/EVM é explicitamente rejeitado porque a cópia do conteúdo/integridade ligada ao inodo assinatura invalidaria-os. Symlinks no caminho de destino ou home, arquivos vinculados e arquivos não regulares são rejeitados. Nenhum retorno de substituição no local ou mais fraco do SFTP é usado.

As salvas graváveis comuns são executadas como a conta SSH. Salvamentos protegidos exigem { sudo: true } explícito; uma senha sudo é opcional para sudo sem senha. As senhas são validadas e passadas apenas no canal stdin, nunca dentro do comando, diário, arquivo de trabalho, logger ou erro remoto. As sessões de root SSH usam o executor raiz direto existente. A autorização falhada deixa a cópia original e funcional intacta. Todos os salvamentos executados como root (raiz direta SSH ou sudo) também rejeitam diretórios/ancestrais de destino pertencentes ou graváveis por outras contas, ou que carregam um ACL de acesso, em vez de confiar em um nome de caminho privilegiado controlado por outra conta.

O auxiliar fixo é executado com python3 -I -B: ignora caminhos Python do usuário, o diretório de trabalho e os pacotes do site do usuário e não escreve nenhum bytecode. Os argumentos Paths e JSON são citados em shell no Core. Plugins nunca recebem comandos arbitrários SSH exec ou SFTP. sandbox existente, CSP, permissões de manifesto, verificação de chave de host e verificação atualização permanecem em uso.

Plugin API e restante integração Monaco

A interface de usuário distribuída separadamente do Monaco/File Manager está ausente neste checkout. Sua integração com a interface do usuário, sudo prompt, manipulação de buffer sujo e traduções não puderam ser implementadas ou testadas aqui. A fonte do plugin empacotado é o plug-in Hash & Checksum. Nenhuma fonte substituta do File Manager foi inventada.

Os métodos existentes permanecem disponíveis. Os métodos/opções aditivos são expostos pela pré-carga com sandbox e pelo tempo de execução verificado por permissão:

const opened = await chjPlugin.files.readText(sessionId, path);
// For a protected read, explicitly pass { sudo: true, sudoPassword }.

const result = await chjPlugin.files.saveText(sessionId, path, editor.getValue(), {
  editId: opened.editId,
  sudo: true,           // Include only after the user authorizes elevation.
  sudoPassword         // Omit for passwordless sudo; never persist this value.
});

if (result.ok && result.value.status === "saved") {
  // Mark this exact submitted editor version as saved. Later edits stay dirty.
} else {
  // Keep the Monaco model dirty. Translate result.error.code/status.
  // result.error.recoveryId/recoveryPath identify retained working material.
}

await chjPlugin.files.closeText(opened.editId);
const recovery = await chjPlugin.files.listRecovery(sessionId);
const copy = await chjPlugin.files.readRecovery(sessionId, recoveryId);
// Review copy.status and copy.text; open a fresh document before another save.
await chjPlugin.files.cleanupRecovery(sessionId, recoveryId);
// Cleanup rejects anything whose target is not currently confirmed.

Os métodos de recuperação aceitam um argumento final { sudo: true, sudoPassword } opcional quando inspecionar um alvo requer elevação. Eles mantêm o espaço de trabalho do usuário autenticado mesmo quando executado através do sudo. Os diários sobrevivem à reinicialização do aplicativo e ao SSH se reconectar; a recuperação nunca repete automaticamente a finalização. Revise um buffer recuperado contra um alvo recém-aberto antes de salvá-lo explicitamente.

files.read guarda leituras, inspeção e liberação de alça. files.write guarda a limpeza e a recuperação. writeText ainda rejeita a falha para plugins existentes; saveText retorna um envelope { ok, value/error } estruturado porque Electron deixa cair propriedades personalizadas em objetos de erro rejeitados. Um writeText legado de três argumentos pode usar a linha de base de um único documento aberto. Vários documentos vivos para o mesmo caminho exigem editId; chamadas legadas ambíguas falham com segurança em vez de escolher a linha de base de outro documento. Plugins devem liberar alças não utilizadas.

A interface do usuário externa deve exibir o salvamento imediatamente, manter os buffers sujos na falha, oferecer sudo somente após falhas de permissão/autenticação, mostrar conflitos sem sobrescrever e oferecer recuperação após perda de conexão ou um resultado desconhecido. Ele deve traduzir esses estados em checo, alemão e inglês. Sugestão de cópia do estado:

State Czech German English
Saving Ukládání… Wird gespeichert… Saving…
Confirmed Uloženo Gespeichert Saved
Failure Uložení selhalo Speichern fehlgeschlagen Save failed
Sudo required Vyžadováno oprávnění sudo sudo-Autorisierung erforderlich Sudo authorization required
Conflict Původní soubor byl změněn Originaldatei wurde geändert Original file changed
Disconnected Spojení bylo přerušeno Verbindung unterbrochen Connection lost
Unknown Výsledek uložení není znám Speicherergebnis unbekannt Save result unknown
Recovery Obnova je dostupná Wiederherstellung verfügbar Recovery available

Definições de latência e ciclo de vida

Ping é a latência relatada por um cliente real ICMP resposta eco ao IP resolvido usado por SSH. O Core invoca o executável ping da plataforma de forma assíncrona com um array de argumento fixo, sem uma necessidade de inicialização de shell ou administrador. Os argumentos Linux, macOS (incluindo ping6) e Windows são selecionados separadamente. Bloqueado ICMP, um executável ausente, um timeout, saída inválida ou uma resposta Windows somente superior como <1ms produzem um valor indisponível, não um número inventado.

SSH RTT é o monotônico performance.now() Duração de um fixo true requisição exec sobre o autenticado existente SSH cliente. Ele inclui configuração de canal, processamento de servidor e entrega de resposta; não é pura rede RTT ou duração de login SSH. A dica de ferramenta do indicador traduzido explica essa distinção.

O monitoramento começa assim que o terminal se conecta. Sondas são executadas de forma simultânea e assíncrona, com um tempo limite de solicitação/processo de cinco segundos. A próxima amostra é programada doze segundos após a amostra anterior ser concluída, evitando sobreposição. Desconecte os abortamentos ICMP, limpa os temporizadores, cancela o trabalho SSH pendente e limpa os valores. As verificações de identidade de registro impedem que uma conexão anterior seja publicada após a reconexão. A falha do ICMP nunca altera o estado da conexão SSH.

A latência viaja dentro do evento state existente / carga IPC ssh:state:

latency: { pingMs: 24.1, sshRttMs: 31.25, measuredAt: "…" }

Os números indisponíveis são null. O indicador de terminal compacto usa milissegundos, texto indisponível localizado e etiquetas Czech/German/English. Esconde-se na desconexão. Não foi necessária nenhuma capacidade adicional de execução do renderizador ou solicitação IPC.

Validação e limites operacionais

O usuário solicitou manter as alterações na árvore de trabalho existente, atualmente feature/hash-checksum-plugin; nenhum interruptor de ramificação ou limpeza não relacionada foi realizada.

Arquivos alterados para esta tarefa