Fabric: "الأدوار" المتوافقة مع الإصدار 2 أو ما شابه ذلك

تم إنشاؤها على ٢٢ أبريل ٢٠١٧  ·  7تعليقات  ·  مصدر: fabric/fabric

ملخص

في وقت كتابة هذا التقرير ، يحتوي فرع v2 على فئة Group والتي يجب أن تكون قادرة على العمل كوحدات كانت تُعرف سابقًا باسم "الأدوار" ، ويعرف أيضًا باسم "مجموعة من المضيفين للقيام بالأشياء باستخدام / تشغيل".

ومع ذلك ، لا توجد طريقة محددة لتنظيم أو تسمية كائنات Group حتى الآن ؛ لقد "تم" بشكل كافٍ لحالة استخدام واجهة برمجة التطبيقات (API) الخالصة للمستخدمين المتقدمين الذين يرغبون في طرح طريقتهم الخاصة في إنشائها ، ولكنها تفتقر إلى أي شيء للمستخدمين الموجهين لـ CLI أو الأشخاص المتوسطين الذين يريدون إنشاء إطار عمل حوله.

بعبارة أخرى ، ما لم تكن تتعامل تمامًا مع واجهة برمجة التطبيقات ، فإن وجود كائنات المجموعة في مكان ما يكون عديم الفائدة إذا لم يكن لدى CLI أو وحدات استدعاء المهام أي طريقة للعثور عليها!

خلفية

في الإصدار 1 ، كانت الأدوار عبارة عن مساحة اسم مسطحة واحدة تقوم بتعيين تسميات سلسلة بسيطة لما يمكن أن تكون مجموعات في الإصدار 2 ، ويمكن تحديدها على CLI في وقت التشغيل ( fab --roles=web,db ) و / أو تسجيلها كأهداف افتراضية للمهام ( @task('db') \n def migrate(): ) ، مثل المضيفين.

قام المستخدمون بتعريفهم بـ env.roledefs ، أمر بسيط ؛ تدور أي وظائف وسيطة إلى متقدمة حول تعديلها ، عادةً في وقت التشغيل (عبر المهمة السابقة أو الروتين الفرعي) ، أحيانًا في وقت تحميل الوحدة.

حالات استخدام محددة / احتياجات / ميزات فرعية

  • رسم خرائط أساسي ساذج للاستخدام / المرجع في أي مكان آخر في النظام: ضع اسمًا ، واسترجع بعض العناصر المكررة مثل Group s و / أو Connection s.

    • غالبًا ما يريد الاسم المستعار أن يتماشى مع ذلك ، على سبيل المثال Lexicon بدلاً من dict .

    • حتى التركيبات الأكثر عمقًا ، مثل "التجميع" ، على سبيل المثال ، لديك تعيينات مباشرة باسم db ، web ، lb ، ولكن بعد ذلك اسم من الدرجة الثانية يسمى prod التي هي دائما اتحاد الثلاثة الأخرى. نسيت إذا أضفت ذلك إلى Lexicon حتى الآن. من المحتمل وجود فئات فرعية أخرى للخرائط تقوم بذلك بالفعل.

    • بالإضافة إلى ذلك / بالتناوب ، أشياء مثل globbing أو غيرها من بناء الجملة ، على الرغم من أنني شخصياً أفضل الاستفادة من حقيقة أن Python ليست "مكتوبة بشكل خيطي" ...

  • "تعيين عكسي" مفيد بحيث يمكنك تحديد المجموعات التي ينتمي إليها اتصال معين.

    • إشكالية: نظرًا لعدم وجود حالة مشتركة عالمية حاليًا ، فإن الإجابة الساذجة على هذا - باستخدام الهوية - تنهار لأنه يمكنك تقنيًا إنشاء كائنات اتصال متطابقة متعددة.

    • خاصة وأن المجموعة يمكن أن تنشئها ضمنيًا نيابة عنك إذا أعطيتها سلاسل مضيفة مختصرة ، على الرغم من أن هذا ليس سوى خيار ملائم.

    • ومع ذلك ، نظرًا لعدم وجود حالة عالمية ، لا يمكنني رؤية مشاكل واضحة في استخدام اختبار المساواة بدلاً من ذلك ، لذلك يجب أن يكون ذلك ممكنًا ، على سبيل المثال ، if cxn in group سيعمل حتى إذا كان cxn كائنًا مميزًا من العضو المتساوي داخل group .

    • الشيء الوحيد الذي يتبادر إلى الذهن هو إذا كانت هناك روابط قوية وذات حالة من اتصال بمجموعة (يجب أن تكون مجموعات ، بصيغة الجمع) ، بدلاً من العكس ، لكن لا يمكنني رؤية أسباب وجيهة لذلك المرتجل.

  • يرتبط ارتباطًا وثيقًا بالسابق: القدرة على فحص / عرض ما هو "الدور الجاري حاليًا" (شيء أراده الناس لفترة طويلة في الإصدار 1 والذي كان غير بديهي بسبب تصميمه)

    • المشكلة الرئيسية هي أن هذا سؤالان شبه مميزان: "ما هو الدور (الأدوار) الذي يمثل الجزء المضيف الحالي ، بشكل عام" (بشكل أساسي ، حالة الاستخدام السابقة للبحث العكسي) ولكن أيضًا "ما هو الدور (الأدوار) الذي كان طلب آلات التنفيذ على وجه التحديد للتغلب على ".

    • بعبارة أخرى ، نظرًا لأن المضيف "foo" ينتمي إلى الأدوار A و B و C: ضمن مهمة معينة يكون سياقها "foo" ، ولكن تم تشغيلها بسبب طلب "التنفيذ في الدور A" ، فإن المستخدم يبحث عن إجابة "A و B و C" (الأدوار "foo" بشكل عام) أو "A" فقط (الدور المنفذ حاليًا)؟

    • يبدو هذا حقًا مثل استدعائين متميزين لواجهة برمجة التطبيقات ، على الرغم من أن طلبات الميزة أتذكر أنني أخلط بين الاثنين.

  • تحديد الهدف على CLI ، عالميًا و / أو لكل مهمة

    • قد يكون امتداد نظام CLI الخاص بـ Invoke لحساب "العلامات التي تحصل عليها جميع المهام فوق ما تحدده" مفيدًا أو مطلوبًا لهذا الغرض. الذي يقع بقوة في منطقة pyinvoke / استدعاء # 205 ، في الواقع ، بحيث حصلت للتو على أولوية أعلى مما كانت عليه بالفعل (والتي كانت عالية جدًا).

  • كما سبق الافتراضات على مستوى المهمة

    • على الرغم من أن الإعدادات الافتراضية للهدف على مستوى المهمة تريد حقًا أن تكون أيًا من: اتصال ، أو اتصالات ، أو كائن مجموعة ، أو أهداف جماعية ، أو اسم يقوم بتقييم _ to_ objs (هذا الأخير هو الشيء الوحيد الذي يتعلق مباشرة بهذه البطاقة ، يمكن القول)

  • كما سبق الافتراضات على مستوى المجموعة (جديد في الإصدار 2!)

    • أي "يتم تشغيل جميع المهام في الوحدة الفرعية $ افتراضيًا مقابل الدور db "

    • نفس الصفقة مثل النقطة السابقة - يريد هذا الإعداد الافتراضي السماح بعدد من القيم المختلفة ، وليس مجرد مفتاح سلسلة.

  • أي شيء آخر جديد ومثير تم تمكينه من خلال نهج OO الذي يريد حقًا مواكبة ذلك؟ تذكر أن التركيز يجب أن يكون على اللبنات الأساسية وتمكين المستخدمين المتقدمين ، وليس على سبيل المثال إعادة ابتكار أنظمة مثل Chef أو Ansible.

أفكار / مخاوف التنفيذ

  • إذا استخدمنا نظام التكوين باعتباره ناقل التخزين الرئيسي ، فإن القيم "تريد" أن تكون عناصر أولية بحيث يمكن تخزينها في yaml و json وما إلى ذلك ، ولكن هذه علبة من الديدان تنتهي بـ "تخزين كل مجموعة / اتصال kwargs في حجم كبير" list-o -dfs "، إلخ.
  • إذا كنا نتوقع أن تكون التعريفات بشكل أساسي في Python ، فيمكننا ببساطة أن نقول "إنشاء كائنات المجموعة" ، ومن ثم لدينا خيار دمج تلك البيانات في نظام التكوين أو تركها مستقلة بطريقة ما.

    • أعتقد أنني أفضل الخيار الأخير لأن حشو كل شيء حرفيًا في إعدادات التكوين المتداخلة يبدو أنه سيؤدي إلى أخبار سيئة.

  • تضيف التركيبات الأعمق مثل الاسم المستعار والتجميع مشكلات معقدة وترتيبًا (على سبيل المثال ، تخيل إعدادًا بسيطًا للاسم المستعار حيث تكون قيمة key1 مجموعة ولكن قيمة key2 هي key1 ؛ الآن عليك الزحف إلى البنية مرتين لحلها أو التحقق من المفتاح 2)

    • على الرغم من أننا إذا اتبعنا نهج "do it in-python" في الغالب ، فإنه يصبح يشبه إلى حد كبير واجهة برمجة تطبيقات نظام التكوين ، حيث يمكنك البدء بهيكل تعريفي ولكن يتم تمكين أي شيء آخر بواسطة استدعاءات الطريقة بعد هذا الإعداد الأولي. لا أعتقد أن هذا مروع؟ تحرير: وأعتقد أن هذا هو بالضبط كيف يعمل Lexicon على أي حال.

  • بغض النظر عن التنسيق ، يتعين علينا معرفة كيف سيرغب المستخدمون المتقدمون في إنشائه سريعًا من مصادر خارجية أو ما شابه ذلك ؛ هذا بالإضافة إلى المشكلات المتعلقة بالتعريف وما شابه ، يعني أننا قد لا نريد هذا في بنية ساذجة "مخزنة" في مكان ما ، ولكن كواجهة برمجة تطبيقات على بعض الكائنات أو الكائنات التي يتم استدعاؤها لإنشائها.

    • أظن أننا قد نرغب في العمل "إلى أسفل" من اختيار الأدوار / المجموعات ، والوصول إلى أي مستوى أعلى من واجهة برمجة التطبيقات من أجل "تحويل ما قدمه المستخدم إلى وحدة قابلة للتنفيذ من الأهداف" ، لأن المستخدمين الأكثر تقدمًا سيرغبون بالضرورة في لديك سيطرة كاملة على تنفيذ استدعاء API هذا. ثم يمكننا كما هو الحال دائمًا توفير ما يبدو أنه حالة عامة مفيدة ولكن يتم تمييزها بوضوح على أنها "طريقة واحدة فقط للقيام بذلك".

    • لدى RedKrieg فكرة رائعة على طول هذه الأسطر حيث لدينا @group مثل @task ، والوظائف ليست وحدات عمل قابلة للتنفيذ ، ولكن بدلاً من ذلك تنتج كائنات المجموعة.

    • يعيد هذا النهج استخدام التسلسل الهرمي للمهام (المجموعة) ، وهو عملي (لماذا نعيد اختراع العجلة) وأنيق (لأنه في حالات العالم الحقيقي ، غالبًا ما ترتبط تعريفات الأدوار / المجموعة بشكل وثيق جدًا بالمهام التي تستخدمها!)



      • كما أنه يعمل بشكل جيد حتى إذا لم تقم مجموعاتك بتعيين مهامك ، لأنه يمكنك ببساطة كتابة التعريفات على مستوى مجموعة الجذر الخاصة بك. سهل جدا.



    • ليس من الواضح بالنسبة لي ما إذا كان هذا هو الأفضل لإرجاع مجموعة واحدة من كل وظيفة ، أو إذا كنا نريد القدرة على إنتاج مجموعات متعددة (أو اتصالات) ، أو ما إذا كان من الأفضل القيام بذلك ليس كوظائف مزخرفة على الإطلاق ولكن مجرد مكالمات API المجموعة (مثل كيفية تخزين التكوينات على مستوى المجموعة).

    • على سبيل المثال ، حالة الاستخدام حيث تكون بيانات المجموعة / الدور ديناميكية وخارج Fabric لا تزال بحاجة إلى حل هنا (وهذا هو السبب في أنني أشرت سابقًا إلى أنه يجب علينا أولاً تحديد واجهة برمجة التطبيقات ذات المستوى الأعلى لهذه المساحة ؛ ثم نحتاج إلى معرفة كيف تتشابك هذه الشبكات مع فكرة المستوى المتوسط.)

Feature

التعليق الأكثر فائدة

مرحبًا ، لا أعرف ما حدث لهذا البرنامج بعد سنوات عديدة ، لكنني حقًا فاتني مفهوم "الأدوار" في [email protected] ، خاصة عند تشغيل $ fab -R dev

ال 7 كومينتر

من القائمة البريدية:

لقد قمنا بتثبيط واجهة برمجة تطبيقات REST الداخلية الخاصة بنا والتي تملأ env.roledefs بشكل ديناميكي اعتمادًا على المشروع الجاري نشره وتعتمد بشكل كبير على عدم تضمين سلاسل المضيف في ملف fabfile الخاص بالمشروع أو تحديدها في CLI.

حالات الاستخدام لدينا هي:

  1. قاعدة بيانات خالية من البيئة https://12factor.net/config. يتم تخزين البيئات (الأدوار) وسلاسل المضيف الخاصة بها في قاعدة بيانات مركزية. يحتوي كل ملف fabfile.py على شيء من هذا القبيل (يملأ env.roledefs عند استيراد الملف):
EnvironmentDatabaseAPIClient(
    'https://rest.api.url/schema/',
    env.service_name,
).apply_env()
  1. عدد بيئات الخادم - بيئات اختبار متعددة (بعضها خاص وبعضها عام) وبيئات إنتاج متعددة (لعملاء مختلفين). تتكون كل بيئة من مضيف واحد أو أكثر ويتم تعيينها لدور النسيج.

  2. كل خدمة ( env.service_name في المثال أعلاه) لها مجموعة مختلفة من البيئات.

  3. أيضًا لدينا أدوار وصفية (مجموعات من الأدوار). وهي مسبوقة بـ group- : group-production ، group-test ، group-external ، group-internal ، group-all . يتيح لنا ذلك النشر إلى أدوار خادم متعددة دون تحديدها واحدًا تلو الآخر ، على سبيل المثال ، يتم نشر group-all لجميع الأدوار ، كل من الإنتاج والاختبار.

  4. لدينا مهام نسيج خاصة لطباعة معلومات حول مجموعات الأدوار والأدوار والمضيفين.

  5. نعتمد أيضًا بشكل كبير على سلاسل مضيف التعيين العكسي إلى أسماء الأدوار (سلاسل المضيف فريدة لكل اسم_خدمة). يستخدم هذا لنشر التسجيل والإخطارات. بشكل أساسي ، نسجل عمليات نشر الخدمة لكل مضيف ونرسل إشعار Slack عندما يتم نشر الخدمة لجميع المضيفين في دور ما. خادم EnvironmentDatabaseAPI هو المسؤول عن هذا (يحتفظ بالسجلات وحالة النشر). يتم ذلك عن طريق تزيين مهام النسيج بمصمم يقوم بإرسال env.host و env.port و env.service_name (بالإضافة إلى معلومات الالتزام) إلى خادم API.

  6. نحن نخطط لإضافة مصادقة النشر في المستقبل ، ومن المحتمل أيضًا أن نسحب المزيد من المتغيرات env من الخادم لجعلها متاحة في سياق المهمة.

شكرا @ max-arnold! أتعرف على العديد من هؤلاء من حالات الاستخدام الخاصة بي في الماضي أيضًا. بتة التعيين العكسي على وجه الخصوص أتذكر ظهورها في v1 عدة مرات ، لذلك أضفتها إلى القائمة.

لكي يصبح Fabric v2 مفيدًا بالنسبة لي ، سأحتاج إلى طريقة لإخبار fab أي مجموعة من المضيفين لتنفيذ مهمة على.

في السابق قمت بتعريف الأدوار ثم قمت بتشغيل fab -R ... . (في الواقع ، تم تحديد الأدوار برمجيًا باستخدام نطاق عناوين IP ، ولكن هذا ليس مطلبًا وستكون القائمة الثابتة داخل ملف YAML أمرًا جيدًا.)

فشلت في العثور على مكافئ في Fabric v2 ، وفشلت أيضًا في محاكاة هذه الميزة باستخدام:

  • يحتوي ملف تكوين fabric.yaml على
active_hostset: null
hostsets:
  myhostset:
  - ...
  • active_hostset = config["hostsets"][config["active_hostset"]] fabfile.py
  • env INVOKE_ACTIVE_HOSTSET=myhostset fab ...

بدلاً من قائمة المضيفين المتوقعة ، أحصل على KeyError: 'active_hostset' .

نقوم بتعيين مجموعات مختلفة من المضيفين لكل دور لكل من بيئاتنا في fabric v1 ، ويتم تعيين البيئة عن طريق تشغيل مهمة role.environment:staging لتحديدها. لذلك تؤثر هذه المهمة على المضيفين الذين تستخدمهم المهام التالية.

في الإصدار 2 ، حاولنا استخدام مهمة مخصصة ، ولكن المشكلة هي أن Executor.expand_calls يتم تشغيله قبل تشغيل مهمة role.environment وبالتالي لا تعرف أي من المهام التالية البيئة من أجل إنشاء قوائم مضيفيهم ديناميكيًا.

إن جعل مولد Executor.expand_calls يسمح بتنفيذ المهام للتأثير على تنفيذ المهام اللاحقة. لذا فإن المثال أعلاه يعمل ، حيث لدينا Task مخصص يحتاج إلى معرفة البيئة لتوسيع الأدوار بشكل صحيح إلى المضيفين. على سبيل المثال ، fab role.environment dev deploy.app - يتم الآن تشغيل المهمة role.environment قبل توسيع deploy.app ، وبالتالي يعرف deploy.app البيئة ويمكن تكوين مضيفيها ثم يتم توسيعها إلى مجموعة المهام الصحيحة.

لقد قمت بنمذجة هذا في شوكاتي:
https://github.com/pyinvoke/invoke/compare/master...rectalogic : توسيع مولد
https://github.com/fabric/fabric/compare/master...rectalogic : توسيع المولد

مرحبًا ، لا أعرف ما حدث لهذا البرنامج بعد سنوات عديدة ، لكنني حقًا فاتني مفهوم "الأدوار" في [email protected] ، خاصة عند تشغيل $ fab -R dev

نستخدم الأدوار أيضًا لتمثيل نفس مجموعة العمليات عبر بيئات مختلفة. ربما يكون فصل مفهوم الدور المحدد عن البيئة المسماة مفيدًا؟ كما هو الحال في ، دور الويب في بيئة التطوير.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات