PHP logo

PHP Version 7.4.33

System Linux localhost.localdomain 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64
Build Date Mar 10 2026 11:55:58
Configure Command './configure' '--prefix=/www/server/php/74' '--with-config-file-path=/www/server/php/74/etc' '--enable-fpm' '--with-fpm-user=www' '--with-fpm-group=www' '--enable-mysqlnd' '--with-mysqli=mysqlnd' '--with-pdo-mysql=mysqlnd' '--with-iconv-dir' '--with-freetype' '--with-jpeg' '--with-zlib' '--with-libxml-dir=/usr' '--enable-xml' '--disable-rpath' '--enable-bcmath' '--enable-shmop' '--enable-sysvsem' '--enable-inline-optimization' '--with-curl' '--enable-mbregex' '--enable-mbstring' '--enable-intl' '--enable-ftp' '--enable-gd' '--with-openssl' '--with-mhash' '--enable-pcntl' '--enable-sockets' '--with-xmlrpc' '--enable-soap' '--with-gettext' '--disable-fileinfo' '--enable-opcache' '--with-sodium=/usr/local/libsodium' '--with-webp' 'PKG_CONFIG_PATH=/usr/local/curl/lib/pkgconfig:/usr/local/openssl/lib/pkgconfig:'
Server API FPM/FastCGI
Virtual Directory Support disabled
Configuration File (php.ini) Path /www/server/php/74/etc
Loaded Configuration File /www/server/php/74/etc/php.ini
Scan this dir for additional .ini files (none)
Additional .ini files parsed (none)
PHP API 20190902
PHP Extension 20190902
Zend Extension 320190902
Zend Extension Build API320190902,NTS
PHP Extension Build API20190902,NTS
Debug Build no
Thread Safety disabled
Zend Signal Handling enabled
Zend Memory Manager enabled
Zend Multibyte Support provided by mbstring
IPv6 Support enabled
DTrace Support disabled
Registered PHP Streamshttps, ftps, compress.zlib, php, file, glob, data, http, ftp, phar, zip
Registered Stream Socket Transportstcp, udp, unix, udg, ssl, sslv3, tls, tlsv1.0, tlsv1.1, tlsv1.2
Registered Stream Filterszlib.*, convert.iconv.*, string.rot13, string.toupper, string.tolower, string.strip_tags, convert.*, consumed, dechunk
Zend logo This program makes use of the Zend Scripting Language Engine:
Zend Engine v3.4.0, Copyright (c) Zend Technologies

Configuration

bcmath

BCMath support enabled
DirectiveLocal ValueMaster Value
bcmath.scale00

cgi-fcgi

php-fpm active
DirectiveLocal ValueMaster Value
cgi.discard_path00
cgi.fix_pathinfo11
cgi.force_redirect11
cgi.nph00
cgi.redirect_status_envno valueno value
cgi.rfc2616_headers00
fastcgi.error_headerno valueno value
fastcgi.logging11
fpm.configno valueno value

Core

PHP Version 7.4.33
DirectiveLocal ValueMaster Value
allow_url_fopenOnOn
allow_url_includeOffOff
arg_separator.input&&
arg_separator.output&&
auto_append_fileno valueno value
auto_globals_jitOnOn
auto_prepend_fileno valueno value
browscapno valueno value
default_charsetUTF-8UTF-8
default_mimetypetext/htmltext/html
disable_classesno valueno value
disable_functionspassthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenvpassthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
display_errorsOnOn
display_startup_errorsOffOff
doc_rootno valueno value
docref_extno valueno value
docref_rootno valueno value
enable_dlOffOff
enable_post_data_readingOnOn
error_append_stringno valueno value
error_logno valueno value
error_prepend_stringno valueno value
error_reporting3275932759
expose_phpOffOff
extension_dir/www/server/php/74/lib/php/extensions/no-debug-non-zts-20190902/www/server/php/74/lib/php/extensions/no-debug-non-zts-20190902
file_uploadsOnOn
hard_timeout22
highlight.comment#FF8000#FF8000
highlight.default#0000BB#0000BB
highlight.html#000000#000000
highlight.keyword#007700#007700
highlight.string#DD0000#DD0000
html_errorsOnOn
ignore_repeated_errorsOffOff
ignore_repeated_sourceOffOff
ignore_user_abortOffOff
implicit_flushOffOff
include_path.:.:
input_encodingno valueno value
internal_encodingno valueno value
log_errorsOnOn
log_errors_max_len10241024
mail.add_x_headerOffOff
mail.force_extra_parametersno valueno value
mail.logno valueno value
max_execution_time300300
max_file_uploads2020
max_input_nesting_level6464
max_input_time6060
max_input_vars10001000
memory_limit128M128M
open_basedirno valueno value
output_buffering40964096
output_encodingno valueno value
output_handlerno valueno value
post_max_size50M50M
precision1414
realpath_cache_size4096K4096K
realpath_cache_ttl120120
register_argc_argvOffOff
report_memleaksOnOn
report_zend_debugOnOn
request_orderGPGP
sendmail_fromno valueno value
sendmail_path/usr/sbin/sendmail -t -i/usr/sbin/sendmail -t -i
serialize_precision-1-1
short_open_tagOnOn
SMTPlocalhostlocalhost
smtp_port2525
sys_temp_dirno valueno value
syslog.facilityLOG_USERLOG_USER
syslog.filterno-ctrlno-ctrl
syslog.identphpphp
track_errorsOffOff
unserialize_callback_funcno valueno value
upload_max_filesize50M50M
upload_tmp_dirno valueno value
user_dirno valueno value
user_ini.cache_ttl300300
user_ini.filename.user.ini.user.ini
variables_orderGPCSGPCS
xmlrpc_error_number00
xmlrpc_errorsOffOff
zend.assertions-1-1
zend.detect_unicodeOnOn
zend.enable_gcOnOn
zend.exception_ignore_argsOnOn
zend.multibyteOffOff
zend.script_encodingno valueno value
zend.signal_checkOffOff

ctype

ctype functions enabled

curl

cURL support enabled
cURL Information 7.70.0
Age 6
Features
AsynchDNS Yes
CharConv No
Debug No
GSS-Negotiate No
IDN No
IPv6 Yes
krb4 No
Largefile Yes
libz Yes
NTLM Yes
NTLMWB Yes
SPNEGO No
SSL Yes
SSPI No
TLS-SRP Yes
HTTP2 No
GSSAPI No
KERBEROS5 No
UNIX_SOCKETS Yes
PSL No
HTTPS_PROXY Yes
MULTI_SSL No
BROTLI No
Protocols dict, file, ftp, ftps, gopher, http, https, imap, imaps, pop3, pop3s, rtsp, smb, smbs, smtp, smtps, telnet, tftp
Host x86_64-pc-linux-gnu
SSL Version OpenSSL/1.0.2u
ZLib Version 1.2.7
DirectiveLocal ValueMaster Value
curl.cainfo/etc/pki/tls/certs/ca-bundle.crt/etc/pki/tls/certs/ca-bundle.crt

date

date/time support enabled
timelib version 2018.04
"Olson" Timezone Database Version 2022.1
Timezone Database internal
Default timezone PRC
DirectiveLocal ValueMaster Value
date.default_latitude31.766731.7667
date.default_longitude35.233335.2333
date.sunrise_zenith90.58333390.583333
date.sunset_zenith90.58333390.583333
date.timezonePRCPRC

dom

DOM/XML enabled
DOM/XML API Version 20031129
libxml Version 2.9.1
HTML Support enabled
XPath Support enabled
XPointer Support enabled
Schema Support enabled
RelaxNG Support enabled

filter

Input Validation and Filtering enabled
DirectiveLocal ValueMaster Value
filter.defaultunsafe_rawunsafe_raw
filter.default_flagsno valueno value

ftp

FTP support enabled
FTPS support enabled

gd

GD Support enabled
GD Version bundled (2.1.0 compatible)
FreeType Support enabled
FreeType Linkage with freetype
FreeType Version 2.8.0
GIF Read Support enabled
GIF Create Support enabled
JPEG Support enabled
libJPEG Version 6b
PNG Support enabled
libPNG Version 1.5.13
WBMP Support enabled
XBM Support enabled
WebP Support enabled
BMP Support enabled
TGA Read Support enabled
DirectiveLocal ValueMaster Value
gd.jpeg_ignore_warning11

gettext

GetText Support enabled

hash

hash support enabled
Hashing Engines md2 md4 md5 sha1 sha224 sha256 sha384 sha512/224 sha512/256 sha512 sha3-224 sha3-256 sha3-384 sha3-512 ripemd128 ripemd160 ripemd256 ripemd320 whirlpool tiger128,3 tiger160,3 tiger192,3 tiger128,4 tiger160,4 tiger192,4 snefru snefru256 gost gost-crypto adler32 crc32 crc32b crc32c fnv132 fnv1a32 fnv164 fnv1a64 joaat haval128,3 haval160,3 haval192,3 haval224,3 haval256,3 haval128,4 haval160,4 haval192,4 haval224,4 haval256,4 haval128,5 haval160,5 haval192,5 haval224,5 haval256,5
MHASH support Enabled
MHASH API Version Emulated Support

iconv

iconv support enabled
iconv implementation glibc
iconv library version 2.17
DirectiveLocal ValueMaster Value
iconv.input_encodingno valueno value
iconv.internal_encodingno valueno value
iconv.output_encodingno valueno value

igbinary

igbinary support enabled
igbinary version 3.2.14
igbinary APCu serializer ABI no
igbinary session support yes
DirectiveLocal ValueMaster Value
igbinary.compact_stringsOnOn

intl

Internationalization supportenabled
ICU version 50.2
ICU Data version 50.2
ICU TZData version 2018e
ICU Unicode version 6.2
DirectiveLocal ValueMaster Value
intl.default_localeno valueno value
intl.error_level00
intl.use_exceptions00

json

json support enabled

libxml

libXML support active
libXML Compiled Version 2.9.1
libXML Loaded Version 20901
libXML streams enabled

mbstring

Multibyte Support enabled
Multibyte string engine libmbfl
HTTP input encoding translation disabled
libmbfl version 1.3.2
mbstring extension makes use of "streamable kanji code filter and converter", which is distributed under the GNU Lesser General Public License version 2.1.
Multibyte (japanese) regex support enabled
Multibyte regex (oniguruma) version 6.8.2
DirectiveLocal ValueMaster Value
mbstring.detect_orderno valueno value
mbstring.encoding_translationOffOff
mbstring.func_overload00
mbstring.http_inputno valueno value
mbstring.http_outputno valueno value
mbstring.http_output_conv_mimetypes^(text/|application/xhtml\+xml)^(text/|application/xhtml\+xml)
mbstring.internal_encodingno valueno value
mbstring.languageneutralneutral
mbstring.regex_retry_limit10000001000000
mbstring.regex_stack_limit100000100000
mbstring.strict_detectionOffOff
mbstring.substitute_characterno valueno value

mysqli

MysqlI Supportenabled
Client API library version mysqlnd 7.4.33
Active Persistent Links 0
Inactive Persistent Links 0
Active Links 0
DirectiveLocal ValueMaster Value
mysqli.allow_local_infileOffOff
mysqli.allow_persistentOnOn
mysqli.default_hostno valueno value
mysqli.default_port33063306
mysqli.default_pwno valueno value
mysqli.default_socketno valueno value
mysqli.default_userno valueno value
mysqli.max_linksUnlimitedUnlimited
mysqli.max_persistentUnlimitedUnlimited
mysqli.reconnectOffOff
mysqli.rollback_on_cached_plinkOffOff

mysqlnd

mysqlndenabled
Version mysqlnd 7.4.33
Compression supported
core SSL supported
extended SSL supported
Command buffer size 4096
Read buffer size 32768
Read timeout 86400
Collecting statistics Yes
Collecting memory statistics No
Tracing n/a
Loaded plugins mysqlnd,debug_trace,auth_plugin_mysql_native_password,auth_plugin_mysql_clear_password,auth_plugin_caching_sha2_password,auth_plugin_sha256_password
API Extensions pdo_mysql,mysqli

openssl

OpenSSL support enabled
OpenSSL Library Version OpenSSL 1.0.2u 20 Dec 2019
OpenSSL Header Version OpenSSL 1.0.2u 20 Dec 2019
Openssl default config /usr/local/openssl/openssl.cnf
DirectiveLocal ValueMaster Value
openssl.cafile/etc/pki/tls/certs/ca-bundle.crt/etc/pki/tls/certs/ca-bundle.crt
openssl.capathno valueno value

pcntl

pcntl supportenabled

pcre

PCRE (Perl Compatible Regular Expressions) Support enabled
PCRE Library Version 10.35 2020-05-09
PCRE Unicode Version 13.0.0
PCRE JIT Support enabled
PCRE JIT Target x86 64bit (little endian + unaligned)
DirectiveLocal ValueMaster Value
pcre.backtrack_limit10000001000000
pcre.jit11
pcre.recursion_limit100000100000

PDO

PDO supportenabled
PDO drivers sqlite, mysql

pdo_mysql

PDO Driver for MySQLenabled
Client API version mysqlnd 7.4.33
DirectiveLocal ValueMaster Value
pdo_mysql.default_socket/tmp/mysql.sock/tmp/mysql.sock

pdo_sqlite

PDO Driver for SQLite 3.xenabled
SQLite Library 3.7.17

Phar

Phar: PHP Archive supportenabled
Phar API version 1.1.1
Phar-based phar archives enabled
Tar-based phar archives enabled
ZIP-based phar archives enabled
gzip compression enabled
bzip2 compression disabled (install ext/bz2)
Native OpenSSL support enabled
Phar based on pear/PHP_Archive, original concept by Davey Shafik.
Phar fully realized by Gregory Beaver and Marcus Boerger.
Portions of tar implementation Copyright (c) 2003-2009 Tim Kientzle.
DirectiveLocal ValueMaster Value
phar.cache_listno valueno value
phar.readonlyOnOn
phar.require_hashOnOn

posix

POSIX support enabled

redis

Redis Supportenabled
Redis Version 5.3.7
Redis Sentinel Version 0.1
Available serializers php, json, igbinary
DirectiveLocal ValueMaster Value
redis.arrays.algorithmno valueno value
redis.arrays.authno valueno value
redis.arrays.autorehash00
redis.arrays.connecttimeout00
redis.arrays.consistent00
redis.arrays.distributorno valueno value
redis.arrays.functionsno valueno value
redis.arrays.hostsno valueno value
redis.arrays.index00
redis.arrays.lazyconnect00
redis.arrays.namesno valueno value
redis.arrays.pconnect00
redis.arrays.previousno valueno value
redis.arrays.readtimeout00
redis.arrays.retryinterval00
redis.clusters.authno valueno value
redis.clusters.cache_slots00
redis.clusters.persistent00
redis.clusters.read_timeout00
redis.clusters.seedsno valueno value
redis.clusters.timeout00
redis.pconnect.connection_limit00
redis.pconnect.echo_check_liveness11
redis.pconnect.pool_detect_dirty00
redis.pconnect.pool_patternno valueno value
redis.pconnect.pool_poll_timeout00
redis.pconnect.pooling_enabled11
redis.session.lock_expire00
redis.session.lock_retries1010
redis.session.lock_wait_time20002000
redis.session.locking_enabled00

Reflection

Reflection enabled

session

Session Support enabled
Registered save handlers files user redis rediscluster
Registered serializer handlers php_serialize php php_binary igbinary
DirectiveLocal ValueMaster Value
session.auto_startOffOff
session.cache_expire180180
session.cache_limiternocachenocache
session.cookie_domainno valueno value
session.cookie_httponlyno valueno value
session.cookie_lifetime00
session.cookie_path//
session.cookie_samesiteno valueno value
session.cookie_secure00
session.gc_divisor10001000
session.gc_maxlifetime14401440
session.gc_probability11
session.lazy_writeOnOn
session.namePHPSESSIDPHPSESSID
session.referer_checkno valueno value
session.save_handlerfilesfiles
session.save_pathno valueno value
session.serialize_handlerphpphp
session.sid_bits_per_character55
session.sid_length2626
session.upload_progress.cleanupOnOn
session.upload_progress.enabledOnOn
session.upload_progress.freq1%1%
session.upload_progress.min_freq11
session.upload_progress.namePHP_SESSION_UPLOAD_PROGRESSPHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefixupload_progress_upload_progress_
session.use_cookies11
session.use_only_cookies11
session.use_strict_mode00
session.use_trans_sid00

shmop

shmop support enabled

SimpleXML

SimpleXML support enabled
Schema support enabled

soap

Soap Client enabled
Soap Server enabled
DirectiveLocal ValueMaster Value
soap.wsdl_cache11
soap.wsdl_cache_dir/tmp/tmp
soap.wsdl_cache_enabled11
soap.wsdl_cache_limit55
soap.wsdl_cache_ttl8640086400

sockets

Sockets Support enabled

sodium

sodium supportenabled
libsodium headers version 1.0.18
libsodium library version 1.0.18

SPL

SPL supportenabled
Interfaces OuterIterator, RecursiveIterator, SeekableIterator, SplObserver, SplSubject
Classes AppendIterator, ArrayIterator, ArrayObject, BadFunctionCallException, BadMethodCallException, CachingIterator, CallbackFilterIterator, DirectoryIterator, DomainException, EmptyIterator, FilesystemIterator, FilterIterator, GlobIterator, InfiniteIterator, InvalidArgumentException, IteratorIterator, LengthException, LimitIterator, LogicException, MultipleIterator, NoRewindIterator, OutOfBoundsException, OutOfRangeException, OverflowException, ParentIterator, RangeException, RecursiveArrayIterator, RecursiveCachingIterator, RecursiveCallbackFilterIterator, RecursiveDirectoryIterator, RecursiveFilterIterator, RecursiveIteratorIterator, RecursiveRegexIterator, RecursiveTreeIterator, RegexIterator, RuntimeException, SplDoublyLinkedList, SplFileInfo, SplFileObject, SplFixedArray, SplHeap, SplMinHeap, SplMaxHeap, SplObjectStorage, SplPriorityQueue, SplQueue, SplStack, SplTempFileObject, UnderflowException, UnexpectedValueException

sqlite3

SQLite3 supportenabled
SQLite Library 3.7.17
DirectiveLocal ValueMaster Value
sqlite3.extension_dirno valueno value

standard

Dynamic Library Support enabled
Path to sendmail /usr/sbin/sendmail -t -i
DirectiveLocal ValueMaster Value
assert.active11
assert.bail00
assert.callbackno valueno value
assert.exception00
assert.quiet_eval00
assert.warning11
auto_detect_line_endings00
default_socket_timeout6060
fromno valueno value
session.trans_sid_hostsno valueno value
session.trans_sid_tagsa=href,area=href,frame=src,form=a=href,area=href,frame=src,form=
unserialize_max_depth40964096
url_rewriter.hostsno valueno value
url_rewriter.tagsform=form=
user_agentno valueno value

sysvsem

sysvsem support enabled

tokenizer

Tokenizer Support enabled

xml

XML Support active
XML Namespace Support active
libxml2 Version 2.9.1

xmlreader

XMLReader enabled

xmlrpc

core library version xmlrpc-epi v. 0.51
author Dan Libby
homepage http://xmlrpc-epi.sourceforge.net
open sourced by Epinions.com

xmlwriter

XMLWriter enabled

zip

Zip enabled
Zip version 1.15.6
Libzip headers version 1.5.2
Libzip library version 1.5.2

zlib

ZLib Supportenabled
Stream Wrapper compress.zlib://
Stream Filter zlib.inflate, zlib.deflate
Compiled Version 1.2.7
Linked Version 1.2.7
DirectiveLocal ValueMaster Value
zlib.output_compressionOffOff
zlib.output_compression_level-1-1
zlib.output_handlerno valueno value

Additional Modules

Module Name

Environment

VariableValue
USER www
HOME /home/www

PHP Variables

VariableValue
$_REQUEST['s']/default/index/show
$_REQUEST['id']305871887
$_GET['s']/default/index/show
$_GET['id']305871887
$_SERVER['USER']www
$_SERVER['HOME']/home/www
$_SERVER['HTTP_ACCEPT_ENCODING']gzip, br, zstd, deflate
$_SERVER['HTTP_USER_AGENT']Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
$_SERVER['HTTP_ACCEPT']*/*
$_SERVER['PATH_INFO']no value
$_SERVER['HTTP_HOST']likecs.com
$_SERVER['REDIRECT_STATUS']200
$_SERVER['SERVER_NAME']likecs.com
$_SERVER['SERVER_PORT']443
$_SERVER['SERVER_ADDR']122.10.52.145
$_SERVER['REMOTE_PORT']3369
$_SERVER['REMOTE_ADDR']216.73.216.50
$_SERVER['SERVER_SOFTWARE']nginx/1.28.1
$_SERVER['GATEWAY_INTERFACE']CGI/1.1
$_SERVER['HTTPS']on
$_SERVER['REQUEST_SCHEME']https
$_SERVER['SERVER_PROTOCOL']HTTP/2.0
$_SERVER['DOCUMENT_ROOT']/www/wwwroot/local.likecs.com
$_SERVER['DOCUMENT_URI']/index.php
$_SERVER['REQUEST_URI']/show-305871887.html
$_SERVER['SCRIPT_NAME']/index.php
$_SERVER['CONTENT_LENGTH']no value
$_SERVER['CONTENT_TYPE']no value
$_SERVER['REQUEST_METHOD']GET
$_SERVER['QUERY_STRING']s=/default/index/show&id=305871887
$_SERVER['SCRIPT_FILENAME']/www/wwwroot/local.likecs.com/index.php
$_SERVER['FCGI_ROLE']RESPONDER
$_SERVER['PHP_SELF']/index.php
$_SERVER['REQUEST_TIME_FLOAT']1773804216.3924
$_SERVER['REQUEST_TIME']1773804216

PHP Credits

PHP Group
Thies C. Arntzen, Stig Bakken, Shane Caraveo, Andi Gutmans, Rasmus Lerdorf, Sam Ruby, Sascha Schumann, Zeev Suraski, Jim Winstead, Andrei Zmievski
Language Design & Concept
Andi Gutmans, Rasmus Lerdorf, Zeev Suraski, Marcus Boerger
PHP Authors
ContributionAuthors
Zend Scripting Language Engine Andi Gutmans, Zeev Suraski, Stanislav Malyshev, Marcus Boerger, Dmitry Stogov, Xinchen Hui, Nikita Popov
Extension Module API Andi Gutmans, Zeev Suraski, Andrei Zmievski
UNIX Build and Modularization Stig Bakken, Sascha Schumann, Jani Taskinen, Peter Kokot
Windows Support Shane Caraveo, Zeev Suraski, Wez Furlong, Pierre-Alain Joye, Anatol Belski, Kalle Sommer Nielsen
Server API (SAPI) Abstraction Layer Andi Gutmans, Shane Caraveo, Zeev Suraski
Streams Abstraction Layer Wez Furlong, Sara Golemon
PHP Data Objects Layer Wez Furlong, Marcus Boerger, Sterling Hughes, George Schlossnagle, Ilia Alshanetsky
Output Handler Zeev Suraski, Thies C. Arntzen, Marcus Boerger, Michael Wallner
Consistent 64 bit support Anthony Ferrara, Anatol Belski
SAPI Modules
ContributionAuthors
Apache 2.0 Handler Ian Holsman, Justin Erenkrantz (based on Apache 2.0 Filter code)
CGI / FastCGI Rasmus Lerdorf, Stig Bakken, Shane Caraveo, Dmitry Stogov
CLI Edin Kadribasic, Marcus Boerger, Johannes Schlueter, Moriyoshi Koizumi, Xinchen Hui
Embed Edin Kadribasic
FastCGI Process Manager Andrei Nigmatulin, dreamcat4, Antony Dovgal, Jerome Loyet
litespeed George Wang
phpdbg Felipe Pena, Joe Watkins, Bob Weinand
Module Authors
ModuleAuthors
BC Math Andi Gutmans
Bzip2 Sterling Hughes
Calendar Shane Caraveo, Colin Viebrock, Hartmut Holzgraefe, Wez Furlong
COM and .Net Wez Furlong
ctype Hartmut Holzgraefe
cURL Sterling Hughes
Date/Time Support Derick Rethans
DB-LIB (MS SQL, Sybase) Wez Furlong, Frank M. Kromann, Adam Baratz
DBA Sascha Schumann, Marcus Boerger
DOM Christian Stocker, Rob Richards, Marcus Boerger
enchant Pierre-Alain Joye, Ilia Alshanetsky
EXIF Rasmus Lerdorf, Marcus Boerger
FFI Dmitry Stogov
fileinfo Ilia Alshanetsky, Pierre Alain Joye, Scott MacVicar, Derick Rethans, Anatol Belski
Firebird driver for PDO Ard Biesheuvel
FTP Stefan Esser, Andrew Skalski
GD imaging Rasmus Lerdorf, Stig Bakken, Jim Winstead, Jouni Ahto, Ilia Alshanetsky, Pierre-Alain Joye, Marcus Boerger
GetText Alex Plotnick
GNU GMP support Stanislav Malyshev
Iconv Rui Hirokawa, Stig Bakken, Moriyoshi Koizumi
IMAP Rex Logan, Mark Musone, Brian Wang, Kaj-Michael Lang, Antoni Pamies Olive, Rasmus Lerdorf, Andrew Skalski, Chuck Hagenbuch, Daniel R Kalowsky
Input Filter Rasmus Lerdorf, Derick Rethans, Pierre-Alain Joye, Ilia Alshanetsky
Internationalization Ed Batutis, Vladimir Iordanov, Dmitry Lakhtyuk, Stanislav Malyshev, Vadim Savchuk, Kirti Velankar
JSON Jakub Zelenka, Omar Kilani, Scott MacVicar
LDAP Amitay Isaacs, Eric Warnke, Rasmus Lerdorf, Gerrit Thomson, Stig Venaas
LIBXML Christian Stocker, Rob Richards, Marcus Boerger, Wez Furlong, Shane Caraveo
Multibyte String Functions Tsukada Takuya, Rui Hirokawa
MySQL driver for PDO George Schlossnagle, Wez Furlong, Ilia Alshanetsky, Johannes Schlueter
MySQLi Zak Greant, Georg Richter, Andrey Hristov, Ulf Wendel
MySQLnd Andrey Hristov, Ulf Wendel, Georg Richter, Johannes Schlüter
OCI8 Stig Bakken, Thies C. Arntzen, Andy Sautins, David Benson, Maxim Maletsky, Harald Radi, Antony Dovgal, Andi Gutmans, Wez Furlong, Christopher Jones, Oracle Corporation
ODBC driver for PDO Wez Furlong
ODBC Stig Bakken, Andreas Karajannis, Frank M. Kromann, Daniel R. Kalowsky
Opcache Andi Gutmans, Zeev Suraski, Stanislav Malyshev, Dmitry Stogov, Xinchen Hui
OpenSSL Stig Venaas, Wez Furlong, Sascha Kettler, Scott MacVicar
Oracle (OCI) driver for PDO Wez Furlong
pcntl Jason Greene, Arnaud Le Blanc
Perl Compatible Regexps Andrei Zmievski
PHP Archive Gregory Beaver, Marcus Boerger
PHP Data Objects Wez Furlong, Marcus Boerger, Sterling Hughes, George Schlossnagle, Ilia Alshanetsky
PHP hash Sara Golemon, Rasmus Lerdorf, Stefan Esser, Michael Wallner, Scott MacVicar
Posix Kristian Koehntopp
PostgreSQL driver for PDO Edin Kadribasic, Ilia Alshanetsky
PostgreSQL Jouni Ahto, Zeev Suraski, Yasuo Ohgaki, Chris Kings-Lynne
Pspell Vlad Krupin
Readline Thies C. Arntzen
Reflection Marcus Boerger, Timm Friebe, George Schlossnagle, Andrei Zmievski, Johannes Schlueter
Sessions Sascha Schumann, Andrei Zmievski
Shared Memory Operations Slava Poliakov, Ilia Alshanetsky
SimpleXML Sterling Hughes, Marcus Boerger, Rob Richards
SNMP Rasmus Lerdorf, Harrie Hazewinkel, Mike Jackson, Steven Lawrance, Johann Hanne, Boris Lytochkin
SOAP Brad Lafountain, Shane Caraveo, Dmitry Stogov
Sockets Chris Vandomelen, Sterling Hughes, Daniel Beulshausen, Jason Greene
Sodium Frank Denis
SPL Marcus Boerger, Etienne Kneuss
SQLite 3.x driver for PDO Wez Furlong
SQLite3 Scott MacVicar, Ilia Alshanetsky, Brad Dewar
System V Message based IPC Wez Furlong
System V Semaphores Tom May
System V Shared Memory Christian Cartus
tidy John Coggeshall, Ilia Alshanetsky
tokenizer Andrei Zmievski, Johannes Schlueter
XML Stig Bakken, Thies C. Arntzen, Sterling Hughes
XMLReader Rob Richards
xmlrpc Dan Libby
XMLWriter Rob Richards, Pierre-Alain Joye
XSL Christian Stocker, Rob Richards
Zip Pierre-Alain Joye, Remi Collet
Zlib Rasmus Lerdorf, Stefan Roehrich, Zeev Suraski, Jade Nicoletti, Michael Wallner
PHP Documentation
Authors Mehdi Achour, Friedhelm Betz, Antony Dovgal, Nuno Lopes, Hannes Magnusson, Philip Olson, Georg Richter, Damien Seguy, Jakub Vrana, Adam Harvey
Editor Peter Cowburn
User Note Maintainers Daniel P. Brown, Thiago Henrique Pojda
Other Contributors Previously active authors, editors and other contributors are listed in the manual.
PHP Quality Assurance Team
Ilia Alshanetsky, Joerg Behrens, Antony Dovgal, Stefan Esser, Moriyoshi Koizumi, Magnus Maatta, Sebastian Nohn, Derick Rethans, Melvyn Sopacua, Pierre-Alain Joye, Dmitry Stogov, Felipe Pena, David Soria Parra, Stanislav Malyshev, Julien Pauli, Stephen Zarkos, Anatol Belski, Remi Collet, Ferenc Kovacs
Websites and Infrastructure team
PHP Websites Team Rasmus Lerdorf, Hannes Magnusson, Philip Olson, Lukas Kahwe Smith, Pierre-Alain Joye, Kalle Sommer Nielsen, Peter Cowburn, Adam Harvey, Ferenc Kovacs, Levi Morrison
Event Maintainers Damien Seguy, Daniel P. Brown
Network Infrastructure Daniel P. Brown
Windows Infrastructure Alex Schoenmaker

PHP License

This program is free software; you can redistribute it and/or modify it under the terms of the PHP License as published by the PHP Group and included in the distribution in the file: LICENSE

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

If you did not receive a copy of the PHP license, or have any questions about PHP licensing, please contact license@php.net.


Warning: session_start(): Cannot start session when headers already sent in /www/wwwroot/local.likecs.com/index.php on line 13

Warning: Cannot modify header information - headers already sent by (output started at /www/wwwroot/local.likecs.com/index.php:1) in /www/wwwroot/local.likecs.com/core/base.php on line 35
Ansible进阶--playbook的使用 - 爱码网

一、什么是playbooks
playbooks是ansible的脚本、如同shell脚本一样,它是控制远程主机的一系列命令的集合,通过YAML语言编写。执行一些简单的任务,我们可以使用ad-hoc命令就可以解决,对于一些较复杂的任务,ad-hoc就不能胜任了,这时候playbooks就派上用场了,在playbooks中可以编排有序的执行过程,甚至可以在多组机器间来回有序的执行特定的步骤,并且可以同步或异步发起任务。

二、YAML语法
1、文件开始符

---

2、数组

- name
- hosts
- user

3、字典

name: restart apache
service: name=httpd state=restarted

字典与字典的嵌套:

vars:
  http_port: 80
  max_clients: 200

字典与数组的嵌套:

tasks:
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: write the apache config file
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service: name=httpd state=started

此外,Ansible 使用 "{{ var }}"来引用变量.,如果一个值以 "{" 开头, YAML 将认为它是一个字典, 所以我们必须引用它, 像这样:foo: "{{ variable }}"

三、playbooks的基本用法
最基本的playbook分为四部分:

  • 定义主机和用户
hosts
users
  • 定义 playbook 执行需要的变量
variable
  • 定义任务
tasks
  • 定义响应事件
handlers

简单示例:

---
- name: Install apache
  hosts: webservers
  user: root
  gather_facts: false
  vars:
    http_port: 80
    max_clients: 200
  tasks:
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: write the apache config file
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service: name=httpd state=started
  handlers:
    - name: restart apache
      service: name=httpd state=restarted

说明:

  • name参数对此playbook实现的功能的概述,执行时会输出name变量值。
  • hosts参数指定了在哪些主机上执行playbook
  • user参数指定在远程主机上使用什么用户执行任务
  • gather_facts参数指定了下面任务执行前,是否先执行setup模块获取远程主机相关信息,这些信息在task中可以作为变量使用
  • vars参数指定了变量
  • task参数指定了任务,这里有3个任务。name参数是对具体任务的描述,在执行过程中会输出
  • handlers参数指定一个响应事件,当template: src=/srv/httpd.j2 dest=/etc/httpd.conf这个任务执行状态是changed时才会触发。

 1、主机和用户

key 含 义
hosts 为主机的IP,或者主机组名,或者关键字all
user 在远程以哪个用户身份执行。
become 切换成其它用户身份执行,值为yes或者no
become_method 与became一起用,指可以为‘sudo’/’su’/’pbrun’/’pfexec’/’doas’
become_user 与bacome一起用,可以是root或者其它用户名

一般用法:

---
- hosts: webserver, [all]
  user: root

还可以在每个 task 中,定义远程执行用户

---
- hosts: webserver
  user: root
  tasks:
  - name: test connection
    ping:
    remote_user: root

也支持 sudo 方法,在 task中同样支持,在sudo需要密码时,可以加上选项 –ask-sudo-pass

---
- hosts: all
  user: test
  sudo: yes
  task:
    - service: name=nginx state=started
      sudo: yes
      sudo_user: root

2、任务列表
tasks 是从上到下顺序执行,如果中间发生错误,整个 playbook 便会中断。
每一个 task 是对module的一次调用,通常会带有特定参数,参数可以使用变量。
每一个 task 有一个 name 属性,name 值会在命令行中输出,以提示用户,如果没有定义,aciton 的值会作为输出信息来标记task。

语法:

tasks:
  - name: make sure apache is running
    service: name=httpd state=running
// 如果参数过长,可以使用空格或者缩进分隔为多行
tasks:
  - name: copy ansible inventory file to client
    copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts
          owner=root group=root mode=0644
// 或者使用 yaml 的字典作为参数
tasks:
  - name: copy ansible inventory file to client
    copy:
      src: /etc/ansible/hosts
      dest: /etc/ansible/hosts
      owner: root
      group: root
      mode: 0644
// 大部分的模块都是使用 `key-value` 这种格式的,其中有两个比较特殊,command 和 shell 模块。
tasks:
  - name: disable selinux
    command: /sbin/setenforce 0
tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/command || /bin/true
tasks:
  - name: run some command and ignore the reslut
    shell: /usr/bin/somecommadn
    ignore_error: True

执行状态:
task中每个action会调用一个module,在module中会去检查当前系统状态是否需要重新执行。
如果本次执行了,那么action会得到返回值changed
如果不需要执行,那么action得到返回值ok

3、响应事件
每个主流的编程语言都会有event机制,那么handler就是playbook的event。
Handlers里面的每一个handler,也是对module的一次调用。而handlers与tasks不同,tasks会默认的按定义顺序执行每一个task,handlers则不会,它需要在tasks中被调用,才有可能被执行。Tasks中的任务都是有状态的,changed或者ok。 在Ansible中,只在task的执行状态为changed的时候,才会执行该task调用的handler,这也是handler与普通的event机制不同的地方。
什么情况下使用handlers呢?
如果你在tasks中修改了apache的配置文件。需要重起apache。此外还安装了apache的插件。那么还需要重起apache。像这样的应该场景中,重启apache就可以设计成一个handler。

特性:

  • 一个handler最多只执行一次

在所有的任务里表执行之后执行,如果有多个task notify同一个handler,那么只执行一次。
在下面的例子里apache只执行一次

---
- hosts: lb
  remote_user: root
  vars:
      random_number1: "{{ 10000 | random }}"
      random_number2: "{{ 10000000000 | random }}"
  tasks:
  - name: Copy the /etc/hosts to /tmp/hosts.{{ random_number1 }}
    copy: src=/etc/hosts dest=/tmp/hosts.{{ random_number1 }}
    notify:
      - call in every action
  - name: Copy the /etc/hosts to /tmp/hosts.{{ random_number2 }}
    copy: src=/etc/hosts dest=/tmp/hosts.{{ random_number2 }}
    notify:
      - call in every action

  handlers:
  - name: call in every action
    debug: msg="call in every action, but execute only one time"
  • action是Changed ,才会执行handler

只有当TASKS种的action的执行状态是changed时,才会触发notify handler的执行。
下面的脚本执行两次,执行结果是不同的:
第一次执行是,tasks的状态都是changed,会触发两个handler
第二次执行是,
第一个task的状态是OK,那么不会触发handlers"call by /tmp/hosts",
第二个task的状态是changed,触发了handler"call by /tmp/hosts.random_number"

//示例代码
---
- hosts: lb
  remote_user: root
  vars:
      random_number: "{{ 10000 | random }}"
  tasks:
  - name: Copy the /etc/hosts to /tmp/hosts
    copy: src=/etc/hosts dest=/tmp/hosts
    notify:
      - call by /tmp/hosts
  - name: Copy the /etc/hosts to /tmp/hosts.{{ random_number }}
    copy: src=/etc/hosts dest=/tmp/hosts.{{ random_number }}
    notify:
      - call by /tmp/hosts.random_number

  handlers:
  - name: call by /tmp/hosts
    debug: msg="call first time"
  - name: call by /tmp/hosts.random_number
    debug: msg="call by /tmp/hosts.random_number"
  • 按Handler的定义顺序执行

andlers是按照在handlers中定义个顺序执行的,而不是安装notify的顺序执行的。
下面的例子定义的顺序是1>2>3,notify的顺序是3>2>1,实际执行顺序:1>2>3

---
- hosts: lb
  remote_user: root
  gather_facts: no
  vars:
      random_number1: "{{ 10000 | random }}"
      random_number2: "{{ 10000000000 | random }}"
  tasks:
  - name: Copy the /etc/hosts to /tmp/hosts.{{ random_number1 }}
    copy: src=/etc/hosts dest=/tmp/hosts.{{ random_number1 }}
    notify:
      - define the 3nd handler
  - name: Copy the /etc/hosts to /tmp/hosts.{{ random_number2 }}
    copy: src=/etc/hosts dest=/tmp/hosts.{{ random_number2 }}
    notify:
      - define the 2nd handler
      - define the 1nd handler

  handlers:
  - name: define the 1nd handler
    debug: msg="define the 1nd handler"
  - name: define the 2nd handler
    debug: msg="define the 2nd handler"
  - name: define the 3nd handler
    debug: msg="define the 3nd handler"

4、变量
playbook中常用变量的几种情况:

  • 用户自定义的变量

用户可以在Playbook中,通过vars关键字自定义变量,使用时用{{ }}引用以来即可。
示例:

---
- hosts: web
  vars:
    http_port: 80
  remote_user: root
  tasks:
  - name: insert firewalld rule for httpd
    firewalld: port={{ http_port }}/tcp permanent=true state=enabled immediate=yes
  • 把变量放在单独的文件中

当变量比较多的时候,或者变量需要在多个playbook中重用的时候,可以把变量放到一个单独的文件中。通过关键字var_files把文件中定义的变量引入playbook中,使用变量的方法和在本文件中定义的变量相同。

- hosts: web
  remote_user: root
  vars_files:
      - vars/server_vars.yml
  tasks:
  - name: insert firewalld rule for httpd
    firewalld: port={{ http_port }}/tcp permanent=true state=enabled immediate=yes

#cat vars/server_vars.yml
http_port: 80

定义复杂的变量
当变量的值不是简单的字符串或者数字,而是一个字典,语法如下

foo:
  field1: one
  field2: two

访问复杂变量中的子属性,可以利用中括号或者点号:

foo['field1']
或
foo.field1
  • 系统变量(facts)

ansible会通过module setup来收集主机的系统信息,这些收集到的系统信息叫做facts,这些facts信息可以直接以变量的形式使用。
有哪些facts变量可以引用呢?在命令行上通过调用setup module命令可以查看:

$ ansible all -m setup -u root

系统变量在playbook中可以直接使用:

---
- hosts: all
  user: root
  tasks:
  - name: echo system
    shell: echo {{ ansible_os_family }}
  - name install ntp on Debian linux
    apt: name=git state=installed
    when: ansible_os_family == "Debian"
  - name install ntp on redhat linux
    yum: name=git state=present
    when: ansible_os_family == "RedHat"

对于复杂的、多层级的facts变量,可以通过下面的两种方式的任意一种访问复杂的变量中的子属性:
中括号:

{{ ansible_ens3["ipv4"]["address"] }}

点号:

{{ ansible_ens3.ipv4.address }}

关系facts变量,一旦关闭之后就不用调用了。关闭方法:

- hosts: webserver
  gather_facts: no
  • 注册变量

把task的执行结果也可以作为一个变量值。这个时候就需要用到“注册变量”,将执行结果注册到一个变量中,待后面的action使用。

---
- hosts: web
  tasks:
     - shell: ls
       register: result
       ignore_errors: True
     - shell: echo "{{ result.stdout }}"
       when: result.rc == 5
     - debug: msg="{{ result.stdout }}"

注册变量经常和debug module一起使用,这样可以得到更多action的输出信息,帮助用户调试。

  • 命令行中传递的变量

为了使Playbook更灵活、通用性更强,允许用户在执行的时候传入变量的值,这个时候就需要用到“额外变量”。
定义命令行变量
在test.yml文件里,hosts和user都定义为变量,需要从命令行传递变量值。

---
- hosts: '{{ hosts }}'
  remote_user: '{{ user }}'
  tasks:
  ...

在命令行里面传值得的方法:

ansible-playbook testyml --extra-vars "hosts=web user=root"

还可以用json格式传递参数:

ansible-playbook test.yml --extra-vars "{'hosts':'vm-rhel7-1', 'user':'root'}"

还可以将参数放在文件里面:

ansible-playbook test.yml --extra-vars "@vars.json"

5、如何执行playbook

语法:

$ ansible-playbook deploy.yml

查看输出的细节

$ ansible-playbook playbook.yml --verbose

查看该脚本影响哪些hosts

$ ansible-playbook playbook.yml --list-hosts

并行执行脚本

$ ansible-playbook playbook.yml -f 10

四、playbooks的高级用法
1、逻辑控制

  • when: 条件判断语句,类似于变成语言中的if

主机为Debian Linux立刻关机:

tasks:
  - name: "shutdown Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_os_family == "Debian"

根据action的执行结果,来决定接下来执行的action

tasks:
  - command: /bin/false
    register: result
    ignore_errors: True
  - command: /bin/something
    when: result|failed
  - command: /bin/something_else
    when: result|success
  - command: /bin/still/something_else
    when: result|skipped

远程中的系统变量facts变量作为when的条件,用“|int”还可以转换返回值的类型:

---
- hosts: web
  tasks:
    - debug: msg="only on Red Hat 7, derivatives, and later"
      when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6

条件表达式

基本:

tasks:
    - shell: echo "This certainly is epic!"
      when: epic

否定:

tasks:
    - shell: echo "This certainly isn't epic!"
      when: not epic

变量定义:

tasks:
    - shell: echo "I've got '{{ foo }}' and am not afraid to use it!"
      when: foo is defined
    - fail: msg="Bailing out. this play requires 'bar'"
      when: bar is not defined

数值表达:

tasks:
    - command: echo {{ item }}
      with_items: [ 0, 2, 4, 6, 8, 10 ]
      when: item > 5

与Include一起用:

- include: tasks/sometasks.yml
  when: "'reticulating splines' in output"

与Role一起用:

- hosts: webservers
  roles:
     - { role: debian_stock_config, when: ansible_os_family == 'Debian' }
  • loop: 循环语句,类似于编程语言的中的while

标准循环
为了保持简洁,重复的任务可以用以下简写的方式:

- name: add several users
  user: name={{ item }} state=present groups=wheel
  with_items:
     - testuser1

如果你在变量文件中或者 'vars' 区域定义了一组YAML列表,你也可以这样做:

vars:
  somelist: ["testuser1", "testuser2"]
tasks:
  -name: add several user
   user: name={{ item }} state=present groups=wheel
   with_items: "{{somelist}}"

使用 'with_items' 用于迭代的条目类型不仅仅支持简单的字符串列表.如果你有一个哈希列表,那么你可以用以下方式来引用子项:

- name: add several users
  user: name={{ item.name }} state=present groups={{ item.groups }}
  with_items:
    - { name: 'testuser1', groups: 'wheel' }
    - { name: 'testuser2', groups: 'root' }

注意:如果同时使用 when 和 with_items (或其它循环声明),when声明会为每个条目单独执行。

嵌套循环:

- name: give users access to multiple databases
  mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
  with_nested:
    - [ 'alice', 'bob' ]
    - [ 'clientdb', 'employeedb', 'providerd']
或者
- name: give users access to multiple databases
  mysql_user: name={{ item.0 }} priv={{ item.1 }}.*:ALL append_privs=yes password=foo
  with_nested:
    - [ 'alice', 'bob' ]
    - [ 'clientdb', 'employeedb', 'providerd']

对字典使用循环:

---
vars:
  users:
    alice:
      name: Alice Appleworth
      telephone: 123-456-7890
    bob:
      name: Bob Bananarama
      telephone: 987-654-3210
tasks:
  - name: Print phone records
    debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
    with_dict: "{{users}}"

对文件列表使用循环
with_fileglob 可以以非递归的方式来模式匹配单个目录中的文件.如下面所示:

tasks:
    # first ensure our target directory exists
    - file: dest=/etc/fooapp state=directory
    # copy each file over that matches the given pattern
    - copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600
      with_fileglob:
        - /playbooks/files/fooapp/*
  • block: 把几个tasks组成一块代码,便于针对一组操作的异常处理等操作。

多个action组装成块,可以根据不同条件执行一段语句 :

tasks:
     - block:
         - yum: name={{ item }} state=installed
           with_items:
             - httpd
             - memcached
         - template: src=templates/src.j2 dest=/etc/foo.conf
         - service: name=bar state=started enabled=True
       when: ansible_distribution == 'CentOS'
       become: true
       become_user: root

组装成块处理异常更方便:

tasks:
  - block:
      - debug: msg='i execute normally'
      - command: /bin/false
      - debug: msg='i never execute, cause ERROR!'
    rescue:
      - debug: msg='I caught an error'
      - command: /bin/false
      - debug: msg='I also never execute :-('
    always:
      - debug: msg="this always executes"

2、重用playbook

Playbook支持两种重用机制,一种是重用静态Playbook脚本,另外一种是类似于编程语言中函数的机制。

  • include语句 - 重用静态的Playbook脚本,使用起来简单、直接。

Include语句的功能,基本的代码重用机制。主要重用tasks。同时Include可将tasks分割成多个文件,避免Playbook过于臃肿,使用户更关注于整体的架构,而不是实现的细节上。
普通用法
像其它语言的Include语句一样,直接Include:

---
# possibly saved as tasks/firewall_httpd_default.yml

  - name: insert firewalld rule for httpd
    firewalld: port=80/tcp permanent=true state=enabled immediate=yes
main.yml文件中调用include的方法:
tasks:
    - include: tasks/firewall_httpd_default.yml

高级用法-使用参数
include文件中还可以定义参数
被include的文件tasks/firewall_httpd_default.yml中,使用{{ port }}定义了一个名字为port的参数。

---
  - name: insert firewalld rule for httpd
    firewalld: port={{ port }}/tcp permanent=true state=enabled immediate=yes

传参数的各种方法
在执行的playbook传参数,可以加在行尾,使用空格分隔:

tasks:
  - include: tasks/firewall.yml port=80
  - include: tasks/firewall.yml port=3260
  - include: tasks/firewall.yml port=423

还可以使用yml的字典传参数:

tasks:
  - include: wordpress.yml
    vars:
        wp_user: timmy
        ssh_keys:
          - keys/one.txt
          - keys/two.txt

还可以把一条task简写成成一个类JSON的形式传参数:

 - { include: wordpress.yml, wp_user: timmy, ssh_keys: [ 'keys/one.txt', 'keys/two.txt' ] }

当然在playbook中已经定义了的参数,就不需要再显示传入值了,可以直接写成下面的:

---
- hosts: lb
  vars:
    port: 3206
  remote_user: root
  tasks:
    - include: tasks/firewall.yml
  • role语言 - Playbook的"函数机制",使用方法稍复杂、功能强大。是Playbook脚本的共享平台ansible galaxy主要的分享方式

Role是比include更强大灵活的代码重用和分享机制。Include类似于编程语言中的include,是重用单个文件的,功能有限。
而Role类似于编程语言中的“Package”,可以重用一组文件形成完整的功能。例如安装和配置apache,需要tasks实现安装包和拷贝模版等,httpd.conf和index.html的模版文件,和handler文件实现重起功能。这些文件都可以放在一个role里面,供不同的playbook文件重用。
Ansible非常提倡在playbook中使用role,并且提供了一个分享role的平台Ansible Galaxy, https://galaxy.ansible.com/, 在galaxy上可以找到别人写好的role。
在ansible中,通过遵循特定的目录结构,就可以实现对role的定义:
下面的目录结构定义了一个role:名字为myrole。在site.yml,调用了这个role。
role的目录结构:

site.yml
roles/
├── myrole
    ├── tasks
    │   └── main.yml
    ├── handlers
    │   └── main.yml
    ├── defaults
    │   └── main.yml
    ├── vars
    │   └── main.yml
    ├── files
    ├── templates
    ├── README.md
    ├── meta
    │   └── main.yml
    └── tests
        ├── inventory
        └── test.yml

site.yml中调用role

---
- hosts: webservers
  roles:
     - myrole

ansible并不要求role包含上述所有的目录及文件,根据role的功能需要加入对应的目录和文件。下面是每个目录和文件的功能。
如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中,所以这个文件也可以视作role的入口文件,想看role做了什么操作,可以从此文件看起。
如果 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
如果 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
如果 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中
roles/x/tasks/main.yml中所有tasks,可以引用 roles/x/{files,templates,tasks}中的文件,不需要指明文件的路径。
在写role的时候,一般都要包含role入口文件roles/x/tasks/main.yml,其它的文件和目录,可以根据需求选择加入。
参数在role中是如何定义的呢
定义一个带参数的role,名字是myrole,那么目录结构为:

 main.yml
 roles
   role_with_var
     tasks
       main.yml

在roles/myrole/tasks/main.yml中,使用{{ }}定义的变量就可以了

 ---
 - name: use param
   debug: msg="{{ param }}"

使用带参数的role
那么在main.yml就可以用如下的方法使用myrole

---
- hosts: webservers
  roles:
    - { role: myrole, param: 'Call some_role for the 1st time' }
    - { role: myrole, param: 'Call some_role for the 2nd time' }

或者写成YAML字典格式:

---
- hosts: webservers
  roles:
    - role: myrole
      param: 'Call some_role for the 1st time'
    - role: myrole
      param: 'Call some_role for the 2nd time'

role指定默认的参数
指定默认参数后,如果在调用时传参数了,那么就使用传入的参数值.如果调用的时候没有传参数,那么就使用默认的参数值.
指定默认参数很简单,以上面的role_with_var为例

main.yml
roles:
  myrole
    tasks
      main.yml
    defaults
      main.yml

在roles/myrole/defaults/main.yml中,使用yml的字典定义语法定义param的值,如下:
param: "I am the default value"
这样在main.yml中,下面两种调用方法都可以

---
- hosts: webservers
  roles:
    - role_with_var
    - { role: role_with_var, param: 'I am the value from external' }

role与条件语句when一起执行,下面的例子中,my_role只有在RedHat系列的server上才执行。

---
- hosts: webservers
  roles:
    - { role: my_role, when: "ansible_os_family == 'RedHat'" }
同样也可以写成YAML字典格式
---
- hosts: webservers
  roles:
    - role: my_role
      when: "ansible_os_family == 'RedHat'"
roles和tasks的执行顺序

如果一个playbook同时出现role和tasks,他们的调用顺序如下:
pre_tasks > role > tasks > post_tasks

---
- hosts: lb
  user: root
  pre_tasks:
    - name: pre
      shell: echo 'hello'
  roles:
    - { role: some_role }

  tasks:
    - name: task
      shell: echo 'still busy'

  post_tasks:
    - name: post
      shell: echo 'goodbye'
执行的结果为:
PLAY [lb] **********************************************************************


TASK [setup] *******************************************************************
ok: [rhel7u3]

TASK [pre] *********************************************************************
changed: [rhel7u3]

TASK [some_role : some role] ***************************************************
ok: [rhel7u3] => {
    "msg": "Im some role"
}

TASK [task] ********************************************************************
changed: [rhel7u3]

TASK [post] ********************************************************************
changed: [rhel7u3]

PLAY RECAP *********************************************************************
rhel7u3                    : ok=5    changed=3    unreachable=0    failed=0

3、tags的用法
如果playbook文件比较大,在执行的时候只是想执行部分功能,这个时候没有有解决方案呢?Playbook提供了tags便签可以实现部分运行。
tags的基本用法
例如,文件example.yml如何所示,标记了两个tag:packages和configuration

tasks:
  - yum: name={{ item }} state=installed
    with_items:
       - httpd
    tags:
       - packages
  - name: copy httpd.conf
    template: src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    tags:
       - configuration
  - name: copy index.html
    template: src=templates/index.html.j2 dest=/var/www/html/index.html
    tags:
       - configuration

那么我们在执行的时候,如果不加任何tag参数,那么会执行所有的tasks

$ ansible-playbook example.yml

指定执行安装部分的tasks,则可以利用关键字tags

$ ansible-playbook example.yml --tags "packages"

指定不执行packages部分的task,则可以利用关键字skip-tags

$ ansible-playbook example.yml --skip-tags "configuration"

特殊的Tags:“always”
tags的名字是用户自定义的,但是如果你把tags的名字定义为“always”,那么就有点特别了。只要在执行playbook时,没有明确指定不执行always tag,那么它就会被执行。
在下面的例子中,即使你只指定执行packages,那么always也会被执行。

tasks:
  - debug: msg="Always print this debug message"
    tags:
      - always
  - yum: name= state=installed
    with_items:
       - httpd
    tags:
       - packages
  - template: src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    tags:
       - configuration

指定运行packages时,还是会执行always tag对应的tasks

$ ansible-playbook tags_always.yml --tags "packages"
“tagged”,“untagged”和“all”
tasks:
  - debug: msg="I am not tagged"
    tags:
      - tag1
  - debug: msg="I am not tagged"
分别指定--tags为“tagged”,“untagged”和“all”试下效果吧:
$ ansible-playbook tags_tagged_untagged_all.yml --tags tagged
$ ansible-playbook tags_tagged_untagged_all.yml --tags untagged
$ ansible-playbook tags_tagged_untagged_all.yml --tags all

在include中和role中使用tags
include语句指定执行的tags的语法:

- include: foo.yml
  tags: [web,foo]

调用role中的tags的语法为:

roles:
  - { role: webserver, port: 5000, tags: [ 'web', 'foo' ] }

4、playbook文件加密

ansible-vault命令可以对配置文件进行基于密码的加密,防止敏感信息泄漏。

加密已存在文件

$ ansible-vault encrypt site.yml

加密并创建文件

$ ansible-vault create filename

执行加密后的playbook

$ ansible-playbook site.yml --ask-vault-pass

解密

$ ansible-vault decrypt site.yml

五、编译安装nginx的playbook的实例

playbooks目录结构:

$ tree playbooks
playbooks
├── group_vars
├── roles
│   └── nginx
│       ├── files
│       │   ├── nginx-1.8.0.tar.gz
│       │   └── pcre-8.33.tar.gz
│       ├── handlers
│       │   └── main.yml
│       ├── tasks
│       │   └── main.yml
│       └── templates
│           └── default.conf
└── site.yml

yml文件内内容如下:

$ cat playbooks/site.yml
---
- name: Install Nginx
  hosts: test
  user: admin

  roles:
    - nginx

$ cat playbooks/roles/nginx/tasks/main.yml
---
- name: Copy nginx software
  copy: src=nginx-1.8.0.tar.gz dest=/app/admin/soft/nginx-1.8.0.tar.gz

- name: Copy pcre software
  copy: src=pcre-8.33.tar.gz dest=/app/admin/soft/pcre-8.33.tar.gz

- name: Install Pcre
  shell: cd /app/admin/soft;tar zxf pcre-8.33.tar.gz;cd pcre-8.33;./configure;make;make install
  sudo: yes

- name: Install Nginx
  shell: cd /app/admin/soft;tar zxf nginx-1.8.0.tar.gz;cd nginx-1.8.0;./configure --user=admin --group=app --prefix=/app/admin/nginx --with-http_stub_status_module --with-http_ssl_module;make;make install

- name: Copy nginx configuration
  template: src=default.conf dest=/app/admin/nginx/conf/nginx.conf
  notify: restart nginx
[admin@wts-vm-01 ~]$ cat playbooks/roles/nginx/handlers/main.yml
---
- name: restart nginx
  shell: /app/admin/nginx/sbin/nginx
  sudo: yes

六、其它
官方例子
Ansible官方提供了一些比较常用的、经过测试的Playbook例子:
https://github.com/ansible/ansible-examples
Playbook分享平台:
https://galaxy.ansible.com/

相关文章: