.\" Man page generated from reStructuredText .\" by the Docutils 0.22.3 manpage writer. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "TESTINFRA" "1" "Dec 20, 2025" "10.2.2" "testinfra" .SH "نام (NAME)" testinfra \- مستندات testinfra .sp آخرین مستندات: \% .SH "درباره (ABOUT)" .sp با Testinfra می‌توانید آزمون‌های واحد (unit tests) را در Python بنویسید تا \fIوضعیت واقعی\fP سرورهای خود را که توسط ابزارهای مدیریتی مانند Salt \%، Ansible \%، Puppet \%، Chef \% و غیره پیکربندی شده‌اند، بسنجید و آزمایش کنید. .sp هدف Testinfra تبدیل شدن به معادل Serverspec \% در پایتون است و به عنوان یک افزایه (plugin) برای موتور قدرتمند آزمون Pytest \% نوشته شده است. .SH "مجوز (LICENSE)" .sp Apache License 2.0 \% .sp نشان‌واره تحت مجوز Creative Commons NoDerivatives 4.0 License \% منتشر شده است. اگر کاربرد دیگری مد نظرتان است، با ما تماس بگیرید. .SH "شروع سریع (QUICK START)" .sp نصب testinfra با استفاده از pip: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pip install pytest\-testinfra # or install the devel version $ pip install \(aqgit+https://github.com/pytest\-dev/pytest\-testinfra@main#egg=pytest\-testinfra\(aq .EE .UNINDENT .UNINDENT .sp نخستین فایل آزمون‌های خود را در \fItest_myinfra.py\fP بنویسید: .INDENT 0.0 .INDENT 3.5 .sp .EX def test_passwd_file(host): passwd = host.file(\(dq/etc/passwd\(dq) assert passwd.contains(\(dqroot\(dq) assert passwd.user == \(dqroot\(dq assert passwd.group == \(dqroot\(dq assert passwd.mode == 0o644 def test_nginx_is_installed(host): nginx = host.package(\(dqnginx\(dq) assert nginx.is_installed assert nginx.version.startswith(\(dq1.2\(dq) def test_nginx_running_and_enabled(host): nginx = host.service(\(dqnginx\(dq) assert nginx.is_running assert nginx.is_enabled .EE .UNINDENT .UNINDENT .sp و آن را اجرا کنید: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-v test_myinfra.py ====================== test session starts ====================== platform linux \-\- Python 2.7.3 \-\- py\-1.4.26 \-\- pytest\-2.6.4 plugins: testinfra collected 3 items test_myinfra.py::test_passwd_file[local] PASSED test_myinfra.py::test_nginx_is_installed[local] PASSED test_myinfra.py::test_nginx_running_and_enabled[local] PASSED =================== 3 passed in 0.66 seconds ==================== .EE .UNINDENT .UNINDENT .SH "مستندات (DOCUMENTATION)" .SS "تغییرات (Changelog)" .SS 10.2.2 .INDENT 0.0 .IP \(bu 2 [FIX] گنجاندن فایل‌های لازم برای اجرای آزمون‌ها در sdist .UNINDENT .SS 10.2.1 .INDENT 0.0 .IP \(bu 2 [FIX] رفع ایراد انتشار در pypi .UNINDENT.SS 10.2.0 .INDENT 0.0 .IP \(bu 2 [جدید] پرس‌وجوی تمام نام‌های کاربری و نام‌های گروه .IP \(bu 2 [اصلاح] جلوگیری از بن‌بست Paramiko هنگامی که آزمون بیش از 2MB داده به stdout ارسال می‌کند .IP \(bu 2 [اصلاح] هماهنگی با تغییرات ماژول shell در ansible .IP \(bu 2 [اصلاح] افزودن 4 به کد خروج مورد انتظار هنگام اجرای \(dqsystemctl is\-active\(dq .IP \(bu 2 [اصلاح] رفع خطای KeyError در MountPoint.__repr__() در صورت عدم وجود mount .IP \(bu 2 [مستندات] استفاده از دستور pytest به‌جای py.test .IP \(bu 2 [مستندات] گسترش مستندات backend با افزودن یک بخش عمومی برای مشخصات میزبان (host spec) .IP \(bu 2 [متفرقه] اجرای lint برای py 3.12 و 3.13 نیز .IP \(bu 2 [متفرقه] تغییر سیستم بسته‌بندی برای استفاده از hatchling .IP \(bu 2 [متفرقه] حذف آرگومان اضافی و استفاده‌نشده‌ی \(dqargs\(dq در run_winrm() .IP \(bu 2 [متفرقه] استفاده از ruff format به‌جای black/isort .IP \(bu 2 [متفرقه] استفاده از ruff به‌جای flake8 .IP \(bu 2 [متفرقه] استفاده از f\-string به‌جای str.format() .IP \(bu 2 [متفرقه] استفاده از dict، list و tuple توکار برای تعیین نوع (typing) .IP \(bu 2 [متفرقه] استفاده از python 3.11 در طول آزمون‌ها .IP \(bu 2 [متفرقه] اصلاح آزمون‌های salt .IP \(bu 2 [متفرقه] رفع مشکل آزمون‌هایی که به دلیل سپری شدن تاریخ انقضا ناموفق می‌شدند .IP \(bu 2 [متفرقه] حذف کتابخانه crypt از فرایند آزمون .UNINDENT .SS 10.1.1 .INDENT 0.0 .IP \(bu 2 [اصلاح] افزودن بررسی برای وجود دایرکتوری ssh control path .IP \(bu 2 [اصلاح] مدیریت is_installed برای بسته‌های rpm در صورت خرابی پایگاه‌داده rpm .IP \(bu 2 [اصلاح] رفع مشکل service.exists .UNINDENT .SS 10.1.0 .INDENT 0.0 .IP \(bu 2 [جدید] افزودن ویژگی Interface.link .IP \(bu 2 [اصلاح] پیروی ویژگی‌های فایل از پیوندهای نمادین (symlinks) .IP \(bu 2 [اصلاح] الزام به pytest>=6 و استفاده از حاشیه‌نویسی‌های آینده (future annotations) برای سازگاری با pytest<7 .UNINDENT .SS 10.0.0 .INDENT 0.0 .IP \(bu 2 [اصلاح] Ansible: رفع مشکل نبود نام‌های گروه در get_variables() .IP \(bu 2 [اصلاح] testinfra/modules/blockdevice: عدم ایجاد خطا و شکست در هنگام خروجی روی stderr .IP \(bu 2 [مستندات] گسترش و نمایش مستندات CommandResult .IP \(bu 2 [اصلاح] گسترش فهرست پسوندهای معتبر برای واحدهای systemd .IP \(bu 2 [مستندات] افزودن بخش مستندات از قلم‌افتاده‌ی Environment .IP \(bu 2 [متفرقه] تعیین انواع داده (types) برای plugin.py .IP \(bu 2 [اصلاح] رفع مشکل عدم وجود توزیع RHEL در ماژول package .IP \(bu 2 [جدید] افزودن پشتیبانی از brew در ماژول package .IP \(bu 2 [جدید] افزودن Service.exists .IP \(bu 2 [متفرقه] تبدیل CommandResult به یک dataclass .UNINDENT .SS 9.0.0 .INDENT 0.0 .IP \(bu 2 [تغییر ناسازگار] pytest\-testinfra اکنون نیازمند python >= 3.9 است .IP \(bu 2 [تغییر ناسازگار] حذف ماژول منسوخ‌شده‌ی PipPackage .IP \(bu 2 [جدید] افزودن پشتیبانی از گزینه اشتراک‌گذاری اتصال ControlPath در SSH (#713) .IP \(bu 2 [اصلاح] تلاش مجدد اتصال SSH هنگام بروز ConnectionResetError (#708) .IP \(bu 2 [اصلاح] فهرست کردن صریح openSUSE Leap و Tumbleweed به‌عنوان توزیع‌های مبتنی بر rpm .IP \(bu 2 [اصلاح] اجباری کردن نام گروه در ماژول group .UNINDENT .SS 8.1.0 .INDENT 0.0 .IP \(bu 2 [جدید] افزودن پشتیبانی از Windows برای ماژول‌های File و Service .IP \(bu 2 [جدید] افزودن ویژگی File.is_executable .UNINDENT .SS 8.0.0 .INDENT 0.0 .IP \(bu 2 [جدید] افزودن مشخصه‌ی Group.members .IP \(bu 2 [جدید] افزودن مشخصه‌ی File.inode .IP \(bu 2 [جدید] افزودن متد Interface.routes() .IP \(bu 2 [جدید] افزودن مشخصه‌ی Docker.is_restarting .IP \(bu 2 [اصلاح] رفع خطای احتمالی در Interface.default() .IP \(bu 2 [اصلاح] اصلاح تشخیص busybox در ماژول Process .IP \(bu 2 [اصلاح] رفع خطای احتمالی KeyError در ماژول SysInfo .IP \(bu 2 [تغییر ناسازگار] توقف پشتیبانی از python 3.7 .UNINDENT.SS 7.0.1 .INDENT 0.0 .IP \(bu 2 [اصلاح] رفع مشکل سازگاری \fIcommand \-v\fP با پوسته dash .UNINDENT .SS 7.0.0 .INDENT 0.0 .IP \(bu 2 [جدید] بهبود پشتیبانی از پیکربندی ssh در بک‌اند Paramiko .IP \(bu 2 [جدید] افزودن بک‌اند chroot .IP \(bu 2 [جدید] افزودن پشتیبانی از Manjaro\-Linux .IP \(bu 2 [جدید] افزودن پشتیبانی از Cloudlinux .IP \(bu 2 [تغییر بنیادین] توقف پشتیبانی از python 3.6 به دلیل پایان دوره پشتیبانی (EOL) .UNINDENT .SS 6.8.0 .INDENT 0.0 .IP \(bu 2 [جدید] افزودن پشتیبانی از AlmaLinux و RockyLinux .UNINDENT .SS 6.7.0 .INDENT 0.0 .IP \(bu 2 [جدید] پشتیبانی از نوع ansible_connection با مقدار community.docker.docker .IP \(bu 2 [جدید] افزودن گزینه ssh_extra_args .UNINDENT .SS 6.6.0 .INDENT 0.0 .IP \(bu 2 [جدید] امکان بررسی انقضای گذرواژه کاربر .IP \(bu 2 [جدید] مدیریت متغیرهای محیطی ANSIBLE_SSH_COMMON_ARGS و ANSIBLE_SSH_EXTRA_ARGS برای اتصال‌های ansible .IP \(bu 2 [اصلاح] رفع مشکل کدگذاری در اتصال‌های salt .IP \(bu 2 [اصلاح] رفع خطای AttributeError در صورت در دسترس نبودن \(dqcommand\(dq و استفاده جایگزین از \(dqwhich\(dq .UNINDENT .SS 6.5.0 .INDENT 0.0 .IP \(bu 2 استفاده جایگزین از which در صورت شکست \(dqcommand \-v\(dq .IP \(bu 2 استفاده پیش‌فرض از realpath برای حل پیوندهای نمادین به‌جای \(dqreadlink \-f\(dq .IP \(bu 2 ansible: پشتیبانی از متغیرهای محیطی .IP \(bu 2 اجبار ماژول package به ارجاع به RpmPackage در Fedora .IP \(bu 2 رفع مشکلی که در آن نسخه‌های جدید supervisor ممکن بود با وضعیت != 0 خارج شوند .IP \(bu 2 رمزگشایی خروجی ansible در صورت غیر ascii بودن .IP \(bu 2 استفاده از python3 یا python جهت دریافت کدگذاری راه دور .UNINDENT .SS 6.4.0 .INDENT 0.0 .IP \(bu 2 پیاده‌سازی نام‌های Interface و پیش‌فرض (#615) .IP \(bu 2 پیاده‌سازی Service.systemd_properties (#612) .UNINDENT .SS 6.3.0 .INDENT 0.0 .IP \(bu 2 رفع مشکل #451 برای استفاده با pytest \-p no:terminal .IP \(bu 2 افزودن client_version() و server_version() و version() به ماژول docker. .UNINDENT .SS 6.2.0 .INDENT 0.0 .IP \(bu 2 رفع مشکل #590: عدم تشخیص صحیح Windows توسط Systeminfo (#592) .IP \(bu 2 نخستین پیاده‌سازی فضاهای نام شبکه در ماژول addr (#596) .IP \(bu 2 پشتیبانی از pip check در ماژول PipPackage (#605) .IP \(bu 2 بازسازی ساختار pip: پیاده‌سازی installed و version (#606) .IP \(bu 2 امکان تعیین مسیرهای supervisorctl و supervisord.conf (#536) .UNINDENT .SS 6.1.0 .INDENT 0.0 .IP \(bu 2 رفع مشکل انتخاب نادرست ماژول package در CentOS هنگام نصب بودن ابزارهای dpkg (#575) #570 .IP \(bu 2 حذف میزبان‌های تکراری بازگردانده‌شده توسط get_backends() (#572) .IP \(bu 2 استفاده از /run/systemd/system/ برای تشخیص systemd (رفع #546) .IP \(bu 2 استفاده از ssh_args از فایل ansible.cfg .IP \(bu 2 الزام به python >= 3.6 .IP \(bu 2 رفع خطای ValueError در python 3.8+ هنگام استفاده از گزینه \-\-nagios. .UNINDENT .SS 6.0.0 .INDENT 0.0 .IP \(bu 2 تغییر بنیادین: پروژه testinfra به سازمان \% منتقل شده است. نام پروژه در PyPi به pytest\-testinfra تغییر یافته است. یک بسته موقت testinfra فرایند انتقال را تسهیل می‌کند، اما باید نام آن را در فایل‌های requirements خود به pytest\-testinfra تغییر دهید. .UNINDENT .SS 5.3.1 .INDENT 0.0 .IP \(bu 2 رفع اشکال ویژگی تازه ارائه‌شده is_masked در سرویس systemd \% .UNINDENT .SS 5.3.0 .INDENT 0.0 .IP \(bu 2 افزودن ویژگی is_masked به سرویس systemd .UNINDENT .SS 5.2.2 .INDENT 0.0 .IP \(bu 2 iptables: استفاده از گزینه \-w جهت انتظار برای دریافت قفل iptables هنگام اجرای موازی با pytest\-xdist. .UNINDENT.SS 5.2.1 .INDENT 0.0 .IP \(bu 2 رفع مشکل ساخت مستندات .UNINDENT .SS 5.2.0 .INDENT 0.0 .IP \(bu 2 امکان تعیین کانتکست kubeconfig در بک‌اند kubernetes .IP \(bu 2 حذف پیاده‌سازی file.__ne__ و الزام به نسخه python >= 3.5 .UNINDENT .SS 5.1.0 .INDENT 0.0 .IP \(bu 2 استفاده از remote_user و remote_port در ansible.cfg .IP \(bu 2 افزودن مشخصه \fIarch\fP (معماری) به ماژول system_info .UNINDENT .SS 5.0.0 .INDENT 0.0 .IP \(bu 2 تغییر ناسازگار (Breaking change): دستور host.file().listdir() اکنون یک متد است .UNINDENT .SS 4.1.0 .INDENT 0.0 .IP \(bu 2 ارسال آرگومان‌های اضافی به خط فرمان ansible از طریق host.ansible() .IP \(bu 2 متد جدید host.file.listdir() برای فهرست کردن موارد موجود در یک دایرکتوری. .UNINDENT .SS 4.0.0 .INDENT 0.0 .IP \(bu 2 پایان پشتیبانی از python2 .UNINDENT .SS 3.4.0 .INDENT 0.0 .IP \(bu 2 افزودن ماژول و بک‌اند podman .IP \(bu 2 هشدار: این آخرین نسخه testinfra با پشتیبانی از python2 خواهد بود، لطفاً به python3 ارتقا دهید. .UNINDENT .SS 3.3.0 .INDENT 0.0 .IP \(bu 2 افزودن extras برای وابستگی‌های بک‌اند (#454) .IP \(bu 2 بهبودهای مختلف در مستندات یکپارچه‌سازی با kitchen .IP \(bu 2 پشتیبانی بک‌اند ansible از فیلد \(dqpassword\(dq در اینونتوری ansible .IP \(bu 2 بک‌اند جدید \(dqopenshift\(dq .UNINDENT .SS 3.2.1 .INDENT 0.0 .IP \(bu 2 رفع ایراد ماژول Process هنگام کار با رشته‌های طولانی (نام کاربری و...) #505 .UNINDENT .SS 3.2.0 .INDENT 0.0 .IP \(bu 2 ماژول جدید \(dqenvironment\(dq برای دریافت متغیرهای محیطی راه دور .IP \(bu 2 ماژول جدید \(dqblock_device\(dq برای نمایش اطلاعات دستگاه‌های بلوکی .IP \(bu 2 افزودن پرچم سراسری \-\-force\-ansible به خط فرمان .IP \(bu 2 صدور خطا در صورت عدم وجود فایل اینونتوری ansible .IP \(bu 2 رفع مشکل گریز (escape) نویسه‌ها در آرگومان‌های ssh در ansible هنگام تنظیم در اینونتوری یا فایل پیکربندی .UNINDENT .SS 3.1.0 .INDENT 0.0 .IP \(bu 2 اتصالات ssh به‌طور پیش‌فرض از اتصالات پایدار (persistent) استفاده می‌کنند. می‌توانید با ارسال controlpersist=0 به گزینه‌های اتصال، این قابلیت را غیرفعال کنید. .IP \(bu 2 اتصالات ssh در ansible اکنون به‌جای paramiko از بک‌اند ssh استفاده می‌کنند. اکنون گزینه‌های ansible_ssh_common_args و ansible_ssh_extra_args لحاظ می‌شوند. .IP \(bu 2 افزودن گزینه اتصال جدید ansible با نام \(dqforce_ansible\(dq؛ هنگامی که روی True تنظیم شود، testinfra همواره ansible را برای اجرای تمام دستوراتی که نیاز دارد فراخوانی می‌کند. .IP \(bu 2 پوشش تمام انواع اتصالات ansible با تنظیم force_ansible=True برای اتصالاتی که معادل متناظری در testinfra ندارند (برای نمونه \(dqnetwork_cli\(dq). .UNINDENT .SS 3.0.6 .INDENT 0.0 .IP \(bu 2 ثبت وقایع کامل دستورات تنها در سطح لاگ DEBUG جهت جلوگیری از لاگ شدن داده‌های حساس در سطح لاگ INFO. .IP \(bu 2 رفع خرابی احتمالی هنگام پردازش اینونتوری‌های ansible #470 .IP \(bu 2 پشتیبانی از فایل kubeconfig جایگزین در اتصالات kubectl #460 .IP \(bu 2 پشتیبانی از تجزیه ProxyCommand از فایل ssh_config برای اتصالات paramiko .UNINDENT .SS 3.0.5 .INDENT 0.0 .IP \(bu 2 تنظیم زمان انتظار پیش‌فرض (timeout) به ۱۰ ثانیه در اتصالات ssh/paramiko .IP \(bu 2 افزودن پشتیبانی از پارامتر ansible_private_key_file در اینونتوری ansible .UNINDENT .SS 3.0.4 .INDENT 0.0 .IP \(bu 2 افزودن پشتیبانی از اتصالات lxc و lxd در ansible .UNINDENT .SS 3.0.3 .INDENT 0.0 .IP \(bu 2 رفع مشکل تجزیه RequestTTY توسط paramiko از پیکربندی‌های ssh .IP \(bu 2 بازگرداندن کلید \(dqgroups\(dq از تابع ansible.get_variables() جهت حفظ سازگاری عقبرو با نسخه‌های 2.X از testinfra .UNINDENT.SS 3.0.2 .INDENT 0.0 .IP \(bu 2 رفع مشکل تطبیق ansible بدون inventory با \(dqlocalhost\(dq .IP \(bu 2 رفع مشکل پشتیبانی از ansible 2.8 بدون inventory .IP \(bu 2 رفع مشکلی در ansible/paramiko که پیکربندی میزبان‌ها را از ~/.ssh/config نمی‌خواند .IP \(bu 2 امکان ارسال \-\-ssh\-config و \-\-ssh\-identity\-file به اتصال ansible .UNINDENT .SS 3.0.1 .INDENT 0.0 .IP \(bu 2 رفع مشکل تجزیه آدرس‌های ipv6 برای backendهای paramiko، ssh و ansible. .IP \(bu 2 رفع مشکل فراخوانی \-\-connection=ansible هنگامی که هیچ میزبانی ارائه نشده است .UNINDENT .SS 3.0.0 .INDENT 0.0 .IP \(bu 2 یک backend جدید برای ansible که پشتیبانی از ansible 2.8 و مشکل مجوز (license) را برطرف می‌کند. برای جزئیات به \% مراجعه کنید. این تغییر باعث می‌شود ansible از backendهای بومی testinfra استفاده کند و تنها برای اتصالات local، ssh یا docker کارایی دارد. اگر انواع اتصال دیگری دارید یا با مشکلی مواجه شدید، لطفاً یک گزارش باگ در \% باز کنید .IP \(bu 2 پشتیبانی از Windows بهبود یافته است. ماژول \(dqpackage\(dq با Chocolatey مدیریت می‌شود و پشتیبانی از ماژول \(dquser\(dq نیز فراهم شده است. .UNINDENT .SS 2.1.0 .INDENT 0.0 .IP \(bu 2 docker: متد کلاسی (classmethod) جدید get_containers() .IP \(bu 2 socket: رفع مشکل تجزیه آدرس‌های ipv6 در نسخه‌های جدید ss .IP \(bu 2 service: بازگشت systemd به sysv هنگامی که \(dqsystemctl is\-active\(dq کار نمی‌کند .UNINDENT .SS 2.0.0 .INDENT 0.0 .IP \(bu 2 افزودن ماژول addr، مورد استفاده برای آزمایش اتصال شبکه .IP \(bu 2 حذف دستور منسوخ‌شدهٔ \(dqtestinfra\(dq؛ باید به جای آن از \(dqpy.test\(dq استفاده کنید .IP \(bu 2 حذف fixtureهای سطح بالای منسوخ‌شده؛ در عوض از طریق fixture با نام \(dqhost\(dq به آن‌ها دسترسی پیدا کنید. .IP \(bu 2 حذف پشتیبانی از ansible <= 2.4 .UNINDENT .SS 1.19.0 .INDENT 0.0 .IP \(bu 2 افزودن ماژول docker .IP \(bu 2 رفع مشکل سازگاری با pytest 4 .UNINDENT .SS 1.18.0 .INDENT 0.0 .IP \(bu 2 امکان استفاده از کدگذاری درصدی (urlencode) برای نویسه‌ها در مشخصات میزبان \(dquser:pass@host\(dq (#387) .IP \(bu 2 رفع مشکل ثبت گزارش دوگانه (double logging) هم از pytest و هم از testinfra .IP \(bu 2 حذف پشتیبانی از python 2.6 .IP \(bu 2 امکان پیکربندی مهلت زمانی (timeout) برای backend نوع winrm .UNINDENT .SS 1.17.0 .INDENT 0.0 .IP \(bu 2 افزودن پشتیبانی از کاربر \(dqbecome\(dq در ماژول ansible .IP \(bu 2 افزودن مشخصه failed/succeeded به خروجی run() .UNINDENT .SS 1.16.0 .INDENT 0.0 .IP \(bu 2 packaging: استفاده از setuptools_scm به جای pbr .IP \(bu 2 iptables: افزودن پشتیبانی از ip6tables .IP \(bu 2 sysctl: یافتن sysctl خارج از PATH (/sbin) .UNINDENT .SS 1.15.0 .INDENT 0.0 .IP \(bu 2 رفع مشکل یافتن دستورهای ss و netstat در مسیرهای \(dqsbin\(dq برای Centos (359) .IP \(bu 2 افزودن یک راهکار موقت (workaround) برای \% .IP \(bu 2 مدیریت وضعیت \(dqstarting\(dq برای ماژول Service در Alpine linux .IP \(bu 2 رفع مشکل گزینه‌های no_ssl و no_verify_ssl برای backend نوع WinRM .UNINDENT .SS 1.14.1 .INDENT 0.0 .IP \(bu 2 رفع مشکل ترتیب اجرای آزمون‌های چندمیزبانی (#347)، پس‌رفت معرفی‌شده در 1.13.1 .IP \(bu 2 رفع مشکل Socket در میزبان‌های OpenBSD (#338) .UNINDENT .SS 1.14.0 .INDENT 0.0 .IP \(bu 2 افزودن یک backend جدید برای lxc .IP \(bu 2 Socket: رفع مشکل is_listening برای سوکت‌های unix .IP \(bu 2 افزودن پشتیبانی از namespace و container برای backend نوع kubernetes .IP \(bu 2 افزودن یک حافظه موقت (cache) از inventoryهای تجزیه‌شدهٔ ansible برای backend نوع ansible .IP \(bu 2 Service: رفع مشکل تشخیص سرویس در میزبان‌های Centos 6 .IP \(bu 2 File: پیاده‌سازی مقایسه فایل با مسیرهای متنی (string paths) .UNINDENT .SS 1.13.1 .INDENT 0.0 .IP \(bu 2 package: رفع رفتار is_installed و version برای بسته‌های نصب‌نشده (#321 و #326) .IP \(bu 2 ansible: استفاده از ترتیب آزمون پیش‌بینی‌پذیر هنگام استفاده از pytest\-xdist برای رفع خطاهای تصادفی در گردآوری آزمون‌ها (#316) .UNINDENT.SS 1.13.0 .INDENT 0.0 .IP \(bu 2 socket: رفع مشکل در شناسایی سوکت‌های شنونده udp (#311) .IP \(bu 2 ssh backend: افزودن پشتیبانی از GSSAPI .UNINDENT .SS 1.12.0 .INDENT 0.0 .IP \(bu 2 ansible: رفع مشکلات سازگاری با ansible 2.5 .IP \(bu 2 pip: رفع مشکلات سازگاری با pip 10 (#299) .UNINDENT .SS 1.11.1 .INDENT 0.0 .IP \(bu 2 Socket: رفع خطا در نسخه‌های قدیمی ss که فاقد گزینه \-\-no\-header هستند (#293) .UNINDENT .SS 1.11.0 .INDENT 0.0 .IP \(bu 2 رفع گزارش نادرست خطا هنگام استفاده از ماژول ansible بدون ansible backend (#288) .IP \(bu 2 Socket: افزودن یک پیاده‌سازی جدید با استفاده از ss به جای netstat (#124) .IP \(bu 2 افزودن پشتیبانی از service، process و systeminfo برای Alpine (#283) .UNINDENT .SS 1.10.1 .INDENT 0.0 .IP \(bu 2 اصلاح ()get_variables برای ansible>=2.0,<2.4 (#274) .IP \(bu 2 Paramiko: استفاده از تنظیمات RequireTTY در صورت تعیین شدن در SSHConfig مشخص‌شده (#247) .UNINDENT .SS 1.10.0 .INDENT 0.0 .IP \(bu 2 ماژول جدید iptables .UNINDENT .SS 1.9.1 .INDENT 0.0 .IP \(bu 2 رفع مشکل اجرای testinfra درون مجموعه‌ای که از doctest استفاده می‌کند (#268) .IP \(bu 2 Service: افزودن متد ()is_valid برای systemd .IP \(bu 2 رفع مشکل ()file.linked_to برای Mac OS .UNINDENT .SS 1.9.0 .INDENT 0.0 .IP \(bu 2 Interface: امکان یافتن دستور \(aqip\(aq خارج از PATH .IP \(bu 2 رفع مشکل گزینه \-\-nagios با python 3 .UNINDENT .SS 1.8.0 .INDENT 0.0 .IP \(bu 2 منسوخ شدن دستور testinfra (در نسخه 2.0 حذف خواهد شد)، به جای آن از py.test استفاده کنید #135 .IP \(bu 2 مدیریت گزینه \-\-nagios هنگام استفاده از دستور py.test .UNINDENT .SS 1.7.1 .INDENT 0.0 .IP \(bu 2 پشتیبانی از ansible 2.4 (#249) .UNINDENT .SS 1.7.0 .INDENT 0.0 .IP \(bu 2 Salt: امکان تعیین پوشه پیکربندی (#230) .IP \(bu 2 افزودن یک WinRM backend .IP \(bu 2 Socket: امکان مدیریت کلاینت‌های ipv4 توسط سوکت‌های ipv6 (#234) .IP \(bu 2 Service: بهبود شناسایی upstart (#243) .UNINDENT .SS 1.6.5 .INDENT 0.0 .IP \(bu 2 Service: افزودن پشتیبانی از ()is_enabled برای OpenBSD .IP \(bu 2 افزودن گزینه فایل هویت ssh برای backendهای paramiko و ssh .IP \(bu 2 گسترش تیلدا (~) به پوشه خانگی کاربر برای گزینه‌های ssh\-config، ssh\-identity\-file و ansible\-inventory .UNINDENT .SS 1.6.4 .INDENT 0.0 .IP \(bu 2 Service: امکان یافتن دستور \(aqservice\(aq خارج از $PATH #211 .IP \(bu 2 اصلاحات مستندات .UNINDENT .SS 1.6.3 .INDENT 0.0 .IP \(bu 2 رفع هشدار منسوخ‌شدگی ناخواسته هنگام اجرای آزمون‌ها با pytest 3.1 #204 .UNINDENT .SS 1.6.2 .INDENT 0.0 .IP \(bu 2 رفع مشکل بسته wheel برای نسخه 1.6.1 .UNINDENT .SS 1.6.1 .INDENT 0.0 .IP \(bu 2 پشتیبانی از ansible 2.3 همراه با python 3 (#197) .UNINDENT .SS 1.6.0 .INDENT 0.0 .IP \(bu 2 فیکسچر جدید \(aqhost\(aq به عنوان جایگزینی برای تمامی فیکسچرهای دیگر. ببینید \% (سایر فیکسچرها منسوخ شده‌اند و در نگارش 2.0 حذف خواهند شد). .UNINDENT .SS 1.5.5 .INDENT 0.0 .IP \(bu 2 backends: رفع مشکل ansible backend با ansible >= 2.3 (#195) .UNINDENT.SS 1.5.4 .INDENT 0.0 .IP \(bu 2 backends: بازگشت به کدگذاری UTF\-8 در صورت ASCII بودن کدگذاری سیستم. .IP \(bu 2 Service: رفع باگ is_running() در سیستم‌های مبتنی بر Upstart. .UNINDENT .SS 1.5.3 .INDENT 0.0 .IP \(bu 2 Sudo: بازگردانی دستور backend در صورت بروز استثناها. .UNINDENT .SS 1.5.2 .INDENT 0.0 .IP \(bu 2 اعمال become_user هنگام استفاده از بک‌اند ansible. .UNINDENT .SS 1.5.1 .INDENT 0.0 .IP \(bu 2 افزودن وابستگی به importlib در python 2.6. .UNINDENT .SS 1.5.0 .INDENT 0.0 .IP \(bu 2 بک‌اند جدید kubectl. .IP \(bu 2 Command: حذف نویسه‌های carriage return و خطوط جدید در check_output (#164). .IP \(bu 2 Package: بهبود در دریافت version() و release() در rpm. .IP \(bu 2 User: افزودن فیلد gecos (توضیحات) (#155). .UNINDENT .SS 1.4.5 .INDENT 0.0 .IP \(bu 2 SystemInfo: تشخیص نام مستعار (codename) از VERSION_CODENAME در /etc/os\-release (پشتیبان در صورت نصب نبودن lsb_release). .IP \(bu 2 Package: افزودن ویژگی release برای سیستم‌های مبتنی بر rpm. .UNINDENT .SS فراخوانی (Invocation) .SS آزمودن چندین میزبان (Test multiple hosts) .sp به‌طور پیش‌فرض Testinfra آزمون‌ها را روی ماشین محلی اجرا می‌کند، اما می‌توانید با استفاده از paramiko \% (یک پیاده‌سازی ssh در پایتون)، سیستم‌های راه دور را نیز بیازمایید: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pip install paramiko $ pytest \-v \-\-hosts=localhost,root@webserver:2222 test_myinfra.py ====================== test session starts ====================== platform linux \-\- Python 2.7.3 \-\- py\-1.4.26 \-\- pytest\-2.6.4 plugins: testinfra collected 3 items test_myinfra.py::test_passwd_file[localhost] PASSED test_myinfra.py::test_nginx_is_installed[localhost] PASSED test_myinfra.py::test_nginx_running_and_enabled[localhost] PASSED test_myinfra.py::test_passwd_file[root@webserver:2222] PASSED test_myinfra.py::test_nginx_is_installed[root@webserver:2222] PASSED test_myinfra.py::test_nginx_running_and_enabled[root@webserver:2222] PASSED =================== 6 passed in 8.49 seconds ==================== .EE .UNINDENT .UNINDENT .sp همچنین می‌توانید میزبان‌ها را به ازای هر ماژول آزمون مشخص کنید: .INDENT 0.0 .INDENT 3.5 .sp .EX testinfra_hosts = [\(dqlocalhost\(dq, \(dqroot@webserver:2222\(dq] def test_foo(host): [....] .EE .UNINDENT .UNINDENT .SS اجرای موازی (Parallel execution) .sp اگر آزمون‌های زیادی دارید، می‌توانید از افزونه‌ی pytest\-xdist \% برای اجرای آزمون‌ها با استفاده از چندین پردازه استفاده کنید: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pip install pytest\-xdist # Launch tests using 3 processes $ pytest \-n 3 \-v \-\-host=web1,web2,web3,web4,web5,web6 test_myinfra.py .EE .UNINDENT .UNINDENT .SS فراخوانی پیشرفته (Advanced invocation) .INDENT 0.0 .INDENT 3.5 .sp .EX # Test recursively all test files (starting with \(gatest_\(ga) in current directory $ pytest # Filter function/hosts with pytest \-k option $ pytest \-\-hosts=webserver,dnsserver \-k webserver \-k nginx .EE .UNINDENT .UNINDENT .sp برای موارد استفاده و قابلیت‌های بیشتر، مستندات Pytest \% را ببینید. .SS بک‌اندهای اتصال (Connection backends) .sp ابزار Testinfra همراه با چندین بک‌اند اتصال برای اجرای دستورهای راه دور ارائه می‌شود. .sp هنگام نصب، باید بک‌اندهای مورد نیاز خود را به عنوان \fBextras\fP انتخاب کنید تا از برآورده شدن وابستگی‌های پایتون اطمینان حاصل شود (توجه داشته باشید که ممکن است همچنان به ابزارهای بسته‌بندی‌شده‌ی مختلف سیستمی نیاز باشد). برای نمونه: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pip install pytest\-testinfra[ansible,salt] .EE .UNINDENT .UNINDENT .sp برای تمام بک‌اندها، دستورها می‌توانند با گزینه \fB\-\-sudo\fP با دسترسی مدیر سیستم (superuser) یا با گزینه \fB\-\-sudo\-user\fP به عنوان یک کاربر مشخص اجرا شوند..SS "مشخصات عمومی میزبان (General Host specification)" .sp پارامتر \fB\-\-hosts\fP در Testinfra برای تعیین میزبان‌های هدف جهت اجرای آزمون‌ها استفاده می‌شود. .sp شما می‌توانید با جدا کردن هر هدف با ویرگول (comma)، چندین میزبان را مشخص کنید؛ این قابلیت به شما اجازه می‌دهد آزمون‌ها را با استفاده از بک‌اندهای مختلف در محیط‌ها یا ماشین‌های گوناگون اجرا نمایید. .sp فیلدهای user، password و port اختیاری هستند و بسته به الزامات احراز هویت و اتصال شما، انعطاف‌پذیری لازم را فراهم می‌کنند. .sp لطفاً جزئیات مربوط به هر یک از بک‌اندها را نیز مطالعه کنید، زیرا نحوه مدیریت مشخصات میزبان در هر بک‌اند اندکی متفاوت است. .sp \fBنحو (Syntax):\fP .INDENT 0.0 .INDENT 3.5 .sp .EX \-\-hosts=://:@: .EE .UNINDENT .UNINDENT .sp \fBاجزا:\fP .INDENT 0.0 .IP \(bu 2 \fB\fP: نوع بک‌اند مورد استفاده (مانند ssh، docker، paramiko، local) .IP \(bu 2 \fB\fP: نام کاربری برای احراز هویت (اختیاری) .IP \(bu 2 \fB\fP: گذرواژه برای احراز هویت (اختیاری) .IP \(bu 2 \fB\fP: نام میزبان یا نشانی IP هدف .IP \(bu 2 \fB\fP: شماره درگاه (پورت) هدف (اختیاری) .UNINDENT .sp نویسه‌های خاص (مانند \(dq:\(dq) در فیلدهای user و password باید طبق استاندارد RFC 3986 درصدکدگذاری (percent\-encoded) شوند. این کار در Python با استفاده از \fBurllib.parse.quote()\fP امکان‌پذیر است. .sp برای نمونه: .INDENT 0.0 .INDENT 3.5 .sp .EX import urllib.parse user = urllib.parse.quote(\(aquser:name\(aq) password = urllib.parse.quote(\(aqp@ssw:rd\(aq) host = \(aqhostname\(aq port = 22 host_spec = f\(dqssh://{user}:{password}@{host}:{port}\(dq print(host_spec) .EE .UNINDENT .UNINDENT .sp این کار تضمین می‌کند که هرگونه نویسه خاص به درستی کدگذاری شده و رشته اتصال معتبر باشد. .sp \fBمثال‌ها:\fP .sp بک‌اند SSH با مشخصات کامل: .INDENT 0.0 .INDENT 3.5 .sp .EX testinfra \-\-hosts=ssh://user:password@hostname:22 .EE .UNINDENT .UNINDENT .sp بک‌اند Docker: .INDENT 0.0 .INDENT 3.5 .sp .EX testinfra \-\-hosts=docker://container_id .EE .UNINDENT .UNINDENT .sp ترکیب چند بک‌اند: .INDENT 0.0 .INDENT 3.5 .sp .EX testinfra \-\-hosts=ssh://user:password@hostname:22,docker://container_id,local:// .EE .UNINDENT .UNINDENT .SS local .sp این بک‌اند پیش‌فرض در صورت عدم تعیین میزبان است (خواه از طریق \fB\-\-hosts\fP یا در ماژول‌ها). دستورها به صورت محلی در یک زیرپردازش (subprocess) تحت کاربر جاری اجرا می‌شوند: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-sudo test_myinfra.py .EE .UNINDENT .UNINDENT .SS paramiko .sp این بک‌اند پیش‌فرض در صورت ارائه فهرستی از میزبان‌ها است. Paramiko \% یک پیاده‌سازی از پروتکل SSHv2 در Python است. Testinfra از شما گذرواژه‌ای درخواست نخواهد کرد، بنابراین باید بتوانید بدون نیاز به گذرواژه (با استفاده از کلیدهای بدون گذرواژه یا \fBssh\-agent\fP) متصل شوید. .sp می‌توانید یک ssh\-config جایگزین مشخص کنید: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-ssh\-config=/path/to/ssh_config \-\-hosts=server .EE .UNINDENT .UNINDENT .SS docker .sp بک‌اند Docker می‌تواند برای آزمودن کانتینرهای \fIدر حال اجرای\fP Docker استفاده شود. این بک‌اند از دستور docker exec \% استفاده می‌کند: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-hosts=\(aqdocker://[user@]container_id_or_name\(aq .EE .UNINDENT .UNINDENT .sp همچنین مثال Test Docker images \%<#\:test-docker-images> را ببینید..SS podman .sp از backend مربوط به Podman می‌توان برای آزمودن کانتینرهای \fIدر حال اجرای\fP Podman استفاده کرد. این backend از دستور podman exec \% استفاده می‌کند: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-hosts=\(aqpodman://[user@]container_id_or_name\(aq .EE .UNINDENT .UNINDENT .SS ssh .sp این یک backend خالص SSH است که از دستور \fBssh\fP استفاده می‌کند. مثال: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-hosts=\(aqssh://server\(aq $ pytest \-\-ssh\-config=/path/to/ssh_config \-\-hosts=\(aqssh://server\(aq $ pytest \-\-ssh\-identity\-file=/path/to/key \-\-hosts=\(aqssh://server\(aq $ pytest \-\-hosts=\(aqssh://server?timeout=60&controlpersist=120\(aq $ pytest \-\-hosts=\(aqssh://server\(aq \-\-ssh\-extra\-args=\(aq\-o StrictHostKeyChecking=no\(aq .EE .UNINDENT .UNINDENT .sp به‌طور پیش‌فرض مهلت زمانی (timeout) روی ۱۰ ثانیه و ControlPersist روی ۶۰ ثانیه تنظیم شده است. می‌توانید با ارسال \fIcontrolpersist=0\fP به گزینه‌ها، اتصال پایدار را غیرفعال کنید. .SS salt .sp موتور backend مربوط به salt از رابط برنامه‌نویسی پایتون کلاینت salt به آدرس \% استفاده می‌کند و می‌توان آن را از سرور salt\-master به کار برد: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-hosts=\(aqsalt://*\(aq $ pytest \-\-hosts=\(aqsalt://minion1,salt://minion2\(aq $ pytest \-\-hosts=\(aqsalt://web*\(aq $ pytest \-\-hosts=\(aqsalt://G@os:Debian\(aq .EE .UNINDENT .UNINDENT .sp ابزار Testinfra از کانال ارتباطی salt برای اجرای دستورها استفاده خواهد کرد. .sp میزبان‌ها را می‌توان با استفاده از \fIglob\fP و تطبیق‌دهنده‌های ترکیبی \%\& انتخاب کرد. .SS ansible .sp از موجودی‌های (inventories) انسیبل می‌توان برای توصیف این‌که Testinfra باید از چه میزبان‌هایی استفاده کند و نحوهٔ اتصال به آن‌ها با استفاده از backend انسیبل در Testinfra، بهره برد. .sp برای استفاده از backend انسیبل، پیشوند \fBansible://\fP را به گزینهٔ \fB\-\-hosts\fP اضافه کنید؛ مانند: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-hosts=\(aqansible://all\(aq # tests all inventory hosts $ pytest \-\-hosts=\(aqansible://host1,ansible://host2\(aq $ pytest \-\-hosts=\(aqansible://web*\(aq .EE .UNINDENT .UNINDENT .sp یک inventory را می‌توان با گزینهٔ \fB\-\-ansible\-inventory\fP مشخص کرد، در غیر این صورت از مقدار پیش‌فرض (\fB/etc/ansible/hosts\fP) استفاده می‌شود. .sp مقدار \fBansible_connection\fP در inventory شما برای تعیین این‌که کدام backend برای هر میزبان به کار رود استفاده خواهد شد: مقادیر پشتیبانی‌شده عبارتند از \fBlocal\fP، \fBssh\fP، \fBparamiko\fP و \fBdocker\fP. سایر اتصال‌ها (یا اگر از گزینهٔ \fB\-\-force\-ansible\fP استفاده کنید) باعث می‌شوند testinfra تمام دستورها را از طریق خود Ansible اجرا کند، که به مراتب کندتر از سایر backendها است: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-force\-ansible \-\-hosts=\(aqansible://all\(aq $ pytest \-\-hosts=\(aqansible://host?force_ansible=True\(aq .EE .UNINDENT .UNINDENT .sp به‌طور پیش‌فرض، backend اتصال Ansible ابتدا برای احراز هویت تلاش می‌کند از \fBansible_ssh_private_key_file\fP و \fBansible_private_key_file\fP استفاده کند، سپس در صورت نیاز به متغیرهای \fBansible_user\fP همراه با \fBansible_ssh_pass\fP رجوع می‌کند (هر دو مورد نیاز هستند)، و در نهایت به عنوان آخرین راهکار به پیکربندی SSH میزبان خودتان متوسل می‌شود. .sp این رفتار را می‌توان با مشخص کردن گزینهٔ \fB\-\-ssh\-identity\-file\fP یا گزینهٔ \fB\-\-ssh\-config\fP بازنویسی کرد. .sp در نهایت، این متغیرهای محیطی پشتیبانی می‌شوند و به متغیر متناظرشان در ansible ارسال خواهند شد (مستندات Ansible را ببینید): .sp \% .sp \% .INDENT 0.0 .IP \(bu 2 \fBANSIBLE_REMOTE_USER\fP .IP \(bu 2 \fBANSIBLE_SSH_EXTRA_ARGS\fP .IP \(bu 2 \fBANSIBLE_SSH_COMMON_ARGS\fP .IP \(bu 2 \fBANSIBLE_REMOTE_PORT\fP .IP \(bu 2 \fBANSIBLE_BECOME_USER\fP .IP \(bu 2 \fBANSIBLE_BECOME\fP .UNINDENT .SS kubectl .sp از backend مربوط به kubectl می‌توان برای آزمودن کانتینرهای در حال اجرا در Kubernetes استفاده کرد. این backend از دستور kubectl exec \% بهره می‌برد و از اتصال به یک کانتینر مشخص درون یک pod و استفاده از یک namespace مشخص پشتیبانی می‌کند: .INDENT 0.0 .INDENT 3.5 .sp .EX # will use the default namespace and default container $ pytest \-\-hosts=\(aqkubectl://mypod\-a1b2c3\(aq # specify container name and namespace $ pytest \-\-hosts=\(aqkubectl://somepod\-2536ab?container=nginx&namespace=web\(aq # specify the kubeconfig context to use $ pytest \-\-hosts=\(aqkubectl://somepod\-2536ab?context=k8s\-cluster\-a&container=nginx\(aq # you can specify kubeconfig either from KUBECONFIG environment variable # or when working with multiple configuration with the \(dqkubeconfig\(dq option $ pytest \-\-hosts=\(aqkubectl://somepod\-123?kubeconfig=/path/kubeconfig,kubectl://otherpod\-123?kubeconfig=/other/kubeconfig\(aq .EE .UNINDENT .UNINDENT.SS openshift .sp پشتانهٔ openshift می‌تواند برای آزمایش کانتینرهای در حال اجرا در OpenShift به کار رود. این پشتانه از دستور oc exec \% استفاده کرده و از اتصال به نام یک کانتینر مشخص درون یک pod و استفاده از یک namespace معین پشتیبانی می‌کند: .INDENT 0.0 .INDENT 3.5 .sp .EX # will use the default namespace and default container $ pytest \-\-hosts=\(aqopenshift://mypod\-a1b2c3\(aq # specify container name and namespace $ pytest \-\-hosts=\(aqopenshift://somepod\-2536ab?container=nginx&namespace=web\(aq # you can specify kubeconfig either from KUBECONFIG environment variable # or when working with multiple configuration with the \(dqkubeconfig\(dq option $ pytest \-\-hosts=\(aqopenshift://somepod\-123?kubeconfig=/path/kubeconfig,openshift://otherpod\-123?kubeconfig=/other/kubeconfig\(aq .EE .UNINDENT .UNINDENT .SS winrm .sp پشتانهٔ winrm از pywinrm \% استفاده می‌کند: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-hosts=\(aqwinrm://Administrator:Password@127.0.0.1\(aq $ pytest \-\-hosts=\(aqwinrm://vagrant@127.0.0.1:2200?no_ssl=true&no_verify_ssl=true\(aq .EE .UNINDENT .UNINDENT .sp مهلت زمانی پیش‌فرض خواندن و عملیات pywinrm را می‌توان با استفاده از آرگومان‌های پرسمان \fBread_timeout_sec\fP و \fBoperation_timeout_sec\fP بازنویسی کرد: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-hosts=\(aqwinrm://vagrant@127.0.0.1:2200?read_timeout_sec=120&operation_timeout_sec=100\(aq .EE .UNINDENT .UNINDENT .SS LXC/LXD .sp پشتانهٔ LXC می‌تواند برای آزمایش کانتینرهای \fIدر حال اجرای\fP LXC یا LXD به کار رود. این پشتانه از دستور lxc exec \% استفاده می‌کند: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-\-hosts=\(aqlxc://container_name\(aq .EE .UNINDENT .UNINDENT .SS ماژول‌ها (Modules) .sp ماژول‌های Testinfra از طریق فیکسچر \fIhost\fP \% ارائه می‌شوند؛ آن را به عنوان آرگومان تابع آزمون خود اعلان کنید تا درون آن در دسترس قرار گیرد. .INDENT 0.0 .INDENT 3.5 .sp .EX def test_foo(host): # [...] .EE .UNINDENT .UNINDENT .SS host .INDENT 0.0 .TP .B class Host(backend: BaseBackend) .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .TP .B ansible کلاس \fBtestinfra.modules.ansible.Ansible\fP .UNINDENT .INDENT 0.0 .TP .B addr کلاس \fBtestinfra.modules.addr.Addr\fP .UNINDENT .INDENT 0.0 .TP .B blockdevice کلاس \fBtestinfra.modules.blockdevice.BlockDevice\fP .UNINDENT .INDENT 0.0 .TP .B docker کلاس \fBtestinfra.modules.docker.Docker\fP .UNINDENT .INDENT 0.0 .TP .B environment کلاس \fBtestinfra.modules.environment.Environment\fP .UNINDENT .INDENT 0.0 .TP .B file کلاس \fBtestinfra.modules.file.File\fP .UNINDENT .INDENT 0.0 .TP .B group کلاس \fBtestinfra.modules.group.Group\fP .UNINDENT .INDENT 0.0 .TP .B interface کلاس \fBtestinfra.modules.interface.Interface\fP .UNINDENT .INDENT 0.0 .TP .B iptables کلاس \fBtestinfra.modules.iptables.Iptables\fP .UNINDENT .INDENT 0.0 .TP .B mount_point کلاس \fBtestinfra.modules.mountpoint.MountPoint\fP .UNINDENT .INDENT 0.0 .TP .B package کلاس \fBtestinfra.modules.package.Package\fP .UNINDENT .INDENT 0.0 .TP .B pip کلاس \fBtestinfra.modules.pip.Pip\fP .UNINDENT .INDENT 0.0 .TP .B podman کلاس \fBtestinfra.modules.podman.Podman\fP .UNINDENT .INDENT 0.0 .TP .B process کلاس \fBtestinfra.modules.process.Process\fP .UNINDENT .INDENT 0.0 .TP .B puppet_resource کلاس \fBtestinfra.modules.puppet.PuppetResource\fP .UNINDENT .INDENT 0.0 .TP .B facter کلاس \fBtestinfra.modules.puppet.Facter\fP .UNINDENT .INDENT 0.0 .TP .B salt کلاس \fBtestinfra.modules.salt.Salt\fP .UNINDENT .INDENT 0.0 .TP .B service کلاس \fBtestinfra.modules.service.Service\fP .UNINDENT .INDENT 0.0 .TP .B socket کلاس \fBtestinfra.modules.socket.Socket\fP .UNINDENT .INDENT 0.0 .TP .B sudo کلاس \fBtestinfra.modules.sudo.Sudo\fP .UNINDENT .INDENT 0.0 .TP .B supervisor کلاس \fBtestinfra.modules.supervisor.Supervisor\fP .UNINDENT .INDENT 0.0 .TP .B sysctl کلاس \fBtestinfra.modules.sysctl.Sysctl\fP .UNINDENT .INDENT 0.0 .TP .B system_info کلاس \fBtestinfra.modules.systeminfo.SystemInfo\fP .UNINDENT .INDENT 0.0 .TP .B user کلاس \fBtestinfra.modules.user.User\fP .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B property has_command_v: bool در صورتی که \fIcommand \-v\fP در دسترس باشد، مقدار True را برمی‌گرداند .UNINDENT .INDENT 7.0.TP .B exists(command: str) -> bool اگر دستور داده‌شده در $PATH وجود داشته باشد، مقدار True را برمی‌گرداند. .UNINDENT .INDENT 7.0 .TP .B find_command(command: str, extrapaths: Iterable[str] = (\(aq/sbin\(aq, \(aq/usr/sbin\(aq)) -> str مسیر دستور داده‌شده را برمی‌گرداند .sp در صورت پیدا نشدن دستور، خطای ValueError ایجاد می‌کند .UNINDENT .INDENT 7.0 .TP .B run(command: str, *args: str, **kwargs: Any) -> CommandResult \%<#\:testinfra\:.backend\:.base\:.CommandResult> دستور داده‌شده را اجرا کرده و rc (وضعیت خروج)، stdout و stderr را برمی‌گرداند .sp .EX >>> cmd = host.run(\(dqls \-l /etc/passwd\(dq) >>> cmd.rc 0 >>> cmd.stdout \(aq\-rw\-r\-\-r\-\- 1 root root 1790 Feb 11 00:28 /etc/passwd\en\(aq >>> cmd.stderr \(aq\(aq >>> cmd.succeeded True >>> cmd.failed False .EE .sp روش مناسب: همواره از نقل‌قول آرگومان‌های شل (shell quoting) استفاده کنید تا از تزریق شل (shell injection) جلوگیری شود .sp .EX >>> cmd = host.run(\(dqls \-l \-\- %s\(dq, \(dq/;echo inject\(dq) CommandResult( rc=2, stdout=\(aq\(aq, stderr=( \(aqls: cannot access /;echo inject: No such file or directory\en\(aq), command=\(dqls \-l \(aq/;echo inject\(aq\(dq) .EE .UNINDENT .INDENT 7.0 .TP .B run_expect(expected: list[int], command: str, *args: str, **kwargs: Any) -> CommandResult \%<#\:testinfra\:.backend\:.base\:.CommandResult> دستور را اجرا کرده و بررسی می‌کند که آیا وضعیت خروج موردانتظار را برمی‌گرداند یا خیر .INDENT 7.0 .TP .B پارامترها \fBexpected\fP \-\- فهرستی از وضعیت‌های خروج موردانتظار .TP .B خطاهای صادرشده AssertionError .UNINDENT .UNINDENT .INDENT 7.0 .TP .B run_test(command: str, *args: str, **kwargs: Any) -> CommandResult \%<#\:testinfra\:.backend\:.base\:.CommandResult> دستور را اجرا کرده و بررسی می‌کند که آیا وضعیت خروج 0 یا 1 را برمی‌گرداند یا خیر .INDENT 7.0 .TP .B خطاهای صادرشده AssertionError .UNINDENT .UNINDENT .INDENT 7.0 .TP .B check_output(command: str, *args: str, **kwargs: Any) -> str دریافت stdout دستوری که با موفقیت اجرا شده است .INDENT 7.0 .TP .B مقادیر بازگشتی خروجی stdout بدون نویسه خط جدید پایانی .TP .B خطاهای صادرشده AssertionError .UNINDENT .UNINDENT .INDENT 7.0 .TP .B classmethod get_host(hostspec: str, **kwargs: Any) -> Host \%<#\:testinfra\:.host\:.Host> یک نمونه از Host را از \fIhostspec\fP برمی‌گرداند .sp مقدار \fIhostspec\fP باید به این صورت باشد: \fI://?param1=value1¶m2=value2\fP .sp پارامترها را می‌توان در \fI**kwargs\fP نیز ارسال کرد (به عنوان مثال، get_host(\(dqlocal://\(dq, sudo=True) معادل get_host(\(dqlocal://?sudo=true\(dq) است) .sp مثال‌ها: .INDENT 7.0 .INDENT 3.5 .sp .EX >>> get_host(\(dqlocal://\(dq, sudo=True) >>> get_host(\(dqparamiko://user@host\(dq, ssh_config=\(dq/path/my_ssh_config\(dq) >>> get_host(\(dqansible://all?ansible_inventory=/etc/ansible/inventory\(dq) .EE .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS Ansible .INDENT 0.0 .TP .B class Ansible(module_name, module_args=None, check=True) توابع ماژول‌های Ansible را اجرا می‌کند .sp این ماژول تنها با بک‌اند اتصال ansible \%<#\:ansible-connection-backend> در دسترس است. .sp حالت بررسی (Check mode) \% به طور پیش‌فرض فعال است، می‌توانید آن را با \fIcheck=False\fP غیرفعال کنید\&. .sp قابلیت Become \% به طور پیش‌فرض \fIFalse\fP است. می‌توانید آن را با \fIbecome=True\fP فعال کنید\&. .sp آرگومان‌های Ansible که به inventory یا ارتباط Ansible (که هر دو توسط testinfra مدیریت می‌شوند) مربوط نیستند نیز از طریق آرگومان‌های کلیدواژه‌ای پذیرفته می‌شوند: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBbecome_method\fP \fIstr\fP sudo، su، doas و غیره. .IP \(bu 2 \fBbecome_user\fP \fIstr\fP تبدیل به این کاربر. .IP \(bu 2 \fBdiff\fP \fIbool\fP: هنگام تغییر فایل‌ها و قالب‌های (کوچک)، تفاوت‌ها را در آن فایل‌ها نشان می‌دهد. .IP \(bu 2 \fBextra_vars\fP \fIdict\fP به صورت یک رشته JSON سریالایز شده و به Ansible فرستاده می‌شود. .IP \(bu 2 \fBone_line\fP \fIbool\fP: فشرده‌سازی خروجی. .IP \(bu 2 \fBuser\fP \fIstr\fP اتصال به عنوان این کاربر. .IP \(bu 2 \fBverbose\fP \fIint\fP سطح جزئیات خروجی (verbosity). .UNINDENT .UNINDENT .UNINDENT .sp .EX >>> host.ansible(\(dqapt\(dq, \(dqname=nginx state=present\(dq)[\(dqchanged\(dq] False >>> host.ansible(\(dqapt\(dq, \(dqname=nginx state=present\(dq, become=True)[\(dqchanged\(dq] False >>> host.ansible(\(dqcommand\(dq, \(dqecho foo\(dq, check=False)[\(dqstdout\(dq] \(aqfoo\(aq >>> host.ansible(\(dqsetup\(dq)[\(dqansible_facts\(dq][\(dqansible_lsb\(dq][\(dqcodename\(dq] \(aqjessie\(aq >>> host.ansible(\(dqfile\(dq, \(dqpath=/etc/passwd\(dq)[\(dqmode\(dq] \(aq0640\(aq >>> host.ansible( \&... \(dqcommand\(dq, \&... \(dqid \-\-user \-\-name\(dq, \&... check=False, \&... become=True, \&... become_user=\(dqhttp\(dq, \&... )[\(dqstdout\(dq] \(aqhttp\(aq >>> host.ansible( \&... \(dqapt\(dq, \&... \(dqname={{ packages }}\(dq, \&... check=False, \&... extra_vars={\(dqpackages\(dq: [\(dqneovim\(dq, \(dqvim\(dq]}, \&... ) # Installs neovim and vim. .EE .INDENT 7.0 .TP .B exception AnsibleException(result) استثنایی که هنگام وقوع خطا در یک فراخوانی ansible ایجاد می‌شود .sp نتیجهٔ حاصل از ansible از طریق مشخصهٔ \fBresult\fP قابل دسترسی است .sp .EX >>> try: \&... host.ansible(\(dqcommand\(dq, \(dqecho foo\(dq) \&... except host.ansible.AnsibleException as exc: \&... assert exc.result[\(aqfailed\(aq] is True \&... assert exc.result[\(aqmsg\(aq] == \(aqSkipped. You might want to try check=False\(aq # noqa .EE .UNINDENT .INDENT 7.0 .TP .B get_variables() یک dict از متغیرهای ansible را برمی‌گرداند .sp .EX >>> host.ansible.get_variables() { \(aqinventory_hostname\(aq: \(aqlocalhost\(aq, \(aqgroup_names\(aq: [\(aqungrouped\(aq], \(aqfoo\(aq: \(aqbar\(aq, } .EE .UNINDENT .UNINDENT.SS Addr .INDENT 0.0 .TP .B class Addr(name) بررسی نشانی دوردست .sp مثال: .sp .EX >>> google = host.addr(\(dqgoogle.com\(dq) >>> google.is_resolvable True >>> \(aq173.194.32.225\(aq in google.ipv4_addresses True >>> google.is_reachable True >>> google.port(443).is_reachable True >>> google.port(666).is_reachable False .EE .sp همچنین می‌تواند درون یک فضای نام شبکه \%\& استفاده شود. .sp .EX >>> localhost = host.addr(\(dqlocalhost\(dq, \(dqns1\(dq) >>> localhost.is_resolvable True .EE .sp فضاهای نام شبکه تنها زمانی قابل استفاده هستند که دستور ip \% در دسترس باشد؛ زیرا در این صورت، ماژول از ip\-netns \% به عنوان پیشوند دستور استفاده می‌کند. در غیر این صورت، خطای NotImplementedError برانگیخته خواهد شد. .INDENT 7.0 .TP .B property name بازگرداندن نام میزبان .UNINDENT .INDENT 7.0 .TP .B property namespace بازگرداندن فضای نام شبکه .UNINDENT .INDENT 7.0 .TP .B property namespace_exists بررسی اینکه آیا فضای نام شبکه وجود دارد یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_resolvable بازگرداندن اینکه آیا نشانی قابل تحلیل و تفکیک (resolve) است یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_reachable بازگرداندن اینکه آیا نشانی در دسترس است یا خیر .UNINDENT .INDENT 7.0 .TP .B property ip_addresses بازگرداندن نشانی‌های IP میزبان .UNINDENT .INDENT 7.0 .TP .B property ipv4_addresses بازگرداندن نشانی‌های IPv4 میزبان .UNINDENT .INDENT 7.0 .TP .B property ipv6_addresses بازگرداندن نشانی‌های IPv6 میزبان .UNINDENT .INDENT 7.0 .TP .B port(port) بازگرداندن جفت نشانی\-درگاه .UNINDENT .UNINDENT .SS BlockDevice .INDENT 0.0 .TP .B class BlockDevice(name) اطلاعات مربوط به دستگاه بلوکی. .sp باید با sudo یا توسط کاربر ریشه (root) استفاده شود. .sp اگر دستگاه یک دستگاه بلوکی نباشد، خطای RuntimeError رخ می‌دهد. .INDENT 7.0 .TP .B property is_partition در صورتی که دستگاه یک پارتیشن باشد True بازمی‌گرداند. .sp .EX >>> host.block_device(\(dq/dev/sda1\(dq).is_partition True .EE .sp .EX >>> host.block_device(\(dq/dev/sda\(dq).is_partition False .EE .UNINDENT .INDENT 7.0 .TP .B property size اندازه دستگاه را بر حسب بایت بازمی‌گرداند. .sp .EX >>> host.block_device(\(dq/dev/sda1\(dq).size 512110190592 .EE .UNINDENT .INDENT 7.0 .TP .B property sector_size اندازه سکتور دستگاه را بر حسب بایت بازمی‌گرداند. .sp .EX >>> host.block_device(\(dq/dev/sda1\(dq).sector_size 512 .EE .UNINDENT .INDENT 7.0 .TP .B property block_size اندازه بلوک دستگاه را بر حسب بایت بازمی‌گرداند. .sp .EX >>> host.block_device(\(dq/dev/sda\(dq).block_size 4096 .EE .UNINDENT .INDENT 7.0 .TP .B property start_sector سکتور آغازین دستگاه را بر روی دستگاه زیرین بازمی‌گرداند. .INDENT 7.0 .INDENT 3.5 معمولاً این مقدار برای دستگاه‌های کامل صفر و برای پارتیشن‌ها غیرصفر است. .UNINDENT .UNINDENT .sp .EX >>> host.block_device(\(dq/dev/sda1\(dq).start_sector 2048 .EE .sp .EX >>> host.block_device(\(dq/dev/md0\(dq).start_sector 0 .EE .UNINDENT .INDENT 7.0 .TP .B property is_writable اگر دستگاه قابل نوشتن باشد (وضعیت RO نداشته باشد) True بازمی‌گرداند. .sp .EX >>> host.block_device(\(dq/dev/sda\(dq).is_writable True .EE .sp .EX >>> host.block_device(\(dq/dev/loop1\(dq).is_writable False .EE .UNINDENT .INDENT 7.0 .TP .B property ra مقدار Read Ahead دستگاه را بر حسب سکتورهای ۵۱۲ بایتی بازمی‌گرداند. .sp .EX >>> host.block_device(\(dq/dev/sda\(dq).ra 256 .EE .UNINDENT .UNINDENT.SS Docker .INDENT 0.0 .TP .B class Docker(name) بررسی و آزمودن کانتینرهای docker در حال اجرا بر روی سیستم. .sp مثال: .sp .EX >>> nginx = host.docker(\(dqapp_nginx\(dq) >>> nginx.is_running True >>> nginx.id \(aq7e67dc7495ca8f451d346b775890bdc0fb561ecdc97b68fb59ff2f77b509a8fe\(aq >>> nginx.name \(aqapp_nginx\(aq .EE .INDENT 7.0 .TP .B classmethod client_version() نسخه کلاینت Docker .UNINDENT .INDENT 7.0 .TP .B classmethod server_version() نسخه سرور Docker .UNINDENT .INDENT 7.0 .TP .B classmethod version(format=None) نسخه Docker \% با یک قالب اختیاری (Go template). .sp .EX >>> host.docker.version() Client: Docker Engine \- Community \&... >>> host.docker.version(\(dq{{.Client.Context}}\(dq)) default .EE .UNINDENT .INDENT 7.0 .TP .B classmethod get_containers(**filters) بازگرداندن فهرستی از کانتینرها .sp به‌طور پیش‌فرض، فهرستی از تمامی کانتینرها شامل کانتینرهای غیر در حال اجرا بازگردانده می‌شود. .sp فیلتر کردن می‌تواند با استفاده از کلیدهای فیلتر تعریف‌شده در \% انجام شود. .sp اعمال چندین فیلتر برای یک کلید مشخص، با تعیین فهرستی از رشته‌ها به‌عنوان مقدار امکان‌پذیر است. .sp .EX >>> host.docker.get_containers() [, , ] # Get all running containers >>> host.docker.get_containers(status=\(dqrunning\(dq) [] # Get containers named \(dqnginx\(dq >>> host.docker.get_containers(name=\(dqnginx\(dq) [] # Get containers named \(dqnginx\(dq or \(dqredis\(dq >>> host.docker.get_containers(name=[\(dqnginx\(dq, \(dqredis\(dq]) [, ] .EE .UNINDENT .UNINDENT .SS Environment .INDENT 0.0 .TP .B class Environment(name) دریافت متغیرهای محیطی .sp مثال: .sp .EX >>> host.environment() { \(dqEDITOR\(dq: \(dqvim\(dq, \(dqSHELL\(dq: \(dq/bin/bash\(dq, [...] } .EE .UNINDENT .SS File .INDENT 0.0 .TP .B class File(path) بررسی ویژگی‌های گوناگون فایل .INDENT 7.0 .TP .B property exists بررسی وجود داشتن فایل .sp .EX >>> host.file(\(dq/etc/passwd\(dq).exists True >>> host.file(\(dq/nonexistent\(dq).exists False .EE .UNINDENT .INDENT 7.0 .TP .B property is_file بررسی اینکه آیا مسیر داده‌شده یک فایل معمولی (regular file) است یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_directory بررسی اینکه آیا مسیر داده‌شده وجود دارد و یک دایرکتوری است یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_executable بررسی اینکه آیا مسیر داده‌شده وجود دارد و مجوز اجرا به آن اعطا شده است یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_pipe بررسی اینکه آیا مسیر داده‌شده وجود دارد و یک لوله (pipe) است یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_socket بررسی اینکه آیا مسیر داده‌شده وجود دارد و یک سوکت (socket) است یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_symlink بررسی اینکه آیا مسیر داده‌شده وجود دارد و یک پیوند نمادین (symlink) است یا خیر .UNINDENT .INDENT 7.0 .TP .B property linked_to حل پیوند نمادین و مشخص کردن مقصد آن .sp .EX >>> host.file(\(dq/var/lock\(dq).linked_to \(aq/run/lock\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property user بازگرداندن مالک فایل به‌صورت رشته .sp .EX >>> host.file(\(dq/etc/passwd\(dq).user \(aqroot\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property uid بازگرداندن شناسه کاربری (UID) فایل به‌صورت یک عدد صحیح .sp .EX >>> host.file(\(dq/etc/passwd\(dq).uid 0 .EE .UNINDENT .INDENT 7.0 .TP .B property group بازگرداندن نام گروه فایل به‌صورت رشته .UNINDENT .INDENT 7.0 .TP .B property gid بازگرداندن شناسه گروه (GID) فایل به‌صورت یک عدد صحیح .UNINDENT .INDENT 7.0 .TP .B property mode بازگرداندن حالت دسترسی فایل (file mode) به‌صورت عدد صحیح در مبنای هشت (octal) .sp .EX >>> host.file(\(dq/etc/shadow\(dq).mode 416 # Oo640 octal >>> host.file(\(dq/etc/shadow\(dq).mode == 0o640 True >>> oct(host.file(\(dq/etc/shadow\(dq).mode) == \(aq0o640\(aq True .EE .sp همچنین می‌توانید از مقادیر ثابت حالت دسترسی فایل در کتابخانهٔ stat \% برای بررسی حالت فایل استفاده کنید. .sp .EX >>> import stat >>> host.file(\(dq/etc/shadow\(dq).mode == stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP True .EE .UNINDENT .INDENT 7.0 .TP .B contains(pattern) بررسی محتوای فایل برای یافتن الگو (pattern) .sp این متد از grep استفاده کرده و در نتیجه از قواعد نحو عبارات منظم (regex) در grep پیروی می‌کند. .UNINDENT .INDENT 7.0.TP .B property md5sum محاسبه چکیده پیام MD5 محتوای فایل .UNINDENT .INDENT 7.0 .TP .B property sha256sum محاسبه چکیده پیام SHA256 محتوای فایل .UNINDENT .INDENT 7.0 .TP .B property content بازگرداندن محتوای فایل به صورت بایت .sp .EX >>> host.file(\(dq/tmp/foo\(dq).content b\(aqcaf\exc3\exa9\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property content_string بازگرداندن محتوای فایل به صورت رشته .sp .EX >>> host.file(\(dq/tmp/foo\(dq).content_string \(aqcafé\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property mtime بازگرداندن زمان آخرین تغییر به عنوان یک شیء datetime.datetime .sp .EX >>> host.file(\(dq/etc/passwd\(dq).mtime datetime.datetime(2015, 3, 15, 20, 25, 40) .EE .UNINDENT .INDENT 7.0 .TP .B property size بازگرداندن اندازه فایل بر حسب بایت .UNINDENT .INDENT 7.0 .TP .B listdir() بازگرداندن فهرست موارد موجود در دایرکتوری .sp .EX >>> host.file(\(dq/tmp\(dq).listdir() [\(aqfoo_file\(aq, \(aqbar_dir\(aq] .EE .UNINDENT .UNINDENT .SS Group .INDENT 0.0 .TP .B class Group(name) بررسی گروه یونیکس .INDENT 7.0 .TP .B property exists بررسی وجود داشتن گروه .sp .EX >>> host.group(\(dqwheel\(dq).exists True >>> host.group(\(dqnosuchgroup\(dq).exists False .EE .UNINDENT .INDENT 7.0 .TP .B property get_all_groups بازگرداندن فهرستی از نام‌های گروه‌های محلی و دوردست .sp .EX >>> host.group(\(dqanyname\(dq).get_all_groups [\(dqroot\(dq, \(dqwheel\(dq, \(dqman\(dq, \(dqtty\(dq, <...>] .EE .UNINDENT .INDENT 7.0 .TP .B property get_local_groups بازگرداندن فهرستی از نام‌های گروه‌های محلی .sp .EX >>> host.group(\(dqanyname\(dq).get_local_groups [\(dqroot\(dq, \(dqwheel\(dq, \(dqman\(dq, \(dqtty\(dq, <...>] .EE .UNINDENT .INDENT 7.0 .TP .B property gid .UNINDENT .INDENT 7.0 .TP .B property members بازگرداندن تمام کاربرانی که عضو این گروه هستند. .UNINDENT .UNINDENT .SS Interface .INDENT 0.0 .TP .B class Interface(name, family=None) بررسی رابط‌های شبکه .sp .EX >>> host.interface(\(dqeth0\(dq).exists True .EE .sp به صورت اختیاری، می‌توان خانواده پروتکل مورد استفاده را مشخص کرد. .sp .EX >>> host.interface(\(dqeth0\(dq, \(dqinet6\(dq).addresses [\(aqfe80::e291:f5ff:fe98:6b8c\(aq] .EE .INDENT 7.0 .TP .B property exists .UNINDENT .INDENT 7.0 .TP .B property speed .UNINDENT .INDENT 7.0 .TP .B property addresses بازگرداندن آدرس‌های ipv4 و ipv6 روی رابط .sp .EX >>> host.interface(\(dqeth0\(dq).addresses [\(aq192.168.31.254\(aq, \(aq192.168.31.252\(aq, \(aqfe80::e291:f5ff:fe98:6b8c\(aq] .EE .UNINDENT .INDENT 7.0 .TP .B property link بازگرداندن ویژگی‌های پیوند (link) مرتبط با رابط. .sp .EX >>> host.interface(\(dqlo\(dq).link {\(aqaddress\(aq: \(aq00:00:00:00:00:00\(aq, \(aqbroadcast\(aq: \(aq00:00:00:00:00:00\(aq, \(aqflags\(aq: [\(aqLOOPBACK\(aq, \(aqUP\(aq, \(aqLOWER_UP\(aq], \(aqgroup\(aq: \(aqdefault\(aq, \(aqifindex\(aq: 1, \(aqifname\(aq: \(aqlo\(aq, \(aqlink_type\(aq: \(aqloopback\(aq, \(aqlinkmode\(aq: \(aqDEFAULT\(aq, \(aqmtu\(aq: 65536, \(aqoperstate\(aq: \(aqUNKNOWN\(aq, \(aqqdisc\(aq: \(aqnoqueue\(aq, \(aqtxqlen\(aq: 1000} .EE .UNINDENT .INDENT 7.0 .TP .B routes(scope=None) بازگرداندن مسیرهای مرتبط با رابط، با امکان پالایش اختیاری بر اساس دامنه scope (\(dqhost\(dq، \(dqlink\(dq یا \(dqglobal\(dq). .sp .EX >>> host.interface(\(dqeth0\(dq).routes() [{\(aqdst\(aq: \(aqdefault\(aq, \(aqflags\(aq: [], \(aqgateway\(aq: \(aq192.0.2.1\(aq, \(aqmetric\(aq: 3003, \(aqprefsrc\(aq: \(aq192.0.2.5\(aq, \(aqprotocol\(aq: \(aqdhcp\(aq}, {\(aqdst\(aq: \(aq192.0.2.0/24\(aq, \(aqflags\(aq: [], \(aqmetric\(aq: 3003, \(aqprefsrc\(aq: \(aq192.0.2.5\(aq, \(aqprotocol\(aq: \(aqdhcp\(aq, \(aqscope\(aq: \(aqlink\(aq}] .EE .UNINDENT .INDENT 7.0 .TP .B classmethod names() بازگرداندن نام تمامی رابط‌ها. .sp .EX >>> host.interface.names() [\(aqlo\(aq, \(aqtunl0\(aq, \(aqip6tnl0\(aq, \(aqeth0\(aq] .EE .UNINDENT .INDENT 7.0 .TP .B classmethod default(family=None) بازگرداندن رابط مورد استفاده برای مسیر پیش‌فرض (default route). .sp .EX >>> host.interface.default() .EE .sp به صورت اختیاری، می‌توان خانواده پروتکل مورد استفاده را مشخص کرد. .sp .EX >>> host.interface.default(\(dqinet6\(dq) None .EE .UNINDENT .UNINDENT.SS Iptables .INDENT 0.0 .TP .B class Iptables بررسی وجود قانون در iptables .INDENT 7.0 .TP .B rules(table=\(aqfilter\(aq, chain=None, version=4) فهرستی از قوانین iptables را برمی‌گرداند .INDENT 7.0 .INDENT 3.5 بر اساس خروجی دستور \fIiptables \-t TABLE \-S CHAIN\fP .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B به صورت اختیاری آرگومان‌های زیر را می‌پذیرد: .INDENT 7.0 .IP \(bu 2 table: پیش‌فرض \fIfilter\fP است .IP \(bu 2 chain: پیش‌فرض تمامی زنجیره‌ها است .IP \(bu 2 version: پیش‌فرض 4 (iptables)، به صورت اختیاری 6 (ip6tables) .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .sp .EX >>> host.iptables.rules() [ \(aq\-P INPUT ACCEPT\(aq, \(aq\-P FORWARD ACCEPT\(aq, \(aq\-P OUTPUT ACCEPT\(aq, \(aq\-A INPUT \-i lo \-j ACCEPT\(aq, \(aq\-A INPUT \-j REJECT\(aq \(aq\-A FORWARD \-j REJECT\(aq ] >>> host.iptables.rules(\(dqnat\(dq, \(dqINPUT\(dq) [\(aq\-P PREROUTING ACCEPT\(aq] .EE .UNINDENT .UNINDENT .SS MountPoint .INDENT 0.0 .TP .B class MountPoint(path) بررسی نقاط اتصال (Mount Points) .INDENT 7.0 .TP .B property exists در صورت وجود نقطه اتصال مقدار True برمی‌گرداند .sp .EX >>> host.mount_point(\(dq/\(dq).exists True .EE .sp .EX >>> host.mount_point(\(dq/not/a/mountpoint\(dq).exists False .EE .UNINDENT .INDENT 7.0 .TP .B property filesystem نوع سیستم‌فایل مرتبط را برمی‌گرداند .sp .EX >>> host.mount_point(\(dq/\(dq).filesystem \(aqext4\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property device دستگاه مرتبط را برمی‌گرداند .sp .EX >>> host.mount_point(\(dq/\(dq).device \(aq/dev/sda1\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property options فهرستی از گزینه‌هایی که نقطه اتصال با آن‌ها ایجاد شده است را برمی‌گرداند .sp .EX >>> host.mount_point(\(dq/\(dq).options [\(aqrw\(aq, \(aqrelatime\(aq, \(aqdata=ordered\(aq] .EE .UNINDENT .INDENT 7.0 .TP .B classmethod get_mountpoints() فهرستی از نمونه‌های MountPoint را برمی‌گرداند .sp .EX >>> host.mount_point.get_mountpoints() [, ] .EE .UNINDENT .UNINDENT .SS Package .INDENT 0.0 .TP .B class Package(name) بررسی وضعیت و نسخه بسته‌ها .INDENT 7.0 .TP .B property is_installed بررسی اینکه آیا بسته نصب شده است یا خیر .sp .EX >>> host.package(\(dqnginx\(dq).is_installed True .EE .sp سیستم‌های بسته پشتیبانی‌شده: .INDENT 7.0 .IP \(bu 2 apk (Alpine) .IP \(bu 2 apt (Debian, Ubuntu, ...) .IP \(bu 2 brew (macOS) .IP \(bu 2 pacman (Arch, Manjaro ) .IP \(bu 2 pkg (FreeBSD) .IP \(bu 2 pkg_info (NetBSD) .IP \(bu 2 pkg_info (OpenBSD) .IP \(bu 2 rpm (RHEL, RockyLinux, Fedora, ...) .UNINDENT .UNINDENT .INDENT 7.0 .TP .B property release اطلاعات مشخصه انتشار (release) را از نسخه بسته برمی‌گرداند .sp .EX >>> host.package(\(dqnginx\(dq).release \(aq1.el6\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property version نسخه بسته را آن‌طور که توسط سیستم بسته بازگردانده شده برمی‌گرداند .sp .EX >>> host.package(\(dqnginx\(dq).version \(aq1.2.1\-2.2+wheezy3\(aq .EE .UNINDENT .UNINDENT.SS Pip .INDENT 0.0 .TP .B class Pip(name, pip_path=\(aqpip\(aq) آزمودن مدیر بسته و بسته‌های pip .INDENT 7.0 .TP .B property is_installed بررسی نصب بودن بسته .sp .EX >>> host.package(\(dqpip\(dq).is_installed True .EE .UNINDENT .INDENT 7.0 .TP .B property version بازگرداندن نسخه‌ی بسته همان‌طور که توسط pip گزارش شده است .sp .EX >>> host.package(\(dqpip\(dq).version \(aq18.1\(aq .EE .UNINDENT .INDENT 7.0 .TP .B classmethod check(pip_path=\(aqpip\(aq) بررسی سازگار بودن وابستگی‌های بسته‌های نصب‌شده. .sp .EX >>> cmd = host.pip.check() >>> cmd.rc 0 >>> cmd.stdout No broken requirements found. .EE .sp تنها در صورتی قابل استفاده است که دستور pip check \% در دسترس باشد، برای نسخه‌های pip >= 9.0.0 \%\&. .UNINDENT .INDENT 7.0 .TP .B classmethod get_packages(pip_path=\(aqpip\(aq) دریافت تمام بسته‌های نصب‌شده و نسخه‌های آن‌ها به شکلی که توسط \fIpip list\fP بازگردانده می‌شوند: .sp .EX >>> host.pip.get_packages(pip_path=\(aq~/venv/website/bin/pip\(aq) {\(aqDjango\(aq: {\(aqversion\(aq: \(aq1.10.2\(aq}, \(aqmywebsite\(aq: {\(aqversion\(aq: \(aq1.0a3\(aq, \(aqpath\(aq: \(aq/srv/website\(aq}, \(aqpsycopg2\(aq: {\(aqversion\(aq: \(aq2.6.2\(aq}} .EE .UNINDENT .INDENT 7.0 .TP .B classmethod get_outdated_packages(pip_path=\(aqpip\(aq) دریافت تمام بسته‌های قدیمی به همراه نسخه‌ی فعلی و آخرین نسخه .sp .EX >>> host.pip.get_outdated_packages( \&... pip_path=\(aq~/venv/website/bin/pip\(aq) {\(aqDjango\(aq: {\(aqcurrent\(aq: \(aq1.10.2\(aq, \(aqlatest\(aq: \(aq1.10.3\(aq}} .EE .UNINDENT .UNINDENT .SS Podman .INDENT 0.0 .TP .B class Podman(name) آزمودن کانتینرهای podman در حال اجرا روی سیستم. .sp مثال: .sp .EX >>> nginx = host.podman(\(dqapp_nginx\(dq) >>> nginx.is_running True >>> nginx.id \(aq7e67dc7495ca8f451d346b775890bdc0fb561ecdc97b68fb59ff2f77b509a8fe\(aq >>> nginx.name \(aqapp_nginx\(aq .EE .INDENT 7.0 .TP .B classmethod get_containers(**filters) بازگرداندن فهرستی از کانتینرها .sp به‌طور پیش‌فرض فهرستی از همه‌ی کانتینرها، شامل کانتینرهای غیر در حال اجرا را بازمی‌گرداند. .sp فیلتر کردن می‌تواند با استفاده از کلیدهای فیلتر تعریف‌شده در podman\-ps(1) انجام شود. .sp اعمال فیلترهای چندگانه برای یک کلید مشخص، با ارائه‌ی فهرستی از رشته‌ها به عنوان مقدار انجام می‌شود. .sp .EX >>> host.podman.get_containers() [, , ] # Get all running containers >>> host.podman.get_containers(status=\(dqrunning\(dq) [] # Get containers named \(dqnginx\(dq >>> host.podman.get_containers(name=\(dqnginx\(dq) [] # Get containers named \(dqnginx\(dq or \(dqredis\(dq >>> host.podman.get_containers(name=[\(dqnginx\(dq, \(dqredis\(dq]) [, ] .EE .UNINDENT .UNINDENT .SS Process .INDENT 0.0 .TP .B class Process آزمودن مشخصه‌های فرآیندها .sp فرآیندها با استفاده از \fBfilter()\fP یا \fBget()\fP انتخاب می‌شوند؛ نام مشخصه‌ها در صفحه‌ی راهنمای ps(1) شرح داده شده است: \%\&. .sp .EX >>> master = host.process.get(user=\(dqroot\(dq, comm=\(dqnginx\(dq) # Here is the master nginx process (running as root) >>> master.args \(aqnginx: master process /usr/sbin/nginx \-g daemon on; master_process on;\(aq # Here are the worker processes (Parent PID = master PID) >>> workers = host.process.filter(ppid=master.pid) >>> len(workers) 4 # Nginx don\(aqt eat memory >>> sum([w.pmem for w in workers]) 0.8 # But php does ! >>> sum([p.pmem for p in host.process.filter(comm=\(dqphp5\-fpm\(dq)]) 19.2 .EE .INDENT 7.0 .TP .B filter(**filters) دریافت فهرستی از فرآیندهای منطبق .sp .EX >>> host.process.filter(user=\(dqroot\(dq, comm=\(dqzsh\(dq) [, , ...] .EE .UNINDENT .INDENT 7.0 .TP .B get(**filters) دریافت یک فرآیند منطبق .sp اگر فرآیندی یافت نشود یا چندین فرآیند با فیلترها مطابقت داشته باشند، \fBRuntimeError\fP ایجاد می‌شود. .UNINDENT .UNINDENT.SS PuppetResource .INDENT 0.0 .TP .B class PuppetResource(type, name=None) دریافت منابع puppet .sp برای دریافت فهرستی از انواع در دسترس، دستور \fBpuppet resource \-\-types\fP را اجرا کنید. .sp .EX >>> host.puppet_resource(\(dquser\(dq, \(dqwww\-data\(dq) { \(aqwww\-data\(aq: { \(aqensure\(aq: \(aqpresent\(aq, \(aqcomment\(aq: \(aqwww\-data\(aq, \(aqgid\(aq: \(aq33\(aq, \(aqhome\(aq: \(aq/var/www\(aq, \(aqshell\(aq: \(aq/usr/sbin/nologin\(aq, \(aquid\(aq: \(aq33\(aq, }, } .EE .UNINDENT .SS Facter .INDENT 0.0 .TP .B class Facter(*facts) دریافت واقعیت‌ها (facts) با facter \% .sp .EX >>> host.facter() { \(dqoperatingsystem\(dq: \(dqDebian\(dq, \(dqkernel\(dq: \(dqlinux\(dq, [...] } >>> host.facter(\(dqkernelversion\(dq, \(dqis_virtual\(dq) { \(dqkernelversion\(dq: \(dq3.16.0\(dq, \(dqis_virtual\(dq: \(dqfalse\(dq } .EE .UNINDENT .SS Salt .INDENT 0.0 .TP .B class Salt(function, args=None, local=False, config=None) اجرای توابع ماژول salt .sp .EX >>> host.salt(\(dqpkg.version\(dq, \(dqnginx\(dq) \(aq1.6.2\-5\(aq >>> host.salt(\(dqpkg.version\(dq, [\(dqnginx\(dq, \(dqphp5\-fpm\(dq]) {\(aqnginx\(aq: \(aq1.6.2\-5\(aq, \(aqphp5\-fpm\(aq: \(aq5.6.7+dfsg\-1\(aq} >>> host.salt(\(dqgrains.item\(dq, [\(dqosarch\(dq, \(dqmem_total\(dq, \(dqnum_cpus\(dq]) {\(aqosarch\(aq: \(aqamd64\(aq, \(aqnum_cpus\(aq: 4, \(aqmem_total\(aq: 15520} .EE .sp برای دریافت فهرست کاملی از توابع، دستور \fBsalt\-call sys.doc\fP را اجرا کنید .UNINDENT .SS Service .INDENT 0.0 .TP .B class Service(name) آزمودن سرویس‌ها .sp پیاده‌سازی‌ها: .INDENT 7.0 .IP \(bu 2 لینوکس: شناسایی Systemd، Upstart یا OpenRC، و بازگشت به SysV در صورت عدم شناسایی .IP \(bu 2 فری‌بی‌اس‌دی: service(1) .IP \(bu 2 اوپن‌بی‌اس‌دی: \fB/etc/rc.d/$name check\fP برای \fBis_running\fP \fBrcctl ls on\fP برای \fBis_enabled\fP (تنها در OpenBSD >= 5.8) .IP \(bu 2 نت‌بی‌اس‌دی: \fB/etc/rc.d/$name onestatus\fP برای \fBis_running\fP (\fBis_enabled\fP هنوز پیاده‌سازی نشده است) .UNINDENT .INDENT 7.0 .TP .B property exists بررسی اینکه آیا سرویس وجود دارد یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_running بررسی اینکه آیا سرویس در حال اجرا است یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_enabled بررسی اینکه آیا سرویس فعال (enabled) است یا خیر .UNINDENT .INDENT 7.0 .TP .B property is_valid بررسی اینکه آیا سرویس معتبر است یا خیر .sp این متد تنها در پیاده‌سازی systemd موجود است، و در سایر پیاده‌سازی‌ها خطای \fBNotImplementedError\fP ایجاد خواهد کرد .UNINDENT .INDENT 7.0 .TP .B property is_masked بررسی اینکه آیا سرویس ماسک (masked) شده است یا خیر .sp این متد تنها در پیاده‌سازی systemd موجود است، و در سایر پیاده‌سازی‌ها خطای \fBNotImplementedError\fP ایجاد خواهد کرد .UNINDENT .INDENT 7.0 .TP .B property systemd_properties ویژگی‌های سرویس (unit). .sp ویژگی‌های سرویس را به عنوان یک \fIdict\fP برمی‌گرداند، ویژگی‌های خالی بازگردانده نمی‌شوند. .sp .EX >>> ntp = host.service(\(dqntp\(dq) >>> ntp.systemd_properties[\(dqFragmentPath\(dq] \(aq/lib/systemd/system/ntp.service\(aq .EE .sp این متد تنها در پیاده‌سازی systemd موجود است، و در سایر پیاده‌سازی‌ها خطای \fBNotImplementedError\fP ایجاد خواهد کرد .sp نکته: بر اساس systemctl show \% .UNINDENT .UNINDENT.SS Socket .INDENT 0.0 .TP .B class Socket(socketspec) بررسی سوکت‌های در حال شنود tcp/udp و unix .sp \fBsocketspec\fP باید به صورت \fB://:\fP مشخص شود .sp این ماژول نیازمند وجود دستور \fBnetstat\fP روی میزبان هدف است. .sp مثال: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 سوکت‌های Unix: \fBunix:///var/run/docker.sock\fP .IP \(bu 2 تمام سوکت‌های tcp پروتکل‌های ipv4 و ipv6 روی پورت 22: \fBtcp://22\fP .IP \(bu 2 تمام سوکت‌های ipv4 روی پورت 22: \fBtcp://0.0.0.0:22\fP .IP \(bu 2 تمام سوکت‌های ipv6 روی پورت 22: \fBtcp://:::22\fP .IP \(bu 2 سوکت udp روی 127.0.0.1 پورت 69: \fBudp://127.0.0.1:69\fP .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B property is_listening بررسی اینکه آیا سوکت در حال شنود است یا خیر .sp .EX >>> host.socket(\(dqunix:///var/run/docker.sock\(dq).is_listening False >>> # This HTTP server listen on all ipv4 addresses but not on ipv6 >>> host.socket(\(dqtcp://0.0.0.0:80\(dq).is_listening True >>> host.socket(\(dqtcp://:::80\(dq).is_listening False >>> host.socket(\(dqtcp://80\(dq).is_listening False .EE .sp \fBنکته:\fP .INDENT 7.0 .INDENT 3.5 اگر میزبانی برای سوکت‌های udp و tcp مشخص نکنید، سوکت در صورتی و تنها در صورتی در وضعیت شنود خواهد بود که سوکت روی \fBهر دو\fP نشانی‌های ipv4 و ipv6 در حال شنود باشد (یعنی 0.0.0.0 و ::) .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B property clients: list[tuple[str, int] | None] فهرستی از کلاینت‌های متصل به یک سوکت در حال شنود را برمی‌گرداند .sp برای سوکت‌های tcp و udp فهرستی از جفت‌های (نشانی، پورت) برگردانده می‌شود. برای سوکت‌های unix فهرستی از None برگردانده می‌شود (بنابراین می‌توانید از ()len برای شمارش کلاینت‌ها استفاده کنید). .sp .EX >>> host.socket(\(dqtcp://22\(dq).clients [(\(aq2001:db8:0:1\(aq, 44298), (\(aq192.168.31.254\(aq, 34866)] >>> host.socket(\(dqunix:///var/run/docker.sock\(dq) [None, None, None] .EE .UNINDENT .INDENT 7.0 .TP .B classmethod get_listening_sockets() فهرستی از تمام سوکت‌های در حال شنود را برمی‌گرداند .sp .EX >>> host.socket.get_listening_sockets() [\(aqtcp://0.0.0.0:22\(aq, \(aqtcp://:::22\(aq, \(aqunix:///run/systemd/private\(aq, ...] .EE .UNINDENT .UNINDENT .SS Sudo .INDENT 0.0 .TP .B class Sudo(user=None) ماژول Sudo اجازه می‌دهد بخش مشخصی از کد تحت کاربری دیگر اجرا شود. .sp این ماژول به عنوان یک مدیر زمینه (context manager) استفاده می‌شود و می‌تواند به صورت تو در تو باشد. .sp .EX >>> Command.check_output(\(dqwhoami\(dq) \(aqphil\(aq >>> with host.sudo(): \&... host.check_output(\(dqwhoami\(dq) \&... with host.sudo(\(dqwww\-data\(dq): \&... host.check_output(\(dqwhoami\(dq) \&... \(aqroot\(aq \(aqwww\-data\(aq .EE .UNINDENT .SS Supervisor .INDENT 0.0 .TP .B class Supervisor(name, supervisorctl_path=\(aqsupervisorctl\(aq, supervisorctl_conf=None, _attrs_cache=None) بررسی سرویس‌های مدیریت‌شده با supervisor .sp .EX >>> gunicorn = host.supervisor(\(dqgunicorn\(dq) >>> gunicorn.status \(aqRUNNING\(aq >>> gunicorn.is_running True >>> gunicorn.pid 4242 .EE .sp مسیری که supervisorctl و فایل پیکربندی آن در آن قرار دارند می‌تواند مشخص شود. .sp .EX >>> gunicorn = host.supervisor(\(dqgunicorn\(dq, \(dq/usr/bin/supervisorctl\(dq, \(dq/etc/supervisor/supervisord.conf\(dq) >>> gunicorn.status \(aqRUNNING\(aq .EE .INDENT 7.0 .TP .B property is_running در صورتی که سرویس مدیریت‌شده در وضعیت RUNNING باشد، True را برمی‌گرداند .UNINDENT .INDENT 7.0 .TP .B property status وضعیت سرویس مدیریت‌شده را برمی‌گرداند .sp وضعیت می‌تواند STOPPED، STARTING، RUNNING، BACKOFF، STOPPING، EXITED، FATAL یا UNKNOWN باشد. .sp ببینید: \% .UNINDENT .INDENT 7.0 .TP .B property pid شناسه فرایند (pid به صورت int) سرویس مدیریت‌شده را برمی‌گرداند .UNINDENT .INDENT 7.0 .TP .B classmethod get_services(supervisorctl_path=\(aqsupervisorctl\(aq, supervisorctl_conf=None) فهرستی از سرویس‌های در حال اجرا تحت supervisor را برمی‌گرداند .sp .EX >>> host.supervisor.get_services() [ ] .EE .sp مسیری که supervisorctl و فایل پیکربندی آن در آن قرار دارند می‌تواند مشخص شود. .sp .EX >>> host.supervisor.get_services(\(dq/usr/bin/supervisorctl\(dq, \(dq/etc/supervisor/supervisord.conf\(dq) [ ] .EE .UNINDENT .UNINDENT.SS Sysctl .INDENT 0.0 .TP .B class Sysctl(name) بررسی پارامترهای هسته .sp .EX >>> host.sysctl(\(dqkernel.osrelease\(dq) \(dq3.16.0\-4\-amd64\(dq >>> host.sysctl(\(dqvm.dirty_ratio\(dq) 20 .EE .UNINDENT .SS SystemInfo .INDENT 0.0 .TP .B class SystemInfo بازگرداندن اطلاعات سیستم .INDENT 7.0 .TP .B property type نوع سیستم‌عامل .sp .EX >>> host.system_info.type \(aqlinux\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property distribution نام توزیع .sp .EX >>> host.system_info.distribution \(aqdebian\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property release شماره انتشار توزیع .sp .EX >>> host.system_info.release \(aq10.2\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property codename اسم رمز انتشار .sp .EX >>> host.system_info.codename \(aqbullseye\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property arch معماری میزبان .sp .EX >>> host.system_info.arch \(aqx86_64\(aq .EE .UNINDENT .UNINDENT .SS User .INDENT 0.0 .TP .B class User(name=None) بررسی کاربران یونیکس .sp اگر name مشخص نشود، کاربر جاری بررسی می‌شود .INDENT 7.0 .TP .B property name بازگرداندن نام کاربر .UNINDENT .INDENT 7.0 .TP .B property exists بررسی وجود کاربر .sp .EX >>> host.user(\(dqroot\(dq).exists True >>> host.user(\(dqnosuchuser\(dq).exists False .EE .UNINDENT .INDENT 7.0 .TP .B property uid بازگرداندن شناسه کاربر .UNINDENT .INDENT 7.0 .TP .B property gid بازگرداندن شناسه گروه مؤثر .UNINDENT .INDENT 7.0 .TP .B property group بازگرداندن نام گروه مؤثر .UNINDENT .INDENT 7.0 .TP .B property gids بازگرداندن فهرست شناسه‌های گروه‌های کاربر .UNINDENT .INDENT 7.0 .TP .B property groups بازگرداندن فهرست نام‌های گروه‌های کاربر .UNINDENT .INDENT 7.0 .TP .B property home بازگرداندن دایرکتوری خانگی کاربر .UNINDENT .INDENT 7.0 .TP .B property shell بازگرداندن پوسته ورود کاربر .UNINDENT .INDENT 7.0 .TP .B property password بازگرداندن گذرواژه رمزگذاری‌شده کاربر .UNINDENT .INDENT 7.0 .TP .B property password_max_days بازگرداندن حداکثر تعداد روزهای بین تغییر گذرواژه .UNINDENT .INDENT 7.0 .TP .B property password_min_days بازگرداندن حداقل تعداد روزهای بین تغییر گذرواژه .UNINDENT .INDENT 7.0 .TP .B property gecos بازگرداندن فیلد توضیحات/gecos کاربر .UNINDENT .INDENT 7.0 .TP .B property expiration_date بازگرداندن تاریخ انقضای حساب کاربری .sp .EX >>> host.user(\(dqphil\(dq).expiration_date datetime.datetime(2020, 1, 1, 0, 0) >>> host.user(\(dqroot\(dq).expiration_date None .EE .UNINDENT .INDENT 7.0 .TP .B property get_all_users بازگرداندن فهرستی از نام‌های کاربران محلی و راه‌دور .sp .EX >>> host.user().get_all_users [\(dqroot\(dq, \(dqbin\(dq, \(dqdaemon\(dq, \(dqlp\(dq, <...>] .EE .UNINDENT .INDENT 7.0 .TP .B property get_local_users بازگرداندن فهرستی از نام‌های کاربران محلی .sp .EX >>> host.user().get_local_users [\(dqroot\(dq, \(dqbin\(dq, \(dqdaemon\(dq, \(dqlp\(dq, <...>] .EE .UNINDENT .UNINDENT.SS CommandResult .INDENT 0.0 .TP .B class CommandResult(backend: BaseBackend, exit_status: int, command: bytes, _stdout: str | bytes, _stderr: str | bytes) شیئی که تمام جزئیات بازگردانده‌شده از اجرای دستور را کپسوله‌سازی می‌کند. .sp مثال: .sp .EX >>> cmd = host.run(\(dqls \-l /etc/passwd\(dq) >>> cmd.rc 0 >>> cmd.stdout \(aq\-rw\-r\-\-r\-\- 1 root root 1790 Feb 11 00:28 /etc/passwd\en\(aq >>> cmd.stderr \(aq\(aq >>> cmd.succeeded True >>> cmd.failed False .EE .INDENT 7.0 .TP .B property succeeded: bool مشخص می‌کند که آیا دستور با موفقیت اجرا شده است یا خیر. .sp .EX >>> host.run(\(dqtrue\(dq).succeeded True .EE .UNINDENT .INDENT 7.0 .TP .B property failed: bool مشخص می‌کند که آیا اجرای دستور ناموفق بوده است یا خیر. .sp .EX >>> host.run(\(dqfalse\(dq).failed True .EE .UNINDENT .INDENT 7.0 .TP .B property rc: int کد بازگشتی (returncode) دستور را دریافت می‌کند. .sp .EX >>> host.run(\(dqtrue\(dq).rc 0 .EE .UNINDENT .INDENT 7.0 .TP .B property stdout: str جریان خروجی استاندارد (stdout) دستور اجراشده را دریافت می‌کند. .sp .EX >>> host.run(\(dqmkdir \-v new_directory\(dq).stdout mkdir: created directory \(aqnew_directory\(aq .EE .UNINDENT .INDENT 7.0 .TP .B property stderr: str جریان خطای استاندارد (stderr) دستور اجراشده را دریافت می‌کند. .sp .EX >>> host.run(\(dqmkdir new_directory\(dq).stderr mkdir: cannot create directory \(aqnew_directory\(aq: File exists .EE .UNINDENT .INDENT 7.0 .TP .B property stdout_bytes: bytes جریان خروجی استاندارد (stdout) دستور اجراشده را به صورت بایت دریافت می‌کند. .sp .EX >>> host.run(\(dqmkdir \-v new_directory\(dq).stdout_bytes b\(dqmkdir: created directory \(aqnew_directory\(aq\(dq .EE .UNINDENT .INDENT 7.0 .TP .B property stderr_bytes: bytes جریان خطای استاندارد (stderr) دستور اجراشده را به صورت بایت دریافت می‌کند. .sp .EX >>> host.run(\(dqmkdir new_directory\(dq).stderr_bytes b\(dqmkdir: cannot create directory \(aqnew_directory\(aq: File exists\(dq .EE .UNINDENT .UNINDENT .SS API .SS Connection API .sp شما می‌توانید از testinfra در خارج از pytest نیز استفاده کنید. می‌توانید به‌صورت پویا یک نمونه از \fIhost\fP دریافت کرده و توابع را فراخوانی کنید یا به اعضای ماژول‌های مربوطه دسترسی داشته باشید: .INDENT 0.0 .INDENT 3.5 .sp .EX >>> import testinfra >>> host = testinfra.get_host(\(dqparamiko://root@server:2222\(dq, sudo=True) >>> host.file(\(dq/etc/shadow\(dq).mode == 0o640 True .EE .UNINDENT .UNINDENT .sp به‌عنوان مثال، می‌توانید آزمونی برای مقایسه دو فایل در دو سرور مختلف ایجاد کنید: .INDENT 0.0 .INDENT 3.5 .sp .EX import testinfra def test_same_passwd(): a = testinfra.get_host(\(dqssh://a\(dq) b = testinfra.get_host(\(dqssh://b\(dq) assert a.file(\(dq/etc/passwd\(dq).content == b.file(\(dq/etc/passwd\(dq).content .EE .UNINDENT .UNINDENT.SS مثال‌ها .SS پارامتریک‌سازی آزمون‌های خود .sp ابزار Pytest از پارامتریک‌سازی آزمون‌ها پشتیبانی می‌کند \%: .INDENT 0.0 .INDENT 3.5 .sp .EX # BAD: If the test fails on nginx, python is not tested def test_packages(host): for name, version in ( (\(dqnginx\(dq, \(dq1.6\(dq), (\(dqpython\(dq, \(dq2.7\(dq), ): pkg = host.package(name) assert pkg.is_installed assert pkg.version.startswith(version) # GOOD: Each package is tested # $ pytest \-v test.py # [...] # test.py::test_package[local\-nginx\-1.6] PASSED # test.py::test_package[local\-python\-2.7] PASSED # [...] import pytest @pytest.mark.parametrize(\(dqname,version\(dq, [ (\(dqnginx\(dq, \(dq1.6\(dq), (\(dqpython\(dq, \(dq2.7\(dq), ]) def test_packages(host, name, version): pkg = host.package(name) assert pkg.is_installed assert pkg.version.startswith(version) .EE .UNINDENT .UNINDENT .SS استفاده از unittest .sp ابزار Testinfra می‌تواند به جای pytest با فریم‌ورک استاندارد آزمون واحد پایتون یعنی unittest \% استفاده شود: .INDENT 0.0 .INDENT 3.5 .sp .EX import unittest import testinfra class Test(unittest.TestCase): def setUp(self): self.host = testinfra.get_host(\(dqparamiko://root@host\(dq) def test_nginx_config(self): self.assertEqual(self.host.run(\(dqnginx \-t\(dq).rc, 0) def test_nginx_service(self): service = self.host.service(\(dqnginx\(dq) self.assertTrue(service.is_running) self.assertTrue(service.is_enabled) if __name__ == \(dq__main__\(dq: unittest.main() .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX $ python test.py \&.. \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- Ran 2 tests in 0.705s OK .EE .UNINDENT .UNINDENT .SS یکپارچه‌سازی با Vagrant .sp ابزار Vagrant \% ابزاری برای راه‌اندازی و تدارک محیط‌های توسعه (ماشین‌های مجازی) است. .sp هنگامی که ماشین Vagrant شما بالا آمده و در حال اجرا است، می‌توانید به آسانی مجموعه آزمون‌های testinfra خود را روی آن اجرا کنید: .INDENT 0.0 .INDENT 3.5 .sp .EX vagrant ssh\-config > .vagrant/ssh\-config pytest \-\-hosts=default \-\-ssh\-config=.vagrant/ssh\-config tests.py .EE .UNINDENT .UNINDENT .SS یکپارچه‌سازی با Jenkins .sp سرور Jenkins \% یک سرور یکپارچه‌سازی مداوم متن‌باز و شناخته‌شده است. .sp اگر اسلیو (slave) جنکینز شما قادر به اجرای Vagrant باشد، اسکریپت‌های ساخت شما می‌توانند به این صورت باشند: .INDENT 0.0 .INDENT 3.5 .sp .EX pip install pytest\-testinfra paramiko vagrant up vagrant ssh\-config > .vagrant/ssh\-config pytest \-\-hosts=default \-\-ssh\-config=.vagrant/ssh\-config \-\-junit\-xml junit.xml tests.py .EE .UNINDENT .UNINDENT .sp سپس Jenkins را پیکربندی کنید تا نتایج آزمون‌ها را از فایل \fIjunit.xml\fP دریافت کند. .SS یکپارچه‌سازی با Nagios .sp آزمون‌های شما معمولاً اعتبارسنجی می‌کنند که سرویس‌های مستقرشده به‌درستی اجرا می‌شوند. این نوع آزمون‌ها به بررسی‌های پایش (مانیتورینگ) نزدیک هستند، بنابراین بیایید آن‌ها را به Nagios \% ارسال کنیم! .sp گزینه \fI\-\-nagios\fP در Testinfra رفتاری سازگار با یک افزونه nagios را فعال می‌کند: .INDENT 0.0 .INDENT 3.5 .sp .EX $ pytest \-qq \-\-nagios \-\-tb line test_ok.py; echo $? TESTINFRA OK \- 2 passed, 0 failed, 0 skipped in 2.30 seconds \&.. 0 $ pytest \-qq \-\-nagios \-\-tb line test_fail.py; echo $? TESTINFRA CRITICAL \- 1 passed, 1 failed, 0 skipped in 2.24 seconds \&.F /usr/lib/python3/dist\-packages/example/example.py:95: error: [Errno 111] error msg 2 .EE .UNINDENT .UNINDENT .sp می‌توانید این آزمون‌ها را از سرور اصلی nagios یا با استفاده از NRPE \%\& روی میزبان مقصد اجرا کنید..SS یکپارچه‌سازی با KitchenCI .sp ابزار KitchenCI (معروف به Test Kitchen) می‌تواند با استفاده از وارسی‌کنندهٔ (verifier) \fBshell\fP خود از testinfra استفاده کند. موارد زیر را به فایل \fB\&.kitchen.yml\fP خود اضافه کنید؛ این کار نیازمند نصب بستهٔ اضافی \fIparamiko\fP است (بر روی ماشین میزبان شما، نه درون ماشین مجازی مدیریت‌شده توسط kitchen). .INDENT 0.0 .INDENT 3.5 .sp .EX verifier: name: shell command: pytest \-\-hosts=\(dqparamiko://${KITCHEN_USERNAME}@${KITCHEN_HOSTNAME}:${KITCHEN_PORT}?ssh_identity_file=${KITCHEN_SSH_KEY}\(dq \-\-junit\-xml \(dqjunit\-${KITCHEN_INSTANCE}.xml\(dq \(dqtest/integration/${KITCHEN_SUITE}\(dq .EE .UNINDENT .UNINDENT .SS آزمودن تصویرهای Docker .sp داکر (Docker) روشی سودمند برای آزمایش کدهای زیرساخت شماست. این دستورالعمل نحوهٔ ساخت و اجرای کانتینرهای Docker با Testinfra را از طریق بازتعریف (overloading) فیکسچر \fIhost\fP نشان می‌دهد. .INDENT 0.0 .INDENT 3.5 .sp .EX import pytest import subprocess import testinfra # scope=\(aqsession\(aq uses the same container for all the tests; # scope=\(aqfunction\(aq uses a new container per test function. @pytest.fixture(scope=\(aqsession\(aq) def host(request): # build local ./Dockerfile subprocess.check_call([\(aqdocker\(aq, \(aqbuild\(aq, \(aq\-t\(aq, \(aqmyimage\(aq, \(aq.\(aq]) # run a container docker_id = subprocess.check_output( [\(aqdocker\(aq, \(aqrun\(aq, \(aq\-d\(aq, \(aqmyimage\(aq]).decode().strip() # return a testinfra connection to the container yield testinfra.get_host(\(dqdocker://\(dq + docker_id) # at the end of the test suite, destroy the container subprocess.check_call([\(aqdocker\(aq, \(aqrm\(aq, \(aq\-f\(aq, docker_id]) def test_myimage(host): # \(aqhost\(aq now binds to the container assert host.check_output(\(aqmyapp \-v\(aq) == \(aqMyapp 1.0\(aq .EE .UNINDENT .UNINDENT .SS پشتیبانی .sp اگر سؤالی دارید یا برای کار با testinfra نیاز به کمک دارید، لطفاً یکی از گزینه‌های زیر را در نظر بگیرید: .SS سامانه پیگیری مشکلات .sp گزارش‌ها و مشکلات موجود را در سامانه پیگیری پروژه بررسی کنید: \% .SS آی‌آرسی (IRC) .sp همچنین می‌توانید سؤالات خود را در IRC و در کانال #pytest \% روی شبکهٔ [libera.chat](\%) مطرح کنید. .SS مستندات pytest .sp ابزار testinfra به‌عنوان یک افزونه برای pytest پیاده‌سازی شده است؛ بنابراین برای بهره‌مندی حداکثری از آن، لطفاً مستندات pytest را مطالعه کنید: \% .SS مشارکت‌های جامعه .INDENT 0.0 .IP \(bu 2 ابزار Molecule \% یک چارچوب آزمایش خودکار برای نقش‌های Ansible است که به‌صورت بومی از Testinfra پشتیبانی می‌کند. .UNINDENT .SH "نویسندگان (AUTHORS)" Philippe Pepiot .SH "کپی‌رایت و تکثیر (COPYRIGHT)" 2025, Philippe Pepiot .\" End of generated man page.