मुझे एक मध्यम आकार की परियोजना मिली है जो अब "क्लाइंट डेमो के लिए मैला कैफीन-संचालित प्रोटोटाइप" चरण के अंत के करीब है और "भविष्य के बारे में सोचो" चरण में संक्रमण कर रही है। परियोजना में सॉफ्टवेयर और फर्मवेयर के साथ लिनक्स आधारित डिवाइस और एक केंद्रीय प्रशासनिक वेब सर्वर शामिल हैं। वर्तमान में 10 प्रोटोटाइप मौजूद हैं, उत्पादन कम 1000 के क्रम पर होने की उम्मीद है।
ऑटो-अपडेट की कला में अच्छी तरह से पारंगत नहीं होने और समय पर कम होने के कारण, मैंने जल्दी से अपनी स्वयं की सॉफ़्टवेयर परिनियोजन / ऑटो-अपडेट रणनीति को रोल किया था और, स्पष्ट रूप से, यह बेकार है। वर्तमान में इसमें निम्नलिखित शामिल हैं:
- एक प्रॉडक्शन रिलीज़ ब्रांच के साथ एक होस्ट गिट रेपो (GitLab) (वेब सर्वर स्रोत भी इसी रेपो में है, साथ ही साथ कुछ अन्य चीजें भी नोट करें)।
- वेब इंटरफ़ेस पर "परिनियोजित अद्यतन" बटन:
- उत्पादन रिलीज शाखा से नवीनतम संस्करण को एक स्थानीय रेपो क्षेत्र में खींचता है और इसे एक अस्थायी पैकेज प्रीप स्टेजिंग क्षेत्र में भी कॉपी करता है।
- असंबंधित स्रोत फ़ाइलों (जैसे सर्वर स्रोत, फ़र्मवेयर स्रोत, आदि) और .गित फ़ाइलों को निकालने के लिए स्टेजिंग क्षेत्र में एक सैनिटाइज़ेशन स्क्रिप्ट (रेपो में संग्रहीत) चलाता है।
- अद्यतन पैकेज में एक फ़ाइल के लिए वर्तमान git हैश लिखता है (उद्देश्य नीचे स्पष्ट हो जाएगा)।
- यदि सब ठीक हो गया, तो यह इसे gzips करता है और पिछले gzipped पैकेज को उसी नाम की फ़ाइल के साथ अधिलेखित करके सेवा के लिए तैयार करता है, फिर स्टेजिंग क्षेत्र को हटा देता है।
- ध्यान दें कि सर्वर पर वर्तमान डिवाइस सॉफ़्टवेयर की अब दो प्रतियां हैं, जो सिंक में होने की उम्मीद है: नवीनतम उत्पादन शाखा पर एक पूर्ण स्थानीय गिट रेपो और एक तैयार-टू-गो गज़पेड पैकेज जिसे अब प्रतिनिधित्व करने के लिए ग्रहण किया गया है एक ही संस्करण।
- डिवाइस पर सॉफ्टवेयर नाम की एक निर्देशिका में स्व-निहित है
/opt/example/current
, जो सॉफ्टवेयर के वर्तमान संस्करण के लिए एक सिमलिंक है। - डिवाइस पर एक ऑटो-अपडेट फ़ंक्शन जो बूट पर है:
- किसी
do_not_update
फ़ाइल की उपस्थिति के लिए जाँच करता है और आगे कोई कार्यवाही नहीं करता है यदि यह मौजूद है (देव उपकरणों के लिए, नीचे देखें)। - उपर्युक्त पाठ फ़ाइल से वर्तमान प्रतिबद्ध हैश पढ़ता है।
- उस HTTP के साथ HTTP के लिए क्वेरी पैरामीटर के रूप में हैश बनाता है। सर्वर या तो 304 के साथ प्रतिक्रिया देगा (हैश वर्तमान संस्करण है) या gzipped अद्यतन पैकेज की सेवा करेगा।
- अद्यतन पैकेज स्थापित करता है, यदि एक प्राप्त किया
/opt/example
गया था:- अद्यतन किए गए सॉफ़्टवेयर जानकारी को नाम दिया गया फ़ोल्डर निकाल रहा है
stage
। - अपडेट पैकेज से पोस्ट-इंस्टॉलेशन स्क्रिप्ट चलाना, जो उस अपडेट के लिए आवश्यक स्थानीय परिवर्तन आदि जैसी चीजें करता है।
- वर्तमान सॉफ़्टवेयर रूट फ़ोल्डर की प्रतिलिपि बनाना
previous
(previous
यदि पहले से मौजूद है, तो हटाता है)। stage
फ़ोल्डर को कॉपी करनाlatest
(latest
पहले मौजूदा हटा देता है , अगर वहाँ एक है)।current
को इंगित करने के लिए सिमलिंक सुनिश्चित करनाlatest
।- डिवाइस को रिबूट करना (फर्मवेयर अपडेट, यदि मौजूद है, तो रिबूट पर लागू किया जाता है)।
- अद्यतन किए गए सॉफ़्टवेयर जानकारी को नाम दिया गया फ़ोल्डर निकाल रहा है
- किसी
नवनिर्मित उपकरणों पर प्रारंभिक तैनाती का मुद्दा भी है। उपकरण वर्तमान में SD कार्ड आधारित हैं (समस्याओं का अपना सेट है, यहाँ से बाहर है) इसलिए इस प्रक्रिया में निम्न शामिल हैं:
- एक एसडी छवि मौजूद है जो उस पर सॉफ़्टवेयर के कुछ स्थिर पूर्व संस्करण है।
- इस चित्र से एक SD कार्ड बनाया जाता है।
- पहले बूट पर, विभिन्न फर्स्ट-टाइम डिवाइस-स्पेसिफिक (सीरियल नंबर आधारित) इनिशियलाइज़ेशन होता है और फिर ऑटो-अपडूलेटर पकड़ लेता है और हमेशा की तरह सॉफ्टवेयर का नवीनतम उत्पादन संस्करण स्थापित करता है।
इसके अतिरिक्त, मुझे विकास उपकरणों के लिए समर्थन की आवश्यकता है। विकास उपकरणों के लिए:
- डिवाइस पर एक पूर्ण स्थानीय गिट रेपो बनाए रखा जाता है।
current
सिम्लिंक विकास निर्देशिका की ओर इशारा करता है।- एक स्थानीय
do_not_update
फ़ाइल मौजूद है जो ऑटो-अपडेटर को उत्पादन अपडेट के साथ विकास कोड को उड़ाने से रोकती है।
अब, तैनाती की प्रक्रिया सैद्धांतिक रूप से होने का इरादा था:
- एक बार कोड परिनियोजन के लिए तैयार हो जाने के बाद इसे रिलीज शाखा में धकेल दें।
- सर्वर पर "तैनाती अद्यतन" बटन दबाएं।
- अद्यतन अब लाइव है और डिवाइस अगली बार जांचने पर ऑटो-अपडेट करेंगे।
हालाँकि, व्यवहार में समस्याओं की एक टन हैं :
- वेब सर्वर कोड डिवाइस कोड के समान रेपो में है, और सर्वर में एक स्थानीय गिट रेपो है जिसे मैं बाहर निष्पादित करता हूं। नवीनतम वेब सर्वर कोड नवीनतम डिवाइस कोड के समान शाखा पर नहीं है। निर्देशिका संरचना समस्याग्रस्त है। जब "तैनाती अद्यतन" बटन उत्पादन शाखा से नवीनतम संस्करण को खींचता है, तो यह सर्वर कोड के एक उपनिर्देशिका में खींचता है। इसका मतलब यह है कि जब मैं एक सर्वर को स्क्रैच से परिनियोजित करता हूं, तो मुझे डिवाइस उपादान शाखा को उसमें ले जाकर इस उपनिर्देशिका को मैन्युअल रूप से "सीड" करना होगा, क्योंकि, यदि संभवत: मेरी ओर से गिट यूजर एरर से, अगर मैं तैनाती का प्रयास नहीं करता हूं पैरेंट डायरेक्टरी की वेब सर्वर ब्रांच से डिवाइस कोड खींचें । मुझे लगता है कि यह मंचन क्षेत्र को सर्वर के स्थानीय गिट रेपो का उपनिर्देशिका नहीं बनाकर हल करने योग्य है।
- वेब सर्वर वर्तमान में डिवाइस सॉफ़्टवेयर के git हैश को लगातार बनाए नहीं रखता है। सर्वर स्टार्टअप पर, यह
git rev-parse HEAD
वर्तमान हैश को पुनः प्राप्त करने के लिए अपने स्थानीय डिवाइस सॉफ्टवेयर रेपो में करता है । जिन कारणों से मैं अपना सिर नहीं लपेट पा रहा हूं, उनमें से एक टन तर्क त्रुटियों का भी कारण बन रहा है, जिसका मैं यहां वर्णन नहीं करूंगा, यह कहने के लिए पर्याप्त है कि कभी-कभी सर्वर शिकंजा चीजों को फिर से शुरू करता है, खासकर अगर सर्वर बिल्कुल नया है और कोई उत्पादन नहीं है शाखा रेपो को अभी तक खींच लिया गया है। अगर मैं अनुरोध करता हूं तो मैं उस तर्क के लिए स्रोत को खुशी से साझा करूंगा, लेकिन यह पोस्ट लंबी हो रही है। - यदि सैनिटाइजेशन स्क्रिप्ट (सर्वर साइड) किसी कारण से विफल हो जाती है, तो सर्वर एक अप-टू-डेट रेपो के साथ छोड़ दिया जाता है, लेकिन एक आउट-ऑफ-सिंक / लापता अपडेट पैकेज, इस प्रकार
git rev-parse HEAD
एक हैश वापस करेगा जो वास्तव में क्या हो रहा है से मेल नहीं खाता है उपकरणों के लिए सेवा की, और यहाँ समस्याओं को मैन्युअल रूप से सर्वर कमांड लाइन पर ठीक किया जाना चाहिए। यानी सर्वर को पता नहीं है कि अपडेट पैकेज सही नहीं है, यह केवल हमेशा शुद्ध विश्वास पर निर्भर करता है। यह पिछले बिंदुओं के साथ संयुक्त सर्वर व्यवहार में बेहद नाजुक बनाता है। - सबसे बड़ी समस्याओं में से एक है : वर्तमान में डिवाइस पर कोई अलग से अपडेटर डेमॉन नहीं चल रहा है। वाईफाई इंटरनेट के उपयोग की प्रतीक्षा कर रहे जटिलताओं और कुछ अंतिम मिनट हैकरी के कारण, यह मुख्य उपकरण नियंत्रण सॉफ्टवेयर है जो डिवाइस की जांच और अद्यतन करता है। इसका मतलब यह है कि अगर किसी तरह खराब परीक्षण किया गया संस्करण इसे उत्पादन में बनाता है, और नियंत्रण सॉफ्टवेयर शुरू नहीं हो सकता है, तो मौजूद सभी डिवाइस अनिवार्य रूप से ईंट कर दिए जाते हैं, क्योंकि यह अब खुद को अपडेट नहीं कर सकता है। यह उत्पादन में एक पूर्ण दुःस्वप्न होगा। एक उपकरण के लिए एक ही सौदा अगर यह एक अशुभ समय में बिजली खो देता है।
- अन्य प्रमुख समस्या है : वृद्धिशील अद्यतन के लिए कोई समर्थन नहीं है। यदि कोई उपकरण, कहता है, थोड़ी देर के लिए चालू नहीं होता है, तो अगली बार इसका अपडेट रिलीज संस्करणों के एक गुच्छा को छोड़ देता है, इसे एक सीधा संस्करण-स्किपिंग अपडेट करने में सक्षम होना पड़ता है। इसका परिणाम अद्यतन परिनियोजन है यह सुनिश्चित करने का एक बुरा सपना है कि किसी भी दिए गए अद्यतन को किसी भी दिए गए पिछले संस्करण के शीर्ष पर लागू किया जा सकता है। इसके अलावा, चूंकि जीआईटी हैश का उपयोग संस्करण संख्याओं के बजाय संस्करणों की पहचान करने के लिए किया जाता है, वृद्धिशील अपडेट की सुविधा के लिए संस्करणों की तुलनात्मक रूप से वर्तमान में संभव नहीं है।
- एक नई आवश्यकता जिसे मैं वर्तमान में समर्थन नहीं करता हूं, वह है कि कुछ प्रति-डिवाइस कॉन्फ़िगरेशन विकल्प (कुंजी / मान जोड़े) मौजूद होंगे जो कि प्रशासनिक सर्वर साइड पर कॉन्फ़िगर किए जाने चाहिए। मैं किसी भी तरह से इन प्रति-डिवाइस विकल्पों को डिवाइस पर वापस उसी HTTP अनुरोध में सेवा करने का मन नहीं करूंगा क्योंकि सॉफ़्टवेयर अपडेट (शायद मैं इसे HTTP हेडर / कुकीज़ में एन्क्रिप्ट कर सकता हूं) हालांकि मैं इस बारे में बहुत चिंतित नहीं हूं, जैसा कि मैं कर सकता हूं हमेशा इसे एक अलग HTTP अनुरोध करें।
- इस तथ्य के कारण थोड़ी जटिलता है कि हार्डवेयर के दो (और भविष्य में) संस्करण मौजूद हैं। हार्डवेयर का वर्तमान संस्करण वास्तव में इसकी प्रारंभिक एसडी छवि (वे स्वयं की पहचान नहीं कर सकते) पर एक पर्यावरण चर के रूप में संग्रहीत किया गया है और सभी सॉफ़्टवेयर को सभी संस्करणों के उपकरणों के साथ संगत करने के लिए डिज़ाइन किया गया है। फर्मवेयर अपडेट को इस पर्यावरण चर के आधार पर चुना जाता है और अपडेट पैकेज में हार्डवेयर के सभी संस्करणों के लिए फर्मवेयर होता है। मैं इसके साथ रह सकता हूं, हालांकि यह थोड़ा सांवला है।
- वर्तमान में डिवाइस पर मैन्युअल रूप से अपडेट अपलोड करने का कोई तरीका मौजूद नहीं है (लंबी कहानी छोटी इन डिवाइसों में दो वाईफाई एडेप्टर हैं, एक इंटरनेट से कनेक्ट करने के लिए, और एक एपी मोड में जो उपयोगकर्ता डिवाइस को कॉन्फ़िगर करने के लिए उपयोग करता है; भविष्य में; मैं डिवाइस के स्थानीय वेब इंटरफ़ेस में "अपडेट सॉफ़्टवेयर" फ़ंक्शन जोड़ने का इरादा रखता हूं)। यह बहुत बड़ी बात नहीं है, लेकिन अपडेट इंस्टॉलेशन पद्धति पर कुछ प्रभाव पड़ता है।
- अन्य कुंठाओं और सामान्य अनिश्चितता का एक समूह।
तो ... वह लंबा था। लेकिन मेरा सवाल इससे उबल रहा है:
मैं इसे ठीक से और सुरक्षित रूप से कैसे करूं? क्या मेरी मौजूदा प्रक्रिया में छोटे समायोजन हो सकते हैं? क्या कोई समय-परीक्षण की गई रणनीति / मौजूदा प्रणाली है जिसका मैं लाभ उठा सकता हूं ताकि मुझे अपने स्वयं के भद्दे अपडेट सिस्टम को रोल न करना पड़े ? या अगर मुझे अपना रोल करना है, तो क्या चीजें हैं जो एक तैनाती / अद्यतन प्रक्रिया के लिए सुरक्षित और सफल होने के लिए सही होनी चाहिए? मुझे मिक्स में विकास उपकरणों को शामिल करने में भी सक्षम होना चाहिए।
मुझे उम्मीद है कि सवाल स्पष्ट है। मुझे लगता है कि यह थोड़ा फजी है, लेकिन मुझे यकीन है कि यह 100% समस्या है जो पहले से निपटने और सफलतापूर्वक हल हो गई है, मुझे अभी यह नहीं पता है कि वर्तमान में स्वीकृत रणनीतियों क्या हैं।