HTML5, Android, Google+ и все такое Кирилл Сухов window.requestAnimationFrame = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame; var reqId = null; (function callback(time) { // Time is the UNIX time // Move element reqId = window.requestAnimationFrame(callback, opt_elem); })(); function draw(time) { paintScene(canvas); // Update models window.requestAnimationFrame(draw, canvas); } draw(); if (navigator.onLine) { console.log('ONLINE!'); } else { console.log('Connection flaky'); } ----------------------------------------------------------------------------------------------------------------- Почтовый сервер. Exim, Dovecot и RoundСube с интеграцией в Active Directory. Часть 1 Виталий Резников PERL_VERSION=5.10.1 # Exim PORTSDIR?= /usr/ports .if ${.CURDIR} == ${PORTSDIR}/mail/exim LOG_FILE_PATH?= syslog # Контентное сканирование WITH_CONTENT_SCAN= yes # Кодировка заголовков по умолчанию WITH_DEFAULT_CHARSET?= koi8-r # Отключаем IPv6 WITHOUT_IPV6= yes # Подключаем LDAP WITH_OPENLDAP= yes # Версия BDB – в чем Exim ведет свою базу «подсказок» WITH_BDB_VER= 4 # Проверки SPF WITH_SPF= yes # Подержка перекодировки (для заголовков) WITH_ICONV= yes .endif # cd /usr/ports/mail/exim # make config # make && make install && make clean # cd /usr/ports/security/clamav # make && make install && make clean # echo 'clamav_clamd_enable="YES"' >> /etc/rc.conf # /usr/local/etc/rc.d/clamav-clamd start # echo 'clamav_freshclam_enable="YES"' >> /etc/rc.conf ms01# /usr/local/etc/rc.d/clamav-freshclam.sh start sendmail_enable="NONE" sendmail /usr/local/sbin/exim send-mail /usr/local/sbin/exim mailq /usr/local/sbin/exim -bp newaliases /usr/local/sbin/exim -bi hoststat /usr/local/sbin/exim purgestat /usr/local/sbin/exim # /etc/rc.d/sendmail stop # echo 'exim_enable="YES"' >> /etc/rc.conf ########################################################### # MAIN CONFIGURATION SETTINGS ########################################################### # Имя хоста, как оно указано в MX-записи ДНС-зоны нашего внешнего домена. Используется в командах HELO, EHLO. # Если ничего не задать, то будет использоваться имя, которое вернет функция uname –n primary_hostname = mail.firma-market.ru # Списки доменов и хостов. К ним потом будем обращаться. # Символ @ – это специальная форма, означает имя локального хоста domainlist local_domains = @ # Делаем список доменов, обслуживаемых этим почтовым сервером. Далее этот список будет в виде +relay_to_domains domainlist relay_to_domains = firma-market.ru # Список сторонних доменов, из которых можно посылать письма на группы рассылки domainlist trust_domains = branch.ru # Если мы не планируем разрешать доступ к серверу снаружи (из Интернета) через MUA (Outlook, Thunderbird и т.д.), # то есть смысл составить список корпоративных подсетей и хостов, с которых разрешен релей (отправка писем в другие домены) hostlist local_net = 192.168.0.0/24 : 192.168.1.0/24 : 192.168.2.0/24 : 192.168.3.0/24 : 192.168.22.0/24 # Список хостов, с которых разрешена отправка писем без аутентификации. Как правило, это нужно для сервисов, # отправляющих различные уведомления администратору по почте,но не умеющих аутентифицироваться для этого hostlist nonauth_hosts = 192.168.0.11 : 192.168.0.10 : 192.168.0.8 : 192.168.0.17 : 192.168.0.19 : 192.168.0.250 # Определяем свои названия ACL и их типы (т.е. в какой части smtp-диалога будут применяться) acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_data # LDAP-серверы (контроллеры домена) ldap_default_servers = 192.168.0.4::389 : 192.168.0.2::389 # Макросы для поиска на сервере LDAP. По сути, это шаблоны, записанные для удобства покороче LDAP_AUTH = user="unix_ldap@firma-market" pass="qwas`1234" LDAP_BASE_SEARCH = ldap:///ou=Users,ou=FIRMA-MARKET,dc=firma-market LDAP_DOMAIN = firma-market LDAP_MAIL_FILTER = (&(!(userAccountControl:1.2.840.113556.1.4.803:=2))(objectClass=user)(mail=${quote_ldap:$local_part}${quote_ldap:@}${quote_ldap:$domain})) # Максимальный размер сообщения message_size_limit = 10M # Настройки логов # Убираем собственную временную метку Еxim из логов, ее будет ставить сам syslogd syslog_timestamp = no # Место для лог-файлов и принцип их именования (в названии будет полная дата) log_file_path = /var/log/exim/%s-%D.log # Системный фильтр обработки почты. С его помощью будем метить как SPAM нежелательные письма в конце обработки письма system_filter = /usr/local/etc/exim/filters/system-filter # Скрипт для встроенного Perl. Использую для групп рассылок perl_startup = do '/usr/local/etc/exim/scripts/group_distrib_AD.pl' ########################################################### # ACL CONFIGURATION # Specifies access control lists for incoming SMTP mail ########################################################### begin acl acl_check_rcpt: # Принимать сообщения, которые пришли с локалхоста (не по TCP/IP) # Кстати, так будет работать наш веб-клиент RoundСube accept hosts = : # Это правило блокирует адреса, локальные части которых начинаются или содержат знаки @ % ! / or |. # Проверяются локальные домены. В случае попадания под правило сообщение отвергается и устанавливается таймаут # следующих подключений для хоста-отправителя директивой delay deny message = Restricted characters in address domains = +relay_to_domains local_parts = ^[.] : ^.*[@%!/|] delay = 30s # Проверяем недопустимые символы для нелокальных получателей deny message = Restricted characters in address domains = !+relay_to_domains local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ delay = 30s # Принимаем почту от серверов, настроенных не по RFC из «белого» списка. Список нужен для серверов, # которые не пройдут фильтры ниже accept hosts = !+local_net : !localhost domains = +relay_to_domains condition = ${lookup{$sender_address_domain}wildlsearch\{/usr/local/etc/exim/db/whitelist}{yes}{no}} logwrite = OK! The host $sender_address_domainis in the WHITE list # Принимаем почту от хостов без аутентификации из списка accept hosts = +nonauth_hosts domains = +relay_to_domains # Устанавливаем в 0 переменную acl_c1. По ее значению дальше в системном фильтре будет установлено, # по какому правилу письмо было определено как SPAM. Краткая информация об этом будет помещена в исходник # письма, дабы помочь нам сразу понять, какое правило сработало на искомом письме warn set acl_c1 = 0 # Метим как SPAM те письма, хосты с которых они пришли не обменивается HELO/EHLO. # Значение переменной acl_c1 увеличивается и становится равным 1 warn condition = ${if eq{$sender_helo_name}{}{yes}{no}} logwrite = SPAM. Send HELO/EHLO and your name first set acl_c1 = ${eval:$acl_c1+1} # Запрещаем пользователям, у которых в свойствах учетки в поле Office («Комната») установлено значение TF # (можно придумать любое значение), посылать письма вне родительского домена. Используем атрибут # Active Directiory под названием physicalDeliveryOfficeName deny message = You are not allowed to send mail outside the own domain. hosts = +local_net : localhost domains = !+relay_to_domains condition = ${if eqi{TF}{${lookup ldapm{LDAP_AUTH\LDAP_BASE_SEARCH?physicalDeliveryOfficeName?sub?\(samaccountName=$sender_address_local_part)}}}{yes}{no}} # Принимаем сообщения от аутентифицированных пользователей, как правило, это MUAs accept hosts = +local_net : localhost authenticated = * control = dkim_disable_verify # Сразу разрываем подключение, если доменная часть адреса отправителя – наш домен drop message = Forbidden to send mail on behalf of users domain \$sender_address_domain hosts = !+local_net : !localhost condition = ${if match_domain{$sender_address_domain}\{$primary_hostname : +local_domains : +relay_to_domains}\{yes}{no}} # Начисляем очки за SPAM тем, кто подставляет IP-адрес вместо имени в команде HELO.Также проверяем, # не начислено ли ранее очков в нашу spam-переменную, чтобы не метить письмо дважды как SPAM warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} condition = ${if or {{ isip{$sender_helo_name}}\{eq{$sender_helo_name}{[$sender_host_address]}}}{yes}{no}} logwrite = SPAM. Forbidden to use IP-address instead of the host name in HELO set acl_c1 = ${eval:$acl_c1+2} # Начисляем очки за SPAM тем, кто подставляет имя нашего сервера в команде HELO warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} condition = ${if match_domain{$sender_helo_name}\{$primary_hostname : +local_domains : +relay_to_domains}{yes}{no}} logwrite = SPAM. In HELO a name of our server set acl_c1 = ${eval:$acl_c1+3} # Проверяем совпадение PTR и A записей DNS для хостов warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} condition = ${if eq{$host_lookup_failed}{1}{yes}{no}} logwrite = SPAM. Yours PTR and A records DNS do not conform et acl_c1 = ${eval:$acl_c1+4} # Проверяем соответствие имени из HELO и DNS записи для хостов. Отключил из-за частых ложных срабатываний. # Ну, не любят у нас админы соблюдать RFC #warn hosts = !+local_net : !localhost # condition = ${if eq{$acl_c1}{0}{yes}{no}} # condition = ${if !match_domain{$sender_host_name}\{$sender_helo_name}{yes}{no}} # logwrite = SPAM. Your DNS record does not conformity to name from HELO # set acl_c1 = ${eval:$acl_c1+5} # Начисляем очки за SPAM для хостов из «черного» списка. У меня обычно в списке доменные суффиксы особо # «спаммерских» национальных доменов типа .br, .it, и т.д., из которых у нас не бывает деловой корреспонденции warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} condition = ${lookup{$sender_host_name}wildlsearch\{/usr/local/etc/exim/db/blacklist}{yes}{no}} logwrite = SPAM. $sender_host_name in our local blacklist set acl_c1 = ${eval:$acl_c1+6} # Начисляем очки за SPAM для хостов, в имени которых число точек >= 4 или тире >= 5. Обычно такие названия # имеют хосты провайдеров домашнего Интернета... и, как выяснилось на практике, почтовые веб-хосты Yahoo. # Поэтому их исключаем warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} condition = ${if and {{match{$sender_host_name}\{\N(?>[^.]+[.]){5,}|(?>[^-]+[\-]){4,}\N}}\{!match{$sender_host_name}{\N\.yahoo\.com$\N}}}{yes}{no}} logwrite = SPAM. Too many point or hyphens in the hostname ($sender_host_name) set acl_c1 = ${eval:$acl_c1+7} # Начисляем очки за SPAM для хостов, имена которых похожи на dialup-хосты из нашего списка. # Также исключаем серверы Yahoo. warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} condition = ${if !match{$sender_host_name}{\N\.yahoo\.com$\N}{yes}{no}} condition = ${lookup{$sender_host_name}\ wildlsearch{/usr/local/etc/exim/db/dialup_hosts}{yes}{no}} logwrite = SPAM. $sender_host_name possibly represents dialup host set acl_c1 = ${eval:$acl_c1+8} # Проверяем хост-отправитель в общедоступных «черных» списках RBL и DNSBL warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} dnslists = cbl.abuseat.org : sbl-xbl.spamhaus.org : bl.spamcop.net logwrite = SPAM. You in blacklist - $dnslist_domain --> $dnslist_text; $dnslist_value set acl_c1 = ${eval:$acl_c1+9} # Начисляем очки за SPAM, если SPF-запись для адреса хоста вернула FAIL warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} spf = fail logwrite = SPAM. SPF check failed: $sender_host_address is not allowed to send mail from $sender_address_domain set acl_c1 = ${eval:$acl_c1+10} # Callback или «обратный вызов». Попытка проверить на существование адрес отправителя в процессе получения # сообщения. Как правило, помогает от несуществующих почтовых адресов warn hosts = !+local_net : !localhost condition = ${if eq{$acl_c1}{0}{yes}{no}} !verify = sender/no_details/callout=15s logwrite = SPAM. $acl_verify_message: $sender_address - does not exist set acl_c1 = ${eval:$acl_c1+11} # Принудительная задержка в виде таймаута для борьбы со SPAM-скриптами warn hosts = !+local_net : !localhost delay = 20s # Разрешаем письма, адресованные в наш домен accept domains = +relay_to_domains hosts = !+local_net : !localhost # Запрещаем все остальное drop message = Access deny - this not open relay! ----------------------------------------------------------------------------------------------------------------- Postfix – быстро, дешево, удобно. Почтовый сервер для компаний, где экономят на ИТ Игорь Решетов apt-get install mc ssh –y apt-get install postfix postfix-ldap mkdir /etc/postfix/ad mcedit /etc/postfix/ad/users.cf version = 3 server_host = ldap://kdc.papa-papa.ru search_base = dc=papa-papa, dc=ru query_filter = (&(objectclass=person)(mail=%s)) result_attribute = mail result_format = %s/Maildir/ bind = yes bind_dn = mail-user@papa-papa.ru bind_pw = password mcedit /etc/postfix/ad/groups.cf version = 3 server_host = ldap://kdc.papa-papa.ru search_base = dc=papa-papa, dc=ru query_filter = (&(objectclass=group)(mail=%s)) leaf_result_attribute = mail special_result_attribute = member bind = yes bind_dn = mail-user@papa-papa.ru bind_pw = password mcedit /etc/postfix/main.cf # Указываем конфигурационные файлы для общения с сервером AD local_recipient_maps = proxy:ldap:/etc/postfix/ad/users.cf virtual_alias_maps = proxy:ldap:/etc/postfix/ad/groups.cf #Какие виртуальные домены обслуживать virtual_mailbox_domains = $mydomain #Куда складывать почту virtual_mailbox_base = /var/mail/ #От чьего имени запускать Рostfix virtual_uid_maps = static:1001 virtual_gid_maps = static:1001 # Указываем тип smtp-авторизации smtpd_sasl_tls_security_options = $smtpd_sasl_security_options smtpd_sasl_security_options = noanonymous virtual_minimum_uid = 1001 #Указываем тип транспорта local_transport = dovecot dovecot_destination_recipient_limit = 1 #Указываем, как и с помощью чего производить smtp-авторизацию smtpd_sasl_auth_enable = yes smtpd_sasl_exceptions_networks = $mynetworks broken_sasl_auth_clients = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth # Указываем, что нужно представиться smtpd_helo_required = yes #Указываем правила, какие письма принимать, а какие #откидывать. (Защищает от СПАМА) smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unknown_helo_hostname, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unlisted_recipient, permit_auth_destination, reject_unauth_destination, reject_rbl_client bl.spamcop.net, reject_rbl_client cbl.abuseat.org, reject_rbl_client psbl.surriel.com, reject_rbl_client spamsources.fabel.dk, reject_rbl_client opm.blitzed.org, reject_rbl_client combined.njabl.org, reject_rbl_client dul.ru, reject_rbl_client dnsbl.sorbs.net, reject_rhsbl_sender rhsbl.sorbs.net, reject_rhsbl_client rhsbl.sorbs.net, reject_rhsbl_sender block.rhs.mailpolice.com reject_rhsbl_client block.rhs.mailpolice.com reject_unknown_client, reject_authenticated_sender_login_mismatch, reject_non_fqdn_sender, reject_sender_login_mismatch, reject_unauthenticated_sender_login_mismatch, reject_unlisted_sender, reject_unverified_sender, reject_unknown_sender_domain #Указываем, чьи письма обрабатывать в первую очередь. smtpd_etrn_restrictions=permit_mynetworks, reject #Защита от массовой рассылки smtpd_data_restrictions = reject_unauth_pipelining #Максимальный размер письма message_size_limit=51200000 /etc/init.d/postfix restart postmap -q "test@papa-papa.ru" ldap:/etc/postfix/ad/ad.cf apt-get install dovecot-common dovecot-imapd dovecot-pop3d mcedit /etc/dovecot/dovecot.conf base_dir = /var/run/dovecot/ protocols = imap pop3 disable_plaintext_auth = no ssl = no login_dir = /var/run/dovecot/login mail_location = maildir:/var/mail/%d/%n maildir_copy_with_hardlinks = yes protocol imap { mail_plugin_dir = /usr/lib/dovecot/modules/imap } protocol pop3 { mail_plugin_dir = /usr/lib/dovecot/modules/pop3 } protocol lda { postmaster_address = postmaster@papa-papa.ru mail_plugins = sieve mail_plugin_dir = /usr/local/lib/dovecot/lda auth_socket_path = /var/run/dovecot/auth-master } auth_executable = /usr/lib/dovecot/dovecot-auth auth_verbose = yes auth_debug = yes auth_debug_passwords = yes auth default { mechanisms = login plain passdb ldap { args = /etc/dovecot/dovecot-ldap.conf } userdb static { args = uid=1001 gid=1001 home=/home/vmail/%u } user = root socket listen { master { path = /var/run/dovecot/auth-master mode = 0666 } client { path = /var/run/dovecot/auth-client mode = 0666 } } } protocol managesieve { managesieve_implementation_string = dovecot } mcedit /etc/dovecot/dovecot-ldap.conf hosts = kdc.papa-papa.ru:3268 dn = mail-user@PAPA-PAPA.RU dnpass = password auth_bind = yes ldap_version = 3 base = dc=PAPA-PAPA,dc=RU deref = never scope = subtree default_pass_scheme = CRYPT pass_filter = (&(objectclass=user)(mail=%n@%d)) groupadd -g 1001 vmail useradd -g vmail -u 1001 vmail mcedit /etc/postfix/master.cf maildrop unix – n n – - pipe flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient} apt-get install apache2 libapache2-mod-php5 mysql-server-5.1 mysql-client-5.1 php5-mysql libpcre3 libgd2-xpm php5-dev libmagic-dev php5 php5-mcrypt php5-intl mcedit /etc/php5/apache2/php.ini memory_limit = 128M file_uploads = On session.auto_start = 0 zend.ze1_compatibility_mode = Off date.timezone = "Europe/Moscow" cd /var/www/ wget http://roundcube.ru/download/roundcubemail-0.5.3.tar.gz tar xzfv roundcubemail-0.3.1.tar.gz mv roundcubemail-0.3.1 mail rm roundcubemail-0.3.1.tar.gz cd /var/www/ chown www-data.www-data /var/www/logs chmod 755 /var/www/logs chown www-data.www-data /var/www/temp/ chmod 755 /var/www/temp # chown -R www-data.www-data /var/www/config # chmod 755 /var/www/config # mysql -u root –p mysql> CREATE DATABASE roundcubemail /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; mysql> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'password'; mysql> flush privileges; mysql> \q # mysql roundcubemail -p < SQL/mysql.initial.sql ----------------------------------------------------------------------------------------------------------------- Виртуальное рабочее место с помощью VMware View 5.0. Часть 1 Антон Борисов netdom join vmview2008 /domain:dcpromo.net /userd:dcpromo\adm /passwordd:MyPass netdom query /domain:dcpromo.net /server:vm2003 /userd:adm /passwordd:MyPass trust netsh interface ip reset C:\Users\Администратор\Documents>powershell PS C:\Users\Администратор\Documents> get-executionPolicy PowerShell -Command "& {set-executionPolicy Unrestricted}" ----------------------------------------------------------------------------------------------------------------- Универсальный сервер сетевой загрузки и установки. Часть 3 Сергей Крутских label winpe7 menu label ^WinPE WIN7 kernel sources/pxeboot.0] mount -o loop /home/iso/winpe7.iso /home/temp/pe7 label freedos menu label ^FreeDOS+MHDD util kernel memdisk append initrd=pe/freedos.ima ----------------------------------------------------------------------------------------------------------------- Openbravo – свободная ERP Сергей Яремчук $ sudo add-apt-repository "deb http://archive.canonical.com/ubuntu natty partner" $ sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu natty partner" $ sudo apt-get update $ sudo apt-cache show openbravo-3 | grep -i version $ sudo apt-get install openbravo-3 $ cat AD_MESSAGE_TRL_ru_RU.xml Product Info Информация о продукте ----------------------------------------------------------------------------------------------------------------- Windows PowerShell 3. Взгляд администратора Иван Коробко Powershell.exe -? ----------------------------------------------------------------------------------------------------------------- Ganglia. Система мониторинга для кластеров Константин Кондаков #./configure # make && make install ./configure --prefix=/opt/ganglia # ./configure --prefix=/opt/rrd --exec-prefix=/opt/rrd # make && make install # ./configure --with-gmetad --prefix=/opt/ganglia --exec-prefix=/opt/ganglia_linux --with-librrd=/opt/rrd/ #make && make install # mkdir -p /opt/ganglia/etc && useradd monitor && passwd-l monitor && mkdir -p /var/ganglia/lib && cd / && tar xzvf /tmp/ganglia_lib.tgz && ldconfig && cp /tmp/web_gmond.conf /opt/ganglia/etc/app_gmond.conf && cp /tmp/gmond /opt/ganglia/ && mkdir -p /opt/ganglia_linux/lib64/ganglia && cd /opt/ganglia_linux/lib64/ && tar xzvf /tmp/ganglib.tgz mcast_join = 224.0.0.1 port = 8649 # netstat -ang globals { daemonize = yes setuid = yes user = nobody debug_level = 0 max_udp_msg_len = 1472 mute = no deaf = no allow_extra_data = yes host_dmax = 0 /*secs */ host_tmax = 20 /*secs */ cleanup_threshold = 300 /*secs */ gexec = no send_metadata_interval = 0 /*secs */ } cluster { name = "web" owner = "unspecified" latlong = "unspecified" url = "unspecified" } host { location = "San Francisco" } udp_send_channel { mcast_join = 224.0.0.1 port = 8649 ttl = 1 } udp_recv_channel { mcast_join = 224.0.0.1 port = 8649 bind = 224.0.0.1 } tcp_accept_channel { port = 8649 } modules { module { name = "core_metrics" } module { name = "cpu_module" path = "modcpu.so" } module { name = "disk_module" path = "moddisk.so" } module { name = "load_module" path = "modload.so" } module { name = "mem_module" path = "modmem.so" } module { name = "net_module" path = "modnet.so" } module { name = "proc_module" path = "modproc.so" } module { name = "sys_module" path = "modsys.so" } collection_group { collect_once = yes time_threshold = 20 metric { name = "heartbeat" } } collection_group { collect_once = yes time_threshold = 1200 metric { name = "cpu_num" title = "CPU Count" } metric { name = "cpu_speed" title = "CPU Speed" } metric { name = "mem_total" title = "Memory Total" } metric { name = "swap_total" title = "Swap Space Total" } metric { name = "boottime" title = "Last Boot Time" } metric { name = "machine_type" title = "Machine Type" } metric { name = "os_name" title = "Operating System" } metric { name = "os_release" title = "Operating System Release" } metric { name = "location" title = "Location" } } collection_group { collect_once = yes time_threshold = 300 metric { name = "gexec" title = "Gexec Status" } } collection_group { collect_every = 20 time_threshold = 90 /* CPU status */ metric { name = "cpu_user" value_threshold = "1.0" title = "CPU User" } metric { name = "cpu_system" value_threshold = "1.0" title = "CPU System" } metric { name = "cpu_idle" value_threshold = "5.0" title = "CPU Idle" } metric { name = "cpu_nice" value_threshold = "1.0" title = "CPU Nice" } metric { name = "cpu_aidle" value_threshold = "5.0" title = "CPU aidle" } metric { name = "cpu_wio" value_threshold = "1.0" title = "CPU wio" } . metric { name = "cpu_intr" value_threshold = "1.0" title = "CPU intr" } metric { name = "cpu_sintr" value_threshold = "1.0" title = "CPU sintr" } } collection_group { collect_every = 20 time_threshold = 90 /* Load Averages */ metric { name = "load_one" value_threshold = "1.0" title = "One Minute Load Average" } metric { name = "load_five" value_threshold = "1.0" title = "Five Minute Load Average" } metric { name = "load_fifteen" value_threshold = "1.0" title = "Fifteen Minute Load Average" } } collection_group { collect_every = 80 time_threshold = 950 metric { name = "proc_run" value_threshold = "1.0" title = "Total Running Processes" } metric { name = "proc_total" value_threshold = "1.0" title = "Total Processes" } } include ("/data01/certain_software/ganglia/etc/conf.d/*.conf") #data_source "local" localhost data_source "web" web1:8650 data_source "app" app1:8649 RRAs "RRA:AVERAGE:0.5:1:5760" "RRA:AVERAGE:0.5:40:1008" "RRA:AVERAGE:0.5:120:1440" "RRA:AVERAGE:0.5:1200:1460" "RRA:AVERAGE:0.5:240:43800" gridname "Test" rrd_rootdir "/opt/rrds" case_sensitive_hostnames 0 #!/usr/bin/python # # # # # import os import sys import urllib2 import base64 from optparse import OptionParser from lxml import etree from lxml import objectify #try: # from cStringIO import StringIO #except: # from StringIO import StringIO def jvm_free_memory_handler(name): load_xml_data(params2) return int(xml_data_py.jvm.memory.get('free')) def jvm_total_memory_handler(name): load_xml_data(params2) return int(xml_data_py.jvm.memory.get('total')) def jvm_max_memory_handler(name): load_xml_data(params2) return int(xml_data_py.jvm.memory.get('max')) def connector_jk8009_maxthreads_handler(name): load_xml_data(params2) return int(jk8009.threadInfo.get('maxThreads')) def connector_jk8009_current_threads_count_handler(name): load_xml_data(params2) return int(jk8009.threadInfo.get('currentThreadCount')) def connector_jk8009_current_threads_busy_handler(name): load_xml_data(params2) return int(jk8009.threadInfo.get('currentThreadsBusy')) def metric_init(params): global descriptors global xml_data_py, jk8009, jk8080, params2 params2 = params d1 = {'name': 'jvm_free_memory', 'call_back': jvm_free_memory_handler, 'time_max': 90, 'value_type': 'uint', 'units': 'bytes', 'slope': 'both', 'format': '%d', 'description': 'JVM Free Memory', 'groups': 'tomcat'} d2 = {'name': 'jvm_total_memory', 'call_back': jvm_total_memory_handler, 'time_max': 90, 'value_type': 'uint', 'units': 'bytes', 'slope': 'both', 'format': '%d', 'description': 'JVM Total Memory', 'groups': 'tomcat'} d3 = {'name': 'jvm_max_memory', 'call_back': jvm_max_memory_handler, 'time_max': 90, 'value_type': 'uint', 'units': 'bytes', 'slope': 'both', 'format': '%d', 'description': 'JVM Max Memory', 'groups': 'tomcat'} d4 = {'name': 'connector_jk8009_maxthreads', 'call_back': connector_jk8009_maxthreads_handler, 'time_max': 90, 'value_type': 'uint', 'units': 'threads', 'slope': 'both', 'format': '%d', 'description': 'JK8009 connector Max Threads', 'groups': 'tomcat'} d5 = {'name': 'connector_jk8009_current_threads_count', 'call_back': connector_jk8009_current_threads_count_handler, 'time_max': 90, 'value_type': 'uint', 'units': 'threads', 'slope': 'both', 'format': '%d', 'description': 'JK8009 connector Current Threads Count', 'groups': 'tomcat'} d6 = {'name': 'connector_jk8009_current_threads_busy', 'call_back': connector_jk8009_current_threads_busy_handler, 'time_max': 90, 'value_type': 'uint', 'units': 'threads', 'slope': 'both', 'format': '%d', 'description': 'JK8009 connector Current Threads Busy', 'groups': 'tomcat'} descriptors = [d1, d2, d3, d4, d5, d6] return descriptors def metric_cleanup(): '''Clean up the metric module.''' pass def load_xml_data(params): global xml_data_py, jk8009, jk8080 theurl = "http://127.0.0.1:8080/manager/status?XML=true" username = 'admin' password = 'password' req = urllib2.Request(theurl) realm = 'Apache Tomcat/4.1.27' base64string = base64.encodestring('%s:%s' % (username, password))[:-1] authheader = "Basic %s" % base64string req.add_header("Authorization", authheader) # create "opener" (OpenerDirector instance) handle = urllib2.urlopen(req) print "getting data..." + theurl xml_data = handle.read() #print xml_data xml_data_py = parse_xml_data(xml_data) #print "XML" #print xml_data_py for connector in xml_data_py.connector: # if connector.get('name') == params['name8009']: jk8009 = connector # if connector.get('name') == params['name8009']: # jk8080 = connector return def parse_xml_data(xml_data): xml_data_py = objectify.fromstring(xml_data) return xml_data_py if __name__ == '__main__': params = { 'hostname' : '127.0.0.1', 'port' : '8080', 'username' : 'admin', 'password' : 'password, 'groups' : 'tomcat', 'name8080' : 'http-bio-8080', 'name8009' : 'ajp-bio-8009'} metric_init(params) for d in descriptors: v = d['call_back'](d['name']) print 'value for %s is %u' % (d['name'], v) modules { module { name = "tomcat" language = "python" param hostname { value = '127.0.0.1' } param port { value = '8080' } param name8080 { value = 'jk-8080' } param name8009 { value = 'jk-8009' } param username { value = 'admin' } param password { value = 'password’ } param groups { value = 'tomcat' } } } collection_group { collect_every = 60 time_threshold = 180 metric { name = "jvm_free_memory" title = "JVM Free Memory" value_threshold = 2000000 } metric { name = "jvm_total_memory" title = "JVM Max Memory" #value_threshold = 2000000 } metric { name = "jvm_total_memory" title = "JVM Total Memory" #value_threshold = 2000000 } metric { name = "jvm_max_memory" title = "JVM Max Memory" #value_threshold = 2000000 } metric { name = "connector_jk8009_maxthreads" title = "JK8009 connector Max Threads" value_threshold = 50 } metric { name = "connector_jk8009_current_threads_count" title = "JK8009 connector Current Threads" value_threshold = 20 } metric { name = "connector_jk8009_current_threads_count" title = "JK8009 connector Current Threads" value_threshold = 20 } metric { name = "connector_jk8009_current_threads_busy" title = "JK8009 connector Busy Threads" value_threshold = 20 } } modules { module { name = "python_module" path = "/usr/lib(64)/ganglia/modpython.so" params = "/usr/lib(64)/ganglia/python_modules" } } include('/etc/ganglia/conf.d/*.pyconf') ----------------------------------------------------------------------------------------------------------------- SQL или NoSQL – вот в чем вопрос. Программное окружение MySQL. Часть 2 Игорь Савчук ./configure --with-mysql-source=... --with-mysql-bindir=... ; make; make install mysql> INSTALL PLUGIN 'HandlerSocket' soname 'HandlerSocket.so'; mysql> SHOW PROCESSLIST; # Номер порта, на котором ожидаются запросы на чтение loose_handlersocket_port = 9998 # Номер порта, на котором ожидаются запросы на запись loose_handlersocket_port_wr = 9999 # Количество рабочих потоков (для запросов по чтению) loose_handlersocket_threads = 16 # Количество рабочих потоков (для запросов по записи) loose_handlersocket_threads_wr = 1 # Максимальное количество разрешенных конкурентных соединений open_files_limit = 65535 handlersocket_plain_secret = YOUR_PASS handlersocket_plain_secret_wr = YOUR_PASS P ‘+’ ... CREATE TABLE 'test'.'test' ( 'keyid' varchar(30), 'value' varchar(30), PRIMARY KEY ('keyid') ) telnet 192.168.1.10 9999 //Инициализируем канал, подключились к модифицирующему потоку (порт 9999) P 0 test test PRIMARY keyid,value //0 1 – открытие канала с данными параметрами прошло успешно //Используем вызов FIND_MODIFY для канала 0. Здесь по порядку идут: //номер канала (0), тип операции (=), количество ключей (1), //значение, которое ищем (в нашем случае – 5555), //код операции – D (то есть удаление всего найденного) 0 = 1 5555 1 0 D //Запрос успешно выполнен (0 1), количество обработанных строк – 1 //Для открытого канала (0) делаем запрос на вставку данных //(vlen=2, значения колонок для вставки: 1111, 2222) 0 + 2 1111 2222 3333 //Запрос успешно выполнен (формат любого ответа – ) telnet 192.168.1.10 9998 P 0 test test PRIMARY keyid,value 0 = 1 77777 0 0 D P 1 test notest PRIMARY nokey,noval P 0 test test PRIMARY keyid,value 0 = 1 1 A 1 samag mysql> scripts/innodb_Memcached_config.sql; mysql> install plugin daemon_Memcached soname "libMemcached.so"; mysql> set session TRANSACTION ISOLATION LEVEL read uncommitted; mysql> INSERT INTO samag_test VALUES ('samag','it rules', 10, 200, NULL) [savgor@corelink_6]$ telnet 69.25.27.173 11211 get samag_test VALUE samag 10 8 END ----------------------------------------------------------------------------------------------------------------- Node: Express для веб-приложений Валентин Синицын npm install [-g] express mkdir vt100-2.0 && express ./vt100-2.0 && cd vt100-2.0 Листинг 1. Файл app.js (номера строк добавлены для удобства ссылок) /** * Module dependencies. */ 01: var express = require('express'); 02: var app = module.exports = express.createServer(); // Configuration 03: app.configure(function(){ 04: app.set('views', __dirname + '/views'); 05: app.set('view engine', 'jade'); 06: app.use(express.bodyParser()); 07: app.use(express.methodOverride()); 08: app.use(app.router); 09: app.use(express.static(__dirname + '/public')); }); 10: app.configure('development', function(){ 11: app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }); 12: app.configure('production', function(){ 13: app.use(express.errorHandler()); }); NODE_ENV=production node app.js // Routes app.get('/', function(req, res){ res.render('index', { title: 'Express' }); }); app.get('/', function(req, res){ res.render('index', { title: 'vt100 - Express' }); }); app.get('/login.html', function(req, res){ res.render('login', { title: 'Please Log in', messages: '' }); }); app.post('/login.html', function(req, resp){ if (req.body.username == 'val' && req.body.password == 'pw') { req.session.authenticated = true; req.session.user = {userName: req.body.username}; resp.redirect('/terminal.html'); } else { resp.render('login', { title: 'Please Log in', messages: 'Invalid username or password' }); } }); app.use(express.cookieParser()); app.use(express.session({ store: sessionStore, secret: 'your_secret_here', key: COOKIE_NAME })); var MemoryStore = express.session.MemoryStore, sessionStore = new MemoryStore(); const COOKIE_NAME = 'vt100.sid'; var util = require('util'); function NotAuthenticated(msg) { Error.call(this, msg); } util.inherits(NotAuthenticated, Error); exports.requestAuthentication = function(msg, callback) { return function(req, resp, next){ if (callback(req, resp)) { next(); } else { throw new NotAuthenticated(msg); } } }; exports.anonymousRedirect = function(url) { return function(err, req, res, next) { if (err instanceof NotAuthenticated) { res.redirect(url); } else { next(err); } } } app.use(auth.anonymousRedirect('/login.html')); Листинг 2. Использование промежуточного ПО auth var restricted = auth.requestAuthentication( 'Please authenticate', function (req, resp) { return req.session && req.session.authenticated; } ); app.get('/terminal.html', restricted, function(req, resp){ var user = req.session.user; resp.render('terminal', { layout: false, title: user.userName + '\'s Session', user: user }); }); !!! html head title= title link(rel='stylesheet', href='/stylesheets/style.css') script(src='/javascripts/VT100.js') script(src='/socket.io/socket.io.js') script(src='/javascripts/terminal.js') body(onload='start();', onunload='leave();') h1= title p Hello, #{user.userName}! div#terminal(tabindex='0') a.button(href='/logout.html') Log Out !!! html head title= title link(rel='stylesheet', href='/stylesheets/style.css') body!= body h1= title - if (messages && messages != '') div#messages= messages form.login(method='post') div label Username: input(type='text', name='username') div label Password: input(type='password', name='password') div input(type='submit', value='Log In') var sio = io.listen(app); app.listen(3000); sio.sockets.on('connection', function(socket) { ... console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); sio.set('authorization', function(handshake, callback) { if (handshake.headers.cookie) { var parseCookie = require('connect').utils.parseCookie; var sid = (parseCookie(handshake.headers.cookie))[COOKIE_NAME]; sessionStore.get(sid, function (err, session) { if (err) { callback(err.message, false); } else { if (!session || !session.authenticated) { callback('Not authenticated', false); } else { handshake.user = session.user; callback(null, true); } } }); } else { callback('No cookie found', false); } }); var app = module.exports = express.createServer({ key: fs.readFileSync('vt100-key.pem'), cert: fs.readFileSync('vt100-cert.pem') }); sio .configure('development', function () { }) .configure('production', function () { sio.set('log level', 1); }); ----------------------------------------------------------------------------------------------------------------- Шаблоны структур данных NoSQL. Приемы их использования на примере Tarantool Александр Календарев [1 , 'Hello Word'] memcached set (1, 'Hello Word' ) [ 1 , 'spb','Hello Word'] define('NS',0); $tnt = new Tarantool($host,$port); $tuple = array(1, 'Hello Word','alex', 1023 ); $res = $tnt->insert(NS,$tuple); var_dump($res); // true в случае успеха иначе false SELECT * FROM space WHERE k0=$key; define('PRIMARY',0); $count = $tnt->select(NS, PRIMARY,’11-22-33-55’); $res = $tnt->getTuple(); var_dump($count,$res); SELECT * FROM space WHERE k0=$key; define('FK_NAME',1); $count = $tnt->select(NS, FK_NAME,’Ваня’); while( ($res = $tnt->getTuple()) != false) { var_dump($res); } SELECT * FROM space WHERE key1='spb' define('FK_CITY',1); $count = $tnt-> select(NS, FK_CITY, 'spb'); while( ($res = $tnt->getTuple()) != false){ var_dump($res); } SELECT * FROM spaсe WHERE field2='spb' AND field3=’Ж’ define('IDX2',2); $count = $tnt-> select(NS, IDX2, array ('spb',’Ж’)); while( ($res = $tnt->getTuple()) != false){ var_dump($res); } CREATE SEQUENCE sq INCREMENT BY 1; define('NS_SYS',0); // Номер служебного space define('NS_USER',1); // Номер space USER define('INC_USER',2); // Номер ключа счетчика define('FD_COUNTER',1); // Номер поля счетчика // Получение значения счетчика $key= $tnt->inc(NS_SYS, INC_USER,FD_COUNTER, 1, true); // Вставка данных $tnt->insert(NS_USER, $key, $data); function box.auto_increment(spaceno, ...) max_tuple = box.space[spaceno].index[0].idx:max() if max_tuple ~= nil then max = box.unpack('i', max_tuple[0]) else max = -1 end return box.insert(spaceno, max + 1, ...) end SELECT * FROM t1 WHERE key0 IN ($key1, $key2, $key3…) $key = array(); for ($i=0; $imselect (NS, PK, $key); while( ($res = $tnt->getTuple()) != false){ var_dump($res); } define('NS_USER_TO_MAP',3); $key= $user_id << 32 + $map_id; $res = $tnt->select (NS_USER_TO_MAP, PK, $key); define('BEG_PTR',4); // номер ключа Beg Pointer $key= $tnt-> inc (NS, BEG _PTR, FD_COUNTER,1,true); $tnt->insert (NS_USER,$data); $res = $tnt->delete(NS, $key, [$flag]); define('END_PTR',5); // Номер ключа End Pointer // Увеличиваем End Pointer $key= $tnt-> inc (NS,END _PTR, FD_COUNTER,-1,true); // Удаляем старые данные $data = $tnt-> delete (NS_USER, $key, true); function fifo_push(name, val) fifo = find_or_create_fifo(name) top = box.unpack('i', fifo[1]) bottom = box.unpack('i', fifo[2]) if top == fifomax+2 then -- % size top = 3 … end return box.update(0, name, '=p=p=p', 1, top,2, bottom, top, val) end $res = $tnt->update($ns, $key, $array) $res = $tnt->inc(NS, $key, $fieldNo, [$delta, $flag]); ----------------------------------------------------------------------------------------------------------------- Раз-два-три, считаем в ритме вальса… Алексей Вторников CREATE TABLE declinations ( id INTEGER NOT NULL, -- Идентификатор description VARCHAR (32), -- Описание int056789 VARCHAR (32), -- Целая часть 0, [5...9] int1 VARCHAR (32), -- Целая часть 1 int234 VARCHAR (32), -- Целая часть [2...4] rat056789 VARCHAR (32), -- Дробная часть 0, [5...9] rat1 VARCHAR (32), -- Дробная часть 1 rat234 VARCHAR (32), -- Дробная часть [2...4] sexi CHAR (1), -- Род целой части sexr CHAR (1), -- Род дробной части PRIMARY KEY (id) ) INSERT INTO declinations VALUES (810,'Российский рубль', 'рублей','рубль','рубля', 'копеек','копейка','копейки','M', ‘F’) INSERT INTO declinations VALUES (980,'Украинская гривна', 'гривен','гривна','гривны', 'копеек','копейка','копейки','F', ‘F’) INSERT INTO declinations VALUES (484,'Мексиканское песо', 'песо','песо','песо', 'сентаво','сентаво','сентаво','S', ‘S’) и т.д. SELECT int056789,int1,int234,rat056789,rat1,rat234,sexi,sexr FROM declinations WHERE id = 980 INSERT INTO declinations VALUES (-956000,'Метр','метров','метр','метра','сантиметров','сантиметр','сантиметра','M', ‘M’) INSERT INTO declinations VALUES (-956001,'Яйцо куриное','яиц','яйцо','яйца','','','','S','') INSERT INTO declinations VALUES (-956002,'Колесо автомобильное','колес','колесо','колеса','','','','S','') INSERT INTO declinations VALUES (-956003,'Вагон ж/д','вагонов','вагон','вагона','','','','M','') и т.д. SELECT int056789,int1,int234,rat056789,rat1,rat234,sexi,sexr FROM declinations WHERE id = -956001 SELECT int056789,int1,int234,rat056789,rat1,rat234,sexi,sexr FROM declinations WHERE id = -956000 #include int getDayOfWeek(int year, int month, int day) { int a = (14 - month)/12; int y = year + 4800 - a; int m = month + 12*a - 3; int Date = day + (153*m + 2)/5 + 365*y + y/4 - y/100 + y/400 - 32045; int day_of_week = Date % 7 + 1; return day_of_week; } void main () { printf ("Day of week is %d", getDayOfWeek (2011, 9, 5)); } ----------------------------------------------------------------------------------------------------------------- У времени в плену. Как научиться работать быстро? Константин Кондаков "netstat -plan|grep :80|awk {'print \$5'} | cut -d: -f 1 | sort | uniq -c | sort -nk 1" -----------------------------------------------------------------------------------------------------------------