CH-J ToolsSSH के ज़रिए सर्वर प्रबंधन
मेनू

रिमोट एडिटर में सहेजना और लेटेंसी मॉनिटरिंग

फ़ाइल डाउनलोड करें

इस अनुवाद की भाषाई समीक्षा जारी है। कोई अंश अस्पष्ट हो, तो अंग्रेज़ी मूल पाठ से मिलाएँ।

मूल कारण

पिछला एडिटर अपनी कार्य-फ़ाइल को लक्ष्य की पैरेंट डायरेक्टरी में अपलोड करता था, जिसमें /etc या /var के अंदर SSH खाता अक्सर लिख नहीं सकता। SFTP rename में न तो अधिकृत sudo पथ था, न बेसलाइन टकराव जाँच, न सुरक्षा मेटाडेटा सत्यापन और न ही भरोसेमंद ओवरराइट व्यवहार। इसका त्रुटि हैंडलर अस्थायी प्रति हटा देता था, जिससे कार्य पूरा होना अनिश्चित होने पर भी रिकवरी सामग्री मिट जाती थी।

सेशन स्थिति पहले केवल कनेक्शन की स्थिति दिखाती थी। टर्मिनल संकेतक को डेटा देने वाला कोई ICMP या प्रमाणित SSH प्रतिक्रिया माप नहीं था।

सहेजने का प्रोटोकॉल

  1. एक तय SSH हेल्पर डिस्क्रिप्टर-आधारित सापेक्ष कार्यों और हर पथ घटक के लिए O_NOFOLLOW का उपयोग करके एक सामान्य, एकल-लिंक वाली फ़ाइल खोलता है। वह सामग्री, SHA-256 हैश, डिवाइस/inode, UID, GID, सभी अनुमति बिट, नैनोसेकंड स्तर के संशोधन/परिवर्तन समय और सभी पढ़ने योग्य विस्तारित एट्रिब्यूट दर्ज करता है। Core हैश सत्यापित करता है और BOM बनाए रखते हुए सख़्त UTF-8 डिकोड करता है। हर दस्तावेज़ को एक अपारदर्शी editId मिलती है, जो उसके प्लगइन, टर्मिनल सेशन और सर्वर पहचान तक सीमित होती है।
  2. एक बिना विशेषाधिकार वाला तैयारी चरण pwd.getpwuid(os.getuid()) से प्रमाणित खाते की होम डायरेक्टरी पता करता है, 0700 मोड में $HOME/ch-j-sm/ बनाता है और एक निजी, अनन्य रिकवरी जर्नल बनाता है। असुरक्षित होम, सिमलिंक वर्कस्पेस या किसी दूसरे खाते के स्वामित्व वाला वर्कस्पेस अस्वीकार कर दिया जाता है।
  3. Core अनन्य निर्माण (wx), मोड 0600 और साठ सेकंड के चैनल/अपलोड टाइमआउट के साथ SFTP से एक छिपी, यादृच्छिक 128-बिट नाम वाली .tmp कार्य-फ़ाइल अपलोड करता है। जर्नल में लक्ष्य, मूल बेसलाइन और अपेक्षित कार्य-फ़ाइल हैश होता है; इसमें कोई क्रेडेंशियल नहीं होता।
  4. एक ही SSH exec पूरा अंतिम चरण पूरा करता है, वैकल्पिक रूप से मौजूदा sudo एक्ज़िक्यूटर के ज़रिए। हेल्पर निजी कार्य-प्रति को सुरक्षित रूप से खोलकर उसका हैश निकालता है और उसे डिस्क पर फ़्लश करता है। वह मूल inode को लॉक करता है, उसकी बेसलाइन जाँचता है, लक्ष्य के बगल में एक अनन्य गंतव्य फ़ाइल बनाता है, पूरी सामग्री लिखता है, मेटाडेटा लागू और सत्यापित करता है, मूल फ़ाइल को फिर से जाँचता है और बदली जाने वाली फ़ाइल को फ़्लश करता है।
  5. उसी डायरेक्टरी में os.replace लक्ष्य को परमाणु रूप से बदल देता है। पैरेंट डायरेक्टरी फ़्लश की जाती है और अंतिम पथ, हैश, inode तथा मेटाडेटा सत्यापित किए जाते हैं। बदलाव होने तक मूल पथ उपलब्ध रहता है। कार्य-फ़ाइल कभी भी फ़ाइल सिस्टम के पार नहीं ले जाई जाती और अंतिम चरण में कभी हटाई नहीं जाती।
  6. Core को सत्यापित सफलता मिलने के बाद, एक अलग सफ़ाई चरण कार्य-फ़ाइल और जर्नल हटाने से पहले अंतिम सामग्री और सुरक्षा मेटाडेटा को फिर से जाँचता है। सफ़ाई विफल होने पर भी recoveryAvailable: true के साथ पुष्ट सहेजने की रिपोर्ट दी जाती है।

अपलोड विफल होने, sudo विफल होने, टकराव, मेटाडेटा त्रुटि या बदलाव विफल होने पर मूल फ़ाइल और सारी तैयार सामग्री सुरक्षित रहती है। अधूरे अपलोड को अधूरा ही चिह्नित किया जाता है और उन्हें पूरे संपादित दस्तावेज़ के रूप में बहाल नहीं किया जा सकता। SSH संचार टूटने, एग्ज़िट स्थिति न मिलने, टाइमआउट और अप्रत्याशित अंतिम परिणाम को अज्ञात बताया जाता है, कभी "सहेजा गया" नहीं। अनिश्चित दस्तावेज़ पर Core अगला सहेजना रोक देता है; बदलाव का कोई स्वचालित पुनःप्रयास नहीं होता।

मेटाडेटा, विशेषाधिकार और सुरक्षा सीमाएँ

हेल्पर UID, GID और सभी POSIX अनुमति बिट सुरक्षित रखता और सत्यापित करता है, जिनमें executable, setuid, setgid और sticky बिट शामिल हैं। वह Linux विस्तारित एट्रिब्यूट को बाइट-दर-बाइट दोबारा बनाता है, जिनमें POSIX ACL, capabilities और SELinux लेबल शामिल हैं। स्वामित्व और फ़ाइल सामग्री सुरक्षा एट्रिब्यूट से पहले सेट की जाती है, क्योंकि लिखने/chown से capabilities या विशेष अनुमति बिट साफ़ हो सकते हैं। गंतव्य पर विरासत में मिले ऐसे एट्रिब्यूट जो मूल में नहीं हैं, हटा दिए जाते हैं। संशोधन समय नए लेखन को दर्शाता है और मूल से कॉपी नहीं किया जाता।

न पढ़ा जा सकने या न दर्शाया जा सकने वाला एट्रिब्यूट कार्य को रोक देता है; मेटाडेटा चुपचाप नहीं छोड़ा जाता। IMA/EVM हस्ताक्षर स्पष्ट रूप से अस्वीकार किए जाते हैं, क्योंकि सामग्री/inode से बंधे अखंडता हस्ताक्षर कॉपी करने से वे अमान्य हो जाएँगे। लक्ष्य या होम पथ में सिमलिंक, हार्ड-लिंक वाली फ़ाइलें और असामान्य फ़ाइलें अस्वीकार की जाती हैं। कोई इन-प्लेस या कमज़ोर SFTP ओवरराइट विकल्प उपयोग नहीं होता।

सामान्य लिखने योग्य सहेजना SSH खाते के रूप में चलता है। सुरक्षित सहेजने के लिए स्पष्ट { sudo: true } ज़रूरी है; बिना पासवर्ड वाले sudo के लिए sudo पासवर्ड वैकल्पिक है। पासवर्ड सत्यापित करके केवल चैनल stdin पर भेजे जाते हैं, कभी कमांड, जर्नल, कार्य-फ़ाइल, लॉगर या रिमोट त्रुटि में नहीं। root SSH सेशन मौजूदा सीधे root एक्ज़िक्यूटर का उपयोग करते हैं। प्राधिकरण विफल होने पर मूल और कार्य-प्रति दोनों अप्रभावित रहती हैं। root के रूप में चलने वाले सभी सहेजने (सीधा root SSH या sudo) उन लक्ष्य डायरेक्टरी/पूर्वज डायरेक्टरी को भी अस्वीकार करते हैं जो दूसरे खातों के स्वामित्व में हों, उनके द्वारा लिखी जा सकती हों या जिन पर access ACL हो, बजाय किसी दूसरे खाते द्वारा नियंत्रित विशेषाधिकार वाले पथ नाम पर भरोसा करने के।

तय हेल्पर python3 -I -B के साथ चलता है: यह उपयोगकर्ता के Python पथ, कार्य डायरेक्टरी और उपयोगकर्ता site-packages को अनदेखा करता है और कोई बाइटकोड नहीं लिखता। पथ और JSON आर्ग्युमेंट Core में शेल-कोट किए जाते हैं। प्लगइन को कभी भी मनमाना SSH exec या SFTP हैंडल नहीं मिलता। मौजूदा सैंडबॉक्स, CSP, मैनिफ़ेस्ट अनुमतियाँ, होस्ट-कुंजी सत्यापन और अपडेट सत्यापन लागू रहते हैं।

Plugin API और बचा हुआ Monaco एकीकरण

अलग से वितरित Monaco/File Manager UI इस चेकआउट में मौजूद नहीं है। इसका UI एकीकरण, sudo संकेत, बिना सहेजे बफ़र का प्रबंधन और अनुवाद यहाँ लागू या परीक्षित नहीं किए जा सके। बंडल प्लगइन सोर्स Hash & Checksum प्लगइन है। कोई वैकल्पिक File Manager सोर्स गढ़ा नहीं गया।

मौजूदा मेथड उपलब्ध रहते हैं। अतिरिक्त मेथड/विकल्प सैंडबॉक्स वाले preload और अनुमति-जाँच वाले रनटाइम से उपलब्ध कराए जाते हैं:

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.

जब लक्ष्य की जाँच के लिए विशेषाधिकार बढ़ाना ज़रूरी हो, तो रिकवरी मेथड अंतिम वैकल्पिक आर्ग्युमेंट { sudo: true, sudoPassword } स्वीकार करते हैं। sudo के ज़रिए चलने पर भी वे प्रमाणित उपयोगकर्ता का वर्कस्पेस ही रखते हैं। जर्नल ऐप रीस्टार्ट और SSH पुनःकनेक्शन के बाद भी बने रहते हैं; रिकवरी कभी अपने-आप अंतिम चरण नहीं दोहराती। बहाल किए गए बफ़र को स्पष्ट रूप से सहेजने से पहले उसे नए सिरे से खोले गए लक्ष्य से मिलाकर देखें।

files.read पढ़ने, निरीक्षण और हैंडल छोड़ने की रक्षा करता है। files.write सहेजने और रिकवरी सफ़ाई की रक्षा करता है। मौजूदा प्लगइन के लिए writeText विफलता पर अब भी reject करता है; saveText एक संरचित { ok, value/error } लिफ़ाफ़ा लौटाता है, क्योंकि Electron reject किए गए Error ऑब्जेक्ट से कस्टम प्रॉपर्टी हटा देता है। पुराना तीन-आर्ग्युमेंट वाला writeText एक ही खुले दस्तावेज़ की बेसलाइन का उपयोग कर सकता है। एक ही पथ के कई सक्रिय दस्तावेज़ों के लिए editId ज़रूरी है; अस्पष्ट पुरानी कॉल किसी दूसरे दस्तावेज़ की बेसलाइन चुनने के बजाय सुरक्षित रूप से विफल होती हैं। प्लगइन को अनुपयोगी हैंडल छोड़ देने चाहिए।

बाहरी UI को सहेजना तुरंत दिखाना चाहिए, विफलता पर बफ़र को बिना सहेजा रखना चाहिए, केवल अनुमति/प्रमाणीकरण विफलता के बाद sudo सुझाना चाहिए, ओवरराइट किए बिना टकराव दिखाना चाहिए और कनेक्शन टूटने या अज्ञात परिणाम के बाद रिकवरी सुझानी चाहिए। इन स्थितियों का चेक, जर्मन और अंग्रेज़ी में अनुवाद ज़रूरी है। सुझाया गया स्थिति पाठ:

स्थिति चेक जर्मन अंग्रेज़ी
सहेजा जा रहा है Ukládání… Wird gespeichert… Saving…
पुष्ट Uloženo Gespeichert Saved
विफलता Uložení selhalo Speichern fehlgeschlagen Save failed
sudo ज़रूरी Vyžadováno oprávnění sudo sudo-Autorisierung erforderlich Sudo authorization required
टकराव Původní soubor byl změněn Originaldatei wurde geändert Original file changed
डिस्कनेक्ट Spojení bylo přerušeno Verbindung unterbrochen Connection lost
अज्ञात Výsledek uložení není znám Speicherergebnis unbekannt Save result unknown
रिकवरी Obnova je dostupná Wiederherstellung verfügbar Recovery available

लेटेंसी की परिभाषाएँ और जीवनचक्र

Ping वह लेटेंसी है जो SSH द्वारा उपयोग किए गए रिज़ॉल्व्ड IP को भेजे गए ICMP echo के क्लाइंट-साइड पर वास्तव में मिले जवाब से रिपोर्ट होती है। Core प्लेटफ़ॉर्म के ping एक्ज़िक्यूटेबल को एक तय आर्ग्युमेंट ऐरे के साथ असिंक्रोनस रूप से चलाता है, बिना शेल के और बिना व्यवस्थापक के रूप में शुरू करने की आवश्यकता के। Linux, macOS (ping6 सहित) और Windows के आर्ग्युमेंट अलग-अलग चुने जाते हैं। ब्लॉक किया गया ICMP, न मिला एक्ज़िक्यूटेबल, टाइमआउट, अमान्य आउटपुट या <1ms जैसा केवल ऊपरी सीमा वाला Windows जवाब, ये सब "उपलब्ध नहीं" मान देते हैं, कोई गढ़ी हुई संख्या नहीं।

SSH RTT मौजूदा प्रमाणित SSH क्लाइंट पर एक तय true exec अनुरोध की मोनोटोनिक performance.now() अवधि है। इसमें चैनल सेटअप, सर्वर प्रसंस्करण और जवाब की डिलीवरी शामिल है; यह न तो शुद्ध नेटवर्क RTT है और न ही SSH लॉगिन की अवधि। अनूदित संकेतक टूलटिप यह अंतर समझाता है।

टर्मिनल कनेक्ट होते ही मॉनिटरिंग शुरू हो जाती है। प्रोब एक साथ और असिंक्रोनस रूप से चलते हैं, पाँच सेकंड के अनुरोध/प्रोसेस टाइमआउट के साथ। ओवरलैप रोकने के लिए अगला नमूना पिछले नमूने के पूरा होने के बारह सेकंड बाद निर्धारित होता है। डिस्कनेक्ट ICMP को रोकता है, टाइमर साफ़ करता है, लंबित SSH कार्य रद्द करता है और मान साफ़ करता है। रिकॉर्ड पहचान जाँच पिछले कनेक्शन को पुनःकनेक्शन के बाद मान प्रकाशित करने से रोकती है। ICMP की विफलता SSH कनेक्शन की स्थिति कभी नहीं बदलती।

लेटेंसी मौजूदा state इवेंट / ssh:state IPC पेलोड के अंदर भेजी जाती है:

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

अनुपलब्ध संख्याएँ null होती हैं। कॉम्पैक्ट टर्मिनल संकेतक मिलीसेकंड, स्थानीयकृत "उपलब्ध नहीं" पाठ और चेक/जर्मन/अंग्रेज़ी लेबल का उपयोग करता है। डिस्कनेक्ट होने पर यह छिप जाता है। किसी अतिरिक्त रेंडरर निष्पादन क्षमता या IPC अनुरोध की ज़रूरत नहीं पड़ी।

सत्यापन और परिचालन सीमाएँ

उपयोगकर्ता ने मौजूदा वर्किंग ट्री (फ़िलहाल feature/hash-checksum-plugin) में बदलाव रखने का अनुरोध किया था; कोई ब्रांच नहीं बदली गई और कोई असंबंधित सफ़ाई नहीं की गई।

इस कार्य में बदली गई फ़ाइलें