Fabric: اختياريا تجنب استخدام ssh إذا كنت تذهب إلى localhost

تم إنشاؤها على ١٩ أغسطس ٢٠١١  ·  59تعليقات  ·  مصدر: fabric/fabric

وصف

سوف يرى run () / sudo () بذكاء أنك ذاهب إلى localhost وتشغيل local () بدلاً من ذلك. ربما يكون هذا أمرًا اختياريًا.

تعليقات من Jeff على IRC:

ونعم ، أعني أنه سيكون هناك دائمًا عبء مع أنابيب ssh مقابل الأنابيب المستقيمة المرتجعة ، ولا أعتقد أنه سيكون من الصعب للغاية تحديث run / sudo (خاصة في Master الآن بعد أن تم إعادة تشكيلها) للاتصال / العودة المحلية ( ) بذكاء لست متأكدًا من أنني أريد هذا السلوك شبه السحري في جوهره (حتى مع إيقافه افتراضيًا مع خيار تمكين لتمكينه ، مع ذلك من شأنه أن يساعد) ولكن مع ذلك ، ستكون تجربة مثيرة للاهتمام. وإذا كان الأمر بسيطًا كما أعتقد ، فأنا بصراحة لا أستطيع أن أتوصل إلى سبب وجيه لعدم القيام بذلك (مرة أخرى بشرط ألا يكون هذا هو السلوك الافتراضي)

تم تقديمه في الأصل بواسطة Nick Welch ( mackstann ) في 2009-11-11 الساعة 01:39 مساءً بتوقيت شرق الولايات المتحدة

علاقات

  • مكرر بواسطة # 364: السماح للعملية المحلية لتجاوز طبقة SSH
  • متعلق برقم 26: تنفيذ ميزة "التشغيل الجاف"
Feature Network

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

إذا تساءل أي شخص "لماذا يفعل أي شخص هذا؟" ، فإن الإجابة هي أنه إذا كان لديك خط أنابيب للنشر ، فقد يكون من المفيد تشغيل نفس البرنامج النصي للنشر بالضبط ، بغض النظر عن البيئة ، بدلاً من وجود برنامج نصي خاص للإعداد للمضيف المحلي مقابل كل شيء آخر.

ال 59 كومينتر

نشر جيمس بيرسون (xiong.chiamiov):


كما هو مذكور أيضًا في irc ، لا أقوم عادةً بتشغيل خادم ssh على جهاز سطح مكتب ، لذلك لا يمكنني في الواقع إرسال ssh إلى المضيف المحلي.


بتاريخ 2009-11-11 الساعة 03:13 مساءً بتوقيت شرق الولايات المتحدة

نشر Travis Swicegood ( tswicegood ):


لقد قمت للتو بتنفيذ شيء مشابه هذا المساء في شكل وظيفة عمليات قماشية جديدة تسمى do . يبحث في env.run_as لمعرفة ما إذا كان يساوي "local" ، وبذلك يتم التبديل إلى طريقة local بدلاً من run (أو sudo إذا تم تمرير sudo=True كـ kwarg). كما أنه يتعامل مع الأوامر المحلية السابقة بـ sudo في حالة تشغيلها محليًا.

هذه طريقة مختلفة لحل هذه المشكلة والتي تعمل دون تغيير سلوك run أو sudo . هذه التغييرات متاحة في مستودعي .


بتاريخ 2010-01-11 الساعة 12:22 صباحًا بتوقيت شرق الولايات المتحدة

نشر Morgan Goose ( goosemo ):


أنا حقًا لا أرى أن هذا معقول. ما الهدف من تشغيل الجري كمحلي. أحد متطلبات Fabric هو تشغيل sshd على الجهاز ، بعيدًا أو استرجاع. المشكلة الأخرى هي أن التغيير المحلي فقط لا يأخذ في الاعتبار put و get و rsync_project وغيرها من الأشياء التي قد لا تزال بحاجة إلى ssh. إن محاولة تنفيذ هذه الأمور ستؤدي حقًا إلى المزيد من المشكلات ، نظرًا لأنها الآن في مجال جعل الملفات الفابية تترجم إلى bash.


بتاريخ 2011-03-13 الساعة 11:14 مساءً بتوقيت شرق الولايات المتحدة

نشر جيف فورسير ( bitprophet ):


على الرغم من أنني لست مقتنعًا بنسبة 100٪ أن هذه فكرة رائعة ، فمن الواضح أنها شيء يشعر عدد من المستخدمين بالحاجة إليه - تم تقديم طلب آخر كـ # 364 مع شرح آخر لحالة الاستخدام.

لقد أضفت أيضًا تذكرة التشغيل الجاف فيما يتعلق بهذه البطاقة ، لأنه (أفترض - إذا كان بإمكان أي من المستخدمين المتقدمين التحقق من أن هذا سيكون رائعًا) ، فإن حالة الاستخدام الرئيسية لهذه الميزة هي للاختبار / التجفيف- ادارة.


بتاريخ 2011-06-23 الساعة 11:26 صباحًا بتوقيت شرق الولايات المتحدة

كما هو مذكور في # 538 ، إذا استطعنا في أي وقت تطبيع العدائين الثلاثة بشكل كامل حتى يمكن استخدامهم بالتبادل ، فسنحتاج إلى التأكد من أن هروب القذيفة يعمل باستمرار عبرهم. في الوقت الحالي ، نحن لا نتخلص من local ، على الرغم من أن هذا يرجع جزئيًا على الأقل إلى عدم استخدام غلاف غلاف.

إذا تساءل أي شخص "لماذا يفعل أي شخص هذا؟" ، فإن الإجابة هي أنه إذا كان لديك خط أنابيب للنشر ، فقد يكون من المفيد تشغيل نفس البرنامج النصي للنشر بالضبط ، بغض النظر عن البيئة ، بدلاً من وجود برنامج نصي خاص للإعداد للمضيف المحلي مقابل كل شيء آخر.

+1 للميزة

+1

+10

+1

+1

لإبقائك على قيد الحياة ، يمكنك فقط التأكد من تشغيل خادم OpenSSH. قم أولاً بعمل sudo apt-get install ssh للتأكد من تثبيته (حتى لو كنت تعتقد أنك تفعل ذلك). ثم افعل sudo service ssh start | stop | restart حسب الحاجة. تعلمت من هذا الموضوع .

+1

حالة الاستخدام الخاصة بي بسيطة: أريد استخدام نفس البرنامج النصي لنشر django لتكوين مثيلات ec2 مع كل من cloud-init من خلال CloudWatch (حالة تشغيل الأوامر المحلية) واستخدام fab deploy_django -H foo@bar العادي.

+1

هذا سيكون مفيدا حقا إحدى حالات الاستخدام التي أستخدمها هي استخدام موفر الصدفة المتشرد لتكوين جهاز افتراضي معين باستخدام النسيج ودون الحاجة إلى ssh localhost.

+1

لقد فوجئت بعدم رؤية هذا في Fabric بالفعل.

لمعلوماتك: يصبح تنفيذ هذه الميزة أكثر تعقيدًا عندما تفكر في وظائف النسيج مثل reboot() .

+1

يجب أن يكون جزءًا من النواة بالفعل!

+1

سيكون ذلك منطقيًا تمامًا: من وجهة نظر مجردة ، فإن local هو مجرد حالة خاصة run ، حيث لا توجد آلات SSH.

هناك شيء آخر يجب الإشارة إليه (ربما يكون واضحًا): يجب أن يكون النسيج ذكيًا بما يكفي لتقرير ما إذا كان يجب تحويل run إلى local بعد قراءة / etc / hosts.

أعني: إذا كان لدينا

env.host = [ 'mywebserver' ]

وفي / etc / hosts لدينا:

127.0.0.1 mywebserver

إذن ، أي مكالمات run يجب أن تكون في الواقع local للمكالمات.

بأخذ هذا المفهوم خطوة إلى الأمام ، يجب أن نتعامل أيضًا مع run كمكالمة محلية عندما يحل المضيف البعيد إلى IP الذي تم تعيينه لواجهة شبكة للجهاز المحلي.
على سبيل المثال:
ملف فاب:

env.host = [ 'mywebserver' ]

/ etc / hosts:

192.168.1.1 mywebserver

ip addr :

[...]
eth0:
  inet 192.168.1.1
[...]

+1

+1: +1:

: +1:

+1

+1

سوف يستخدم Fabric 2 pyinvoke / invoke لذا من السهل جدًا القيام بذلك هناك. كنت أنتظر Fabric 2 للحصول على طريقة غير معقدة للقيام بذلك.

: +1:

+1

: +1:

: +1: يرجى تنفيذ ذلك ، خاصة وأن أجهزة كمبيوتر mac لا يتم إعدادها تلقائيًا لتهيئة أنفاق SSH للوصول عن بُعد إلى خادم المضيف المحلي.

+1

+1 :)

+1 من فضلك

: +1:

: +1:

: +1:

نحن نستخدم Fab لبناء حزم دبيان وهذا يضيف تعقيدًا إضافيًا

يا رفاق ، مرحبا بكم جميعا
أحاول إنشاء نسخة من القماش مع اختلاف:

  • تعمل الدالة run () بنفس الطريقة مع subprocess.popen ضمن المضيف المحلي كما هو الحال في ssh ، اتصل بالمضيف البعيد
  • يستخدم المصنع opensh أو أي عميل ssh آخر (يجب عليك تعديل التكوين لذلك) ، حتى تتمكن من استخدام كل طاقة مآخذ ssh
  • يستخدم المصنع مكتبة gevent للتنفيذ غير المتزامن

يمكنك إلقاء نظرة إذا كنت بحاجة إلى هذه الميزة
https://github.com/Friz-zy/factory

قد أفتقد شيئًا ما في هذه المناقشة ، ولكن هذا ما فعلته لاستخدام نفس الرمز مع الأمر fab run على كل من المضيف المحلي والأجهزة البعيدة.

  1. قمت بتعيين env.use_ssh_config = True في ملفي fabfile.py
  2. ssh-copy-id localhost

هذا لا يحل مشكلتك إذا كنت لا تقوم بتشغيل خادم ssh على جهازك المحلي

: +1:

+1

+1 الرجاء تنفيذ هذه الميزة :)

+1

قد يكون مفيدًا جدًا في تمهيد صور Docker باستخدام البرامج النصية الموجودة في Fabric. ستتجنب هذه الميزة تثبيت خادم SSH على الحاوية ، وهو ما يتعارض مع أفضل ممارسات Docker

+1

+1

+1

بالإضافة إلى الإجابة التي قدمتها AntoniosHadji ، إليك التعليمات الكاملة لإنجاح هذا العمل ؛

# Generate new SSH key for local usage
ssh-keygen -f ~/.ssh/id_rsa -N ''

# Add server keys to users known hosts (eliminates 'are you sure' messages);
ssh-keyscan -H localhost > ~/.ssh/known_hosts

# Allow user to ssh to itself
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

في الواقع ، يمكن القيام بذلك باستخدام المطبخ . تحتاج إلى تغيير جميع عمليات التنفيذ run للإشارة إلى دالة cuisine.run ، والتي يمكن إجراؤها بسهولة من خلال الاستيراد ، وتغيير الوضع إلى الوضع المحلي:

from cuisine import run, mode_local

mode_local()
print run("echo Hello")

cgarciaarano رائع

لحالات الاستخدام البسيطة ، هذا يناسبني:

from fabric.api import run, local
# ...
# in task:
  if env.host is None or env.host == 'localhost':
    run = local

: +1:

أريد تشغيل ملف fabfile الخاص بي عن بُعد أو محليًا عندما لا يكون ssh خيارًا. يتضمن ذلك أغلفة محلية للحصول على / وضع / موجود وما إلى ذلك.

: +1: لدي ملفات فاب تعمل محليًا وعن بعد وانتهى بي الأمر باختراق وظائف الغلاف الخاصة بي للتشغيل / المحلي / للتعامل مع جميع الاختلافات الدقيقة مثل التقاط الإخراج ومعالجة الأخطاء.

ماذا لو كان لديك اتصال ssh يقوم بإعادة توجيه منفذ ديناميكي وربطه على 127.0.0.2 (لا يزال محليًا تقنيًا) على المنفذ 2223. يمكنني أن أرى كيف يمكن أن يتسبب ذلك في حدوث مشكلات ، لتحقيق هذه الغاية المطابقة على المضيف المحلي والحل إلى 127.0.0.1 بدلاً من أيضًا قد يكون دعم الفئة 127.0.0.0/8 بأكملها فكرة جيدة للتعامل معها.

@ blade2005 نعم ، يشير النطاق 127 بأكمله _._. * إلى مضيفك المحلي (باستثناء 127.0.0.0 و 127.255.255.255) ولكن عندما تشير فعليًا إلى مضيفك المحلي ، فلن تستخدم المنفذ بشكل صحيح؟
لذلك أعتقد أنه يمكننا أن نفترض بأمان أنه يمكن تجنب 127.*.*.* == localhost و ssh ولكن 127.*.*.*:* يشير إلى منفذ معاد توجيهه و ssh مطلوب.

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

لقد نفذت شيئًا محليًا ، وهو عمل أكثر بكثير من مجرد التبديل بين التشغيل المحلي / التشغيل. عليك أن تفكر في البادئات والأدلة المتغيرة ومستخدمي sudo وما إلى ذلك.

كنت أفكر بإيجاز في هذا في سياق تذكرة أخرى ذات صلة بـ 2.0 ، وأدركت أن هناك المزيد الذي يظهر بجانب " run يصبح إعادة ربط local ":

  • أي نوع من المهام ذات الوضع المختلط حقًا باستخدام كل من local و run ، أو أي من put / get ، تصبح مشكلة بطبيعتها: العمليات ذات التحديد الواضح ينتهي الآن كلاهما "محلي" و "بعيد" محليًا.

    • أفترض أن هذه حالة استخدام أقلية (إذا كانت واحدة على الإطلاق) ولكنها لا تزال بحاجة إلى معرفة ، حتى لو كانت "تستدعي أي عملية ولكن run أو sudo ترفع DoesntMakeAnySenseError "أو أيا كان.

    • put المفترض أن يتحول get إلى shutil.copy أو ما شابه

    • local المفترض ألا يتم تغيير run-except-locally ...؟)

    • تم التطرق إلى ما سبق ، فإن طرق معالجة السياق / مديري السياق المختلفة مثل prefix ، cd إلخ ، تحتاج جميعها إلى إجابات مماثلة.

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

    • ما لم يصبح أيضًا مجرد ارتباط آخر بـ local ، وهو احتمال آخر. على الرغم من أنها ليست كبيرة ، إلا أن أي أوامر sudo تعمل محليًا (على سبيل المثال ، يتم النشر إلى Linux ونشره) من المفترض أن تظل مميزة محليًا (على سبيل المثال ، apt / yum والأصدقاء ، إصلاح جدار الحماية ، إلخ).

  • يحتاج sudo أيضًا (كما أشار جون أعلاه) إلى زيادة إمكانية تكوين متجهات تكوين محلية مقابل بعيدة نظرًا لأن مستخدم sudo وكلمة المرور وما إلى ذلك من المحتمل أن تختلف بين الجانبين.

    • على الرغم من أنني أفكر في كل هذا في سياق Fab 2 ، فمن المحتمل أن تحل تجاوزات التكوين المتوقعة لكل مضيف هذا الجزء من الأشياء على الأقل - سيتم ببساطة تسليم سياق localhost القيم المناسبة. (بالإضافة إلى ذلك ، كفئة فرعية مخصصة "لتشغيل الأشياء عن بُعد محليًا" Context يمكنها القيام بأشياء أخرى أيضًا ، إذا لزم الأمر).

كان @ max-arnold يحاول ذلك في الإصدار 2 ألفا وواجه مشكلات مربكة ، وهو أمر متوقع في هذه المرحلة منذ - لم أقم بتجربة حالة استخدام هذه التذكرة المعينة حتى الآن ، بخلاف ضمان run و local لديهما واجهات برمجة تطبيقات مشابهة قدر الإمكان.

في الوقت الحالي ، تكمن المشكلة الكبرى ببساطة في طبيعة وواجهة برمجة تطبيقات الكائن المرتبط بسياق المهمة ( c أو ctx أو أيًا كان اسمه) posarg. في الوقت الحالي ، ومرة ​​أخرى ، لا يُقصد من هذا أن يكون نهائيًا ، إنه فقط كيف انتهى الأمر حتى الآن:

  • بشكل افتراضي ، عند تنفيذه بواسطة Invoke Executor ، أو بواسطة Fab 2 FabExecutor حالة عدم وجود مضيفين ، يكون invoke.Context ، الذي يحتوي على run يتم تشغيله محليًا ، ويفتقر إلى local ؛
  • عندما يكون لدى Fab 2 مضيف (مضيفات) للتشغيل عليه ، فإنه ينشئ fabric.Connection ، الذي يعمل عن بعد run ، والذي local هو إعادة ربط لـ Invoke run (وهكذا يتم تشغيله محليًا ، أصليًا ، وليس عبر SSH إلى مضيف محلي أو أي شيء.)

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

  • الحل المفيد (أو _ على الأقل _ التوثيق) لهذا يجب أن يكون موجودًا بشكل شبه مؤكد (لكل محادثة سابقة حوله تعيش خارج النواة) للأسباب التالية:

    • إنها حالة استخدام شائعة بدرجة كافية

    • من السهل الفوضى

    • مطلوب لتنفيذ إصدارات متوافقة مع الإصدار 2 بشكل مفيد patchwork (née contrib ) و / أو invocations (إصدار Invoke من نفس الإصدار) ، خاصةً لأنه يُعلم مقدار مشاركة الكود التي يمكنهم مشاركتها فعل. قد ترغب العديد من المهام و / أو الإجراءات الفرعية في تلك الأنواع من قواعد التعليمات البرمجية في التشغيل محليًا أو عن بُعد.

  • يتعلق الأمر في جوهره بما تتوقعه واجهة برمجة التطبيقات من كائنات السياق حيث قد لا تعرف المهمة على وجه اليقين "كيف" يتم استدعاؤها
  • يمكن أن يتوقف على كيفية إنشاء المهمة ، أي إصدارات مختلفة من @task و / أو kwargs لنفسها ، حيث قد يعلن المستخدم توقعاته (على سبيل المثال ، "أريد حقًا أن أحصل على سياق قادر على التحكم عن بعد" ، "من فضلك لا تعطيني أبدًا سياق قادر على التحكم عن بعد" ، وما إلى ذلك)

    • قد نرغب في _طلب_ هذا لتجنب الغموض ( ZoP # 12 )

    • كلما فكرت في الأمر أكثر ، بدا واضحًا أننا نريد من Fabric أن ينمي غلافه الخفيف الوزن بحوالي @task / Task ؛ ستستخدم قواعد أكواد Pure-Invoke الخاصة بها @task والتي ستؤدي دائمًا إلى منح الفانيليا Context ، في حين أن المهام التي تم إنشاؤها عبر إصدار Fabric سيكون لها على الأقل خيار الحصول على Connection ، إذا لم تطلب واحدًا.

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

    • على الرغم من أن هذا هو في الواقع نقطة واحدة كاملة لواجهة برمجة التطبيقات الحالية ؛ هذه المهام _لا تهتم_ بفئة السياق الفرعية _ طالما أن ctx.run() موجود_.

    • لذلك من المفترض أن يتم تزيين هؤلاء بإصدار "أنا فقط بحاجة إلى قاعدة سياق الفانيليا" من @task ، مع إدراك أن شخصًا ما من وجهة نظر استدعاء قماش (أو شبيه بالنسيج) لديه خيار إعطاء هؤلاء المهام Connection بدلاً من Context .



      • وهو ما يعيدنا إلى التساؤل عن كيفية تنفيذ المهام بالضبط ، ويعرف أيضًا باسم pyinvoke / استدعاء # 170



  • بغض النظر عن التنفيذ ، يتعين علينا التأكد من أننا نقلل من إمكانات استخدام المسدس إلى الحد الأدنى: يقوم المستخدمون بأشياء مثل:

    • توقع local عندما لا يكون موجودًا (يتم تشغيل كود توقع الاتصال / النسيج عبر Invoke)

    • توقع تشغيل run محليًا عندما تم إعطاء سياق واحد بدلاً من ذلك باستخدام run (استدعاء / تشغيل كود توقع السياق عبر Fabric)

    • أي شيء آخر من تعليق Max الإضافي هنا

  • كما هو موضح في التعليقات الأقدم ، فإن حالة الاستخدام الفرعي هنا هي أن المستخدمين يتوقعون ما يعادل v2 Connection('localhost').run('foo') _لا يستخدم SSH_ ولكن بدلاً من ذلك يتصرف تمامًا مثل Connection('localhost').local('foo') .

    • أنا _أخمن_ أننا لا نريد في الواقع القيام بذلك لأنه يبدو وكأنه مسدس قدم سيئ لأي شخص يحاول إجراء فحوصات سلامة المضيف المحلي. إنه مجرد شعور سحري للغاية بالنسبة لي. لكنني منفتح على الحجج ، ربما على أساس التقيد (على سبيل المثال ، قم بتعيين خيار تكوين مثل ssh.localhost_becomes_subprocess = True أو أيًا كان.)

حالة الاستخدام الوحيدة هنا في الوقت الحالي ستكون upload_template() أن أكون قادرًا على عرض قالب محليًا.

بالطبع يمكن للمرء أن يفعل ذلك على النحو التالي:

#http://matthiaseisen.com/pp/patterns/p0198/
import os
import jinja2


def render(tpl_path, context):
    path, filename = os.path.split(tpl_path)
    return jinja2.Environment(
        loader=jinja2.FileSystemLoader(path or './')
    ).get_template(filename).render(context)

ولكن لماذا لا يكون لديك خيار العرض محليًا؟

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

ضع في اعتبارك أن لديك settings.py.j2 يتم عرضه على الخادم الوجهة عند النشر وهناك اسمه settings.py ويحتوي فقط على كود python ، وليس jinja.
أنت الآن تريد إجراء الاختبار محليًا ، ولكن لا يوجد أي settings.py محليًا حتى الآن ، لأنه يحتاج إلى الحصول عليه من settings.py.j2 .
لذلك لا يمكن بدء تطبيقك ، وسيتعين عليك إنشاء settings.py منفصل يدويًا للاختبار المحلي الخاص بك.

هذا متعب للغاية ، ويجب أن يكون أسهل.

على سبيل المثال ، في Ansible ، سأقول للمهمة أنها ستستخدم "اتصال محلي" ، وسوف يتم عرضها على المضيف المحلي دون محاولة الدخول إليها.

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

fninja لم upload_template نفسه حتى الآن لكنني أوافق بالتأكيد على أنه يقع ضمن مساحة المشكلة هذه. يمكن القول إنه يمكن للمرء التعامل مع هذا فقط عن طريق تقسيم خطوة تصيير التفاف Jinja وخطوة تحميل بعض السلاسل ، esp نظرًا لأن الأخير موجود بالفعل في شكل "تسليم FLO إلى put ". على سبيل المثال:

from StringIO import StringIO # too lazy to remember the newer path offhand
from somewhere.jinja_wrapper import render
from invoke import task

<strong i="9">@task</strong>
def render_settings(c):
    rendered = render('settings.py.j2', {'template': 'params'})
    c.put(StringIO(rendered), 'remote/path/to/settings.py')

ولكن ربما لا يزال هناك مجال لتناظرية ذات نقطة توقف واحدة أقصر إلى upload_template والتي ستكون إما طريقة Connection أو إجراء فرعي يأخذ وسيطة Connection .

في كلتا الحالتين ، فإنه يثير المزيد من الأسئلة حول: كيفية التعامل بالضبط مع هذا النوع من الأشياء - على سبيل المثال ، لا تحتوي عناصر Invoke-only Context على put / get . هل يستحق إضافتهم؟ من المنطقي جدًا لمستخدمي Fabric في سياق هذه التذكرة (ثم upload_template أو w / e يمكن ببساطة الاتصال بـ put في كلتا الحالتين) ، ولكن بالنسبة لمستخدمي Pure Invoke ، فهو أمر غريب وجزء عديم الفائدة من API.

+1 لجعل هذه الميزة أساسية

Crosspost من # 1637. مجرد فكرة:

from fabric import task, local

<strong i="6">@task</strong>
<strong i="7">@local</strong>
def build(ctx):
    with ctx.cd('/project/dir'):
        ctx.run('build > artifact.zip')

<strong i="8">@task</strong>
def deploy(conn):
    build(local(conn))

    with conn.cd('/remote/path'), local(conn).cd('/project/dir'):
        conn.put(remote_path='build.zip', local_path='artifact.zip')

يمكن أن يعمل local() كديكور / مدير سياق / وظيفة وتحويل Connection إلى Context .

حالة استخدام أخرى لا أعتقد أنني رأيتها مذكورة: إنشاء مكتبة للوظائف القابلة لإعادة الاستخدام. في حالتي ، يكون الأمر في الغالب عبارة عن أوامر git . كتبت dorun مفرط التبسيط يخفي الاختلافات بين معلمات الدالة run و local (في الإصدار 1) ؛ يتم تمرير الوظيفة التي يتم اختيارها كمعامل. إليك git checkout على سبيل المثال:

def git_checkout(branch, remote='origin', run=run):
    """Checkout a branch if necessary."""

    if branch == git_current_branch(run=run):
        return
    elif branch in git_local_branches(run=run):
        dorun('git checkout ' + branch, run=run)
    else:
        dorun('git checkout -t -b {0} {1}/{0}'.format(branch, remote), run=run)


def git_current_branch(run=run):
    """Get the current branch (aka HEAD)"""

    output = dorun('git name-rev --name-only HEAD', run=run)
    return output.strip()


def git_local_branches(run=run):
    """Get a list of local branches; assumes in repo directory."""

    output = dorun('git branch --no-color', run=run)
    branches = {l.strip().split(' ')[-1]
                for l in output.strip().split('\n')}
    return branches

تبدو هكذا:

from fabric.api import run as run_remote, local as run_local

def dorun(*args, **kwargs):
    """Work around the fact that "local" and "run" are very different."""
    kwargs.setdefault('run', run_remote)
    run = kwargs.pop('run')

    if run == run_local:
        kwargs.setdefault('capture', True)
    elif 'capture' in kwargs:
        del kwargs['capture']

    return run(*args, **kwargs)

ليس لدي أي فكرة عما يحدث مع sudo وهناك مشكلات لا يمكنني التعامل معها بسهولة ، مثل توسيع ~remoteuser لإنتاج مسار.

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