Владимир Закляков
Looking Glass своими руками,
или Сервер диагностики сетевой доступности
# mount /dev/sr0 /mnt
# vi /etc/yum.repos.d/CentOS-Base.repo
$ diff -urN CentOS-Base.repo.old CentOS-Base.repo
--- CentOS-Base.repo.old 2015-08-03 19:13:00.000000000 +0400
+++ CentOS-Base.repo 2016-01-22 14:00:19.006142526 +0400
@@ -12,8 +12,9 @@
[base]
name=CentOS-$releasever - Base
-mirrorlist=http://mirrorlist.centos.org/?release= $releasever&arch=$basearch&repo=os&infra=$infra
+#mirrorlist=http://mirrorlist.centos.org/?release= $releasever&arch=$basearch&repo=os&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/ os/$basearch/
+baseurl=file:///mnt
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
@@ -22,6 +23,7 @@
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release= $releasever&arch=$basearch&repo=updates&infra= $infra
#baseurl=http://mirror.centos.org/centos/$releasever/ updates/$basearch/
+enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
@@ -31,6 +33,7 @@
mirrorlist=http://mirrorlist.centos.org/?release= $releasever&arch=$basearch&repo=extras&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/ extras/$basearch/
gpgcheck=1
+enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
# ip addr add 192.168.1.4/24 brd 192.168.1.255 dev eth0
# ip link set eth0 up
# ip addr show
# ip addr
# ip route add default via 192.168.1.1
# ip route show
# ip route
order bind,hosts
nameserver 192.168.1.1
# dhclient eth0
0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request
# iptables -I INPUT -p tcp --dport 80 --sport 1024:65535 -j ACCEPT
# iptables -I OUTPUT -p tcp --sport 80 --dport 1024:65535 -j ACCEPT
# iptables -I OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
# iptables -I INPUT -p icmp --icmp-type echo-reply -j ACCEPT
# iptables -L -v -x -n --line-numbers
# yum -y install mc httpd php
# yum -y install mc httpd php
# mount
# service httpd start
# chkconfig httpd on
unconfined_u:object_r:httpd_sys_content_t:s0
# chcon unconfined_u:object_r:httpd_sys_content_t:s0 1.php
";
system ("/usr/bin/whoami");
?>
# yum -y install policycoreutils-python
# semanage permissive -a httpd_t
";
system ("/bin/ping -c3 192.168.1.1");
?>
# tail /var/log/httpd/error_log
# tail -f /var/log/audit/audit.log
system ("/bin/ping -i 0.1 -s 1500 -c6 192.168.1.1");
apache ALL=(ALL) NOPASSWD: /bin/ping -i 0.1 -s 1500 -c6 192.168.1.1
# Defaults requiretty
system ("/usr/bin/sudo /bin/ping -i 0.1 -s 1500 -c6 192.168.1.1");
kernel /vmlinuz-2.6....
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
if(isset($_REQUEST['secret_parameter'])
and ($_REQUEST['secret_parameter']=='abc')
) {
.... system(...);
}
$ htpasswd -c /var/www/html/.users_file vladimir
AuthName "Enter password1"
AuthType Basic
AuthUserFile /var/www/html/.users_file
Require valid-user
# service httpd reload
/bin/date -R >log.txt.
-------------------------------------------------------------
Денис Силаков
Виртуальные машины в Virtuozzo 7
# prlctl create vm1 --vmtype vm --distribution=win-xp
# prlctl create vm -d list
# prlctl set vm1 --device-add cdrom --image <имя_образа.iso>
# prlctl set vm1 --vnc-mode auto --vnc-nopasswd
# prlctl start vm1
# prlctl set vm1 --device-bootorder="cdrom1 hdd0"
# prlctl list -i vm1
# prlctl installtools vm1
# prlctl set vm1 —tools-autoupdate on
# prlsrvctl net add network1 -t bridged --ifname enp0s6
# prlctl set vm1 --device-add net1
# prlctl set vm1 --device-set net1 --ipadd 192.129.129.20 --gw 192.129.129.1 --nameserver 192.192.192.10
# prlctl set vm1 --device-set net1 --dhcp yes
# prlctl set vm1 --device-set net1 --network network1
# prlctl clone vm1 --name vm2
# prlctl clone vm1 --name my_vm_template –template
---------------------------------------------------
Андрей Маркелов
Основы облачного хранилища данных Ceph
Часть 3. Интеграция с сервисами OpenStack
# yum -y install python-rbd ceph
[root@ceph1 ~]# ceph osd pool create cinder-volumes 128
[root@ceph1 ~]# ceph auth get-or-create client.cinder mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=cinder-volumes'
[root@ceph1 ~]# ceph auth get-or-create client.cinder | ssh root@controller tee /etc/ceph/ceph.client.cinder.keyring
[root@ceph1 ~]# ssh root@controller chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring
[root@ceph1 ~]# ceph auth get-or-create client.cinder | ssh root@compute tee /etc/ceph/ceph.client.cinder.keyring
[root@ceph1 ~]# ceph auth get-key client.cinder | ssh root@compute tee client.cinder.key
$ uuidgen
7651c383-1aef-4644-b7fe-d9cbbd9fe116
client.cinder secret
[root@compute ~]# virsh secret-define --file имя_файла.xml
[root@compute ~]# virsh secret-set-value --secret 7651c383-1aef-4644-b7fe-d9cbbd9fe116 --base64 $(cat client.cinder.key) && rm client.cinder.key secret.xml
[DEFAULT]
enabled_backends = rbd
[rbd]
volume_driver = cinder.volume.drivers.rbd.RBDDriver
rbd_pool = cinder-volumes
rbd_ceph_conf = /etc/ceph/ceph.conf
rbd_flatten_volume_from_snapshot = false
rbd_max_clone_depth = 5
rbd_store_chunk_size = 4
rados_connect_timeout = -1
glance_api_version = 2
rbd_user = cinder
rbd_secret_uuid = 7651c383-1aef-4644-b7fe-d9cbbd9fe116
[libvirt]
rbd_user = cinder
rbd_secret_uuid = 7651c383-1aef-4644-b7fe-d9cbbd9fe116
$ cinder create --display-name chephtest1 1
$ cinder list
[root@ceph1 ~]# ceph df
[root@ceph1 ~]# rados -p cinder-volumes ls
[root@ceph1 ~]# ceph osd pool create images 128
[root@ceph1 ~]# ceph auth get-or-create client.glance mon'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=images'
[root@ceph1 ~]# ceph auth get-or-create client.glance | ssh root@controller tee /etc/ceph/ceph.client.glance.keyring
[root@ceph1 ~]# ssh root@controller chown glance:glance /etc/ceph/ceph.client.glance.keyring
[glance_store]
default_store = rbd
stores = rbd
rbd_store_pool = images
rbd_store_user = glance
rbd_store_ceph_conf = /etc/ceph/ceph.conf
rbd_store_chunk_size = 8
[DEFAULT]
show_image_direct_url = True
$ wget -P /tmp http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
$ qemu-img convert -O raw /tmp/cirros-0.3.4-x86_64-disk.img /tmp/cirros-raw.img
$ glance image-create --name "cirros-raw" --visibility public --disk-format raw --container-format=bare --file /tmp/cirros-raw.img
[root@ceph1 ~]# ceph osd pool create vms 128
[client]
rbd cache = true
rbd cache writethrough until flush = true
admin socket = /var/run/ceph/guests/$cluster-$type.$id.$pid.$cctid.asok
log file = /var/log/qemu/qemu-guest-$pid.log
rbd concurrent management ops = 20
[root@compute ~]# mkdir -p /var/run/ceph/guests/ /var/log/qemu/
[root@compute ~]# chown qemu.qemu /var/run/ceph/guests /var/log/qemu/
[libvirt]
images_type = rbd
images_rbd_pool = vms
images_rbd_ceph_conf = /etc/ceph/ceph.conf
disk_cachemodes="network=writeback"
hw_disk_discard = unmap
[root@ceph1 ~]# ceph auth caps client.cinder mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=cinder-volumes, allow rwx pool=vms, allow rx pool=images'
[root@ceph1 ~]# ceph auth list
$ nova boot --flavor m2.tiny --image cirros-raw --key-name demokey1 --security-groups demo-sgroup test-vm
[root@compute-opt ~]# ps aux | grep qemu-kvm
[root@ceph1 ~]# ceph df
------------------------------------------------
Рашид Ачилов
остроение корпоратив ных VPN
Часть 10. Связь Linux-Linux с помощью strongSwan
# yum list strongswan
# swanctl
swanctl {
plugins {
openssl {
fips_mode = 0
}
}
}
i_dont_care_about_security_and_use_aggressive_mode_psk = no
charon {
filelog {
/var/log/ipsec {
append = yes
default = 2
job = 0
asn = 1
enc = 1
#ike = 4
#net = 4
#cfg = 3
flush_line = yes
ike_name = no
time_format = %b %e %T
}
}
}
: PSK "ключ"
212.20.5.1 180.80.80.1 : PSK "123456"
: PSK "654321"
conn %default
ikelifetime=2h
lifetime=1h
ike=aes128-sha256-modp1024, aes192-sha256-modp1024,aes256-sha256-modp1024!
esp=aes128-sha256-modp1024, aes192-sha256-modp1024,aes256-sha256-modp1024
conn ipsec-node1-psk
auto=route
left=212.20.5.1
leftid=212.20.5.1
leftauth=psk
leftsubnet=10.54.1.0/24
right=180.80.80.1
rightid=180.80.80.1
rightsubnet=10.42.1.0/24
rightauth=psk
keyexchange=ikev1
spdadd 10.54.1.0/24 10.42.1.0/24 any -P in ipsec esp/tunnel/212.20.5.1-180.80.80.1/unique;
right=180.80.80.1
rightid=10.42.1.2
rightsubnet=172.16.1.0/24
rightauth=psk
conn node1
auto=start
right=212.20.5.1
rightid=212.20.5.1
rightauth=psk
rightsubnet=10.54.1.0/24
left=180.80.80.1
leftid=180.80.80.1
leftsubnet=10.42.1.0/24
leftauth=psk
left=10.42.1.2
leftid=10.42.1.2
leftsubnet=172.16.1.0/24
leftauth=psk
: RSA ipsec_deltahw.key
conn ipsec-node1-rsa
auto=route
left=212.20.5.1
leftid="/C=RU/ST=Novosibirsk region/L=Novosibirsk/ O=DeltaHardware Ltd/OU=Linux servers/ CN=ipsec.deltahw.ru/emailAddress=root@deltahw.ru"
leftauth=pubkey
leftcert=ipsec_deltahw.crt
leftsubnet=10.54.1.0/24
right=180.80.80.1
rightid="/C=RU/ST=Novosibirsk region/L=Novosibirsk/ O=DeltaHardware Ltd/OU=Routers/ CN=node1.deltahw.ru/emailAddress=root@deltahw.ru"
rightcert=node1_deltahw.crt
rightsubnet=10.42.1.0/24
rightauth=pubkey
keyexchange=ikev1
ike=aes128-sha-modp1024,aes256-sha-modp1024, aes512-sha-modp1024
esp=aes128-sha-modp1024,aes256-sha-modp1024, aes512-sha-modp1024
# openssl x509 -in ipsec_deltahw.crt -noout -subject
---------------------------------------------------------
Дмитрий Голосов
ManageEngine ServiceDesk Plus
Часть 3. Интегрируем с Nagios
Листинг 1. Настройки сервиса Ping Service в Nagios
define service
{
use generic-service
host_name Switch_1
service_description Ping Service
check_command check_ping!200.0,20%!600.0,60%
normal_check_interval 5
retry_check_interval 1
}
parameter1_name
parameter1_value
…
parameterN_name
parameterN_value
Листинг 2. Скрипт sd_open.php
requester
Nagios_user
subject
$subject
requestType
Инцидент
technician
Nagios_user
category
Monitoring
subcategory
$subcategory
item
$item
group
Инфраструктура
XML;
//Инициализируем curl-сессию:
$ch = curl_init();
//Задаем опции для curl-сессии:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_POST, true);
/*Передаем строку с данными для передачи HTTP POST.
Для REST API параметром OPERATION_NAME=ADD_REQUEST даем
команду на добавление инцидента, параметром INPUT_DATA
передаем XML-документ, а в конце строки указываем API Key
в параметре TECHNICIAN_KEY */
curl_setopt($ch, CURLOPT_POSTFIELDS, "OPERATION_NAME=ADD_REQUEST&INPUT_DATA= $request_xmlstring&TECHNICIAN_KEY=$TK");
//Открываем curl-сессию:
curl_exec($ch);
//закрываем curl-сессию:
curl_close($ch);
?>
php add_request.php CRITICAL Switch_1 "Ping Service"
parameter1_name
parameter1_value
…
parameterN_name
parameterN_value
parameter1_name
parameter1_value
…
parameterN_name
parameterN_value
Листинг 3. Скрипт sd_close.php
from
0
limit
100
filterby
5429_MyView
XML;
//Формируем XML-документ для закрытия инцидента:
$close_xmlstr=<<
closeComment
Closed by Nagios with state $state
XML;
//Инициализируем curl-сессию:
$ch = curl_init();
//Задаем опции для curl-сессии:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_POST, true);
/*Передаем строку с данными для передачи HTTP POST.
Для REST API параметром OPERATION_NAME=GET_REQUESTS
даем команду на получение списка инцидентов, параметром
INPUT_DATA передаем XML-документ, а в конце строки указываем
API Key в параметре TECHNICIAN_KEY */
curl_setopt($ch, CURLOPT_POSTFIELDS, "OPERATION_NAME=GET_REQUESTS&INPUT_DATA= $xmlstr&TECHNICIAN_KEY=$TK");
//Открываем curl-сессию и передаем полученный результат
//в переменную $data:
$data = curl_exec($ch);
//Создаем новый объект SimpleXMLElement и передаем ему
//на обработку полученный XML-документ из переменной $data:
$sd=new SimpleXMLElement($data);
//Получаем количество элементов массива record
//и запускаем цикл:
for ($i=0;$i<=count($sd->response->operation-> Details->record)-1;$i++)
{
//Получаем URL каждого инцидента, который хранится
//в параметре URI каждого элемента массива record:
$new_url=$sd->response->operation->Details-> record[$i]->attributes()->URI;
//устанавливаем новый URL для curl-сессии
curl_setopt($ch, CURLOPT_URL, $new_url);
/*Передаем новую строку с данными для передачи HTTP POST.
Для REST API параметром OPERATION_NAME=GET_REQUEST даем
команду на получение параметров инцидента, параметром
INPUT_DATA передаем XML-документ, а в конце строки указываем
API Key в параметре TECHNICIAN_KEY */
curl_setopt($ch, CURLOPT_POSTFIELDS, "OPERATION_NAME=GET_REQUEST&TECHNICIAN_KEY=$TK");
//Открываем curl-сессию и передаем полученный результат
//в переменную $data_req:
$data_req = curl_exec($ch);
//Создаем новый объект SimpleXMLElement и передаем ему
//на обработку полученный XML-документ из переменной
//$data_req:
$sd1=new SimpleXMLElement($data_req);
/*Анализируем полученные параметры инцидента: подкатегория
(параметр 23) и позиция (параметр 24) должны соответствовать
полученным от Nagios
имени хоста и названию сервиса*/
if ($sd1->response->operation->Details-> parameter[23]->value==$subcategory)
{
if ($sd1->response->operation->Details-> parameter[24]->value==$item)
{
//Если условия выполнены, то устанавливаем новые параметры
//для curl-сессии. Для REST API параметром OPERATION_
//NAME=CLOSE_REQUEST даем команду на закрытие инцидента,
//параметром INPUT_DATA передаем XML-документ, а в конце
//строки указываем API Key в параметре TECHNICIAN_KEY */
curl_setopt($ch, CURLOPT_URL, $new_url);
curl_setopt($ch, CURLOPT_POSTFIELDS, "OPERATION_NAME=CLOSE_REQUEST&INPUT_DATA= $close_xmlstr&TECHNICIAN_KEY=$TK");
//открываем curl-сессию:
curl_exec($ch);
}
}
}
//Закрываем curl-сессию:
curl_close($ch);
?>
php add_request.php OK Switch_1 "Ping Service"
Листинг 4. Скрипт sd_notification.sh
#!/bin/bash
case "$1" in
OK) php /usr/local/nagios/libexec/eventhandlers/ sd_close.php $1 $2 "$3";;
WARNING);;
UNKNOWN);;
CRITICAL) php /usr/local/nagios/libexec/eventhandlers/ sd_open.php $1 $2 "$3";;
esac
exit 0
chown nagios:nagios sd_close.php
chown nagios:nagios sd_open.php
chown nagios:nagios sd_notification.sh
chmod 644 sd_close.php
chmod 644 sd_open.php
chmod 755 sd_notification.sh
Листинг 5. Определение команды для Nagios
define command
{
command_name sd_notification
command_line $USER2$/sd_notification.sh $SERVICESTATE$ $HOSTNAME$ '$SERVICEDESC$'
}
Листинг 6. Настройки сервиса Ping Service в Nagios
define service
{
use generic-service
host_name Switch_1
service_description Ping Service
check_command check_ping!200.0,20%!600.0,60%
event_handler_enabled 1
event_handler sd_notification
normal_check_interval 5
retry_check_interval 1
}
-------------------------------------------
Михаил Ушаков
Одноплатный компьютер CubieBoard2
Часть 2. Использование в качестве сетевого хранилища
$ dd if=cb-a20-lubuntu-desktop-card-v105.img of=/dev/sdc bs=1M
auto lo eth0
iface lo inet loopback
iface eth0 inet static
address 192.168.10.5
gateway 192.168.10.1
netmask 255.255.255.0
network 192.168.10.0/24
broadcast 192.168.10.255
dns-nameservers 8.8.8.8 192.168.10.1
deb http://old-releases.ubuntu.com/ubuntu quantal main universe
deb-src http://old-releases.ubuntu.com/ubuntu quantal main universe
$ sudo apt-get update
$ sudo locale-gen en_US en_US.UTF-8
$ sudo dpkg-reconfigure locales
export LC_ALL=en_US.utf-8
export LANG en_US
export C_CTYPE en_US
$ sudo apt-get install openssh
PerminRootLogin no
$ useradd tempuser
$ sudo adduser tempuser sudo
$ sudo passwd tempuser
$ sudo adduser tempuser sudo
$ sudo usermod -l michael linaro
$ sudo userdel tempuser
$ mv /home/linaro /home/Michael
$ sudo mkfs.ntfs -Q /dev/sdb1
$ sudo mkfs.ntfs -Q /dev/sdb2
$ sudo mkfs.ntfs -Q /dev/sdb3
$ sudo ntfslabel -f /dev/sdb1 SambaStorage
$ sudo ntfslabel -f /dev/sdb2 FtpStorage
$ sudo ntfslabel -f /dev/sdb3 Other
$ sudo apt-get ntfs-3g
$ sudo mount /dev/sda1 /media/SambaService -t ntfs-3g -o rw
$ sudo mount /dev/sda2 /media/FtpService -t ntfs-3g -o rw
$ sudo mount /dev/sda3 /media/Other -t ntfs-3g -o rw
$ sudo apt-get install vsftpd
local_root: local_root=/media/FtpStorage
$ sudo apt-get install db5.3-util
user1
password (для пользователя с логином user1)
user2
password (для пользователя с логином user2)
$ sudo db5.3_load -T -t hash -f /etc/vsftpd.users /etc/vsftpd.users.db
$ sudo chmod 600 /etc/vsftpd.users.db
$ sudo touch /etc/pam.d/vsftpd.virtual
auth required pam_userdb.so db=/etc/vsftpd.users
account required pam_userdb.so db=/etc/vsftpd.users
session required pam_loginuid.so
listen=YES
user_sub_token=$USER
local_root=/media/FtpStorage/$USER
anonymous_enable=NO
local_enable=YES
write_enable=YES
guest_enable=YES
guest_username=ftp
virtual_use_local_privs=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
pam_service_name=vsftpd.virtual
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
userlist_deny=YES
userlist_file=/etc/vsftpd_denied.users
sudo service vsftpd start | stop | restart | force-reload
$ sudo apt-get install samba samba-common-bin
[global]
workgroup = DEVELOPERS
server string = Cubie Samba Server
dns proxy = no
security = user
browseable = yes
syslog = 0
[shared]
path = /media/SambaService
writeable = yes
browseable = yes
valid users = @smbgroup
guest ok = no
$ sudo groupadd sambagroup
$ sudo user add samba
$ sudo passwd samba
$ sudo usermod -a -G smbgroup samba
sudo service smbd start|stop|restart
ftp> get ./distribs/dotNet/dotnet_4.0_x86-x64.msi
ftp> mget ./distribs/dotNet/*.msi
sudo mount -t cifs //192.168.10.5/shared /home/michael/shared -o user=samba, password=P@55W0rd123456,workgroup=DEVELOPERS
--------------------------------------------------
Дмитрий Голосов
Мониторинг телефонов Cisco
с помощью Nagios
Листинг 1. Скрипт check_phone.sh
#!/bin/bash
# Принимаем первый параметр скрипта – IP-адрес CUCM
HOSTADDRESS=$1
# Принимаем второй параметр скрипта – системное имя телефона
# Добавляем кавычки, поскольку CUCM отдает результат
# в таком формате
HOSTNAME='"'$2'"'
# Открываем цикл, сравнивая полученное от CUCM системное
# имя телефона с полученным значением на входе скрипта
while [[ $HOSTTEMP != $HOSTNAME ]];
do
# Увеличиваем значение счетчика
i=$(($i+1))
# Делаем запрос по SNMP к CUCM для объекта
# с системным номером i в OID ccmPhoneName
HOSTTEMP=$(snmpget -c public -v 2c $HOSTADDRESS '.1.3.6.1.4.1.9.9.156.1.2.1.1.20.'$i -O vq)
done
# Возвращаем значение счетчика, которое будет указывать
# на системный номер телефона
echo $i
exit 0
# ./check_phoneid.sh 192.168.1.2 SEP689CE2E6F022
# chown nagios:nagios check_phone.sh
# chmod 755 check_phone.sh
Листинг 2. Определение команды для Nagios
define command{
command_name check_phone
command_line $USER1$/check_phone.sh $HOSTADDRESS$ $ARG1$
}
Листинг 3. Создание хоста для мониторинга телефона
define host{
use generic-host
host_name Phone_1
alias Cisco Phone 1
# Указываем адрес нашего CUCM:
address 192.168.1.2;
#Указываем нашу команду, передавая ей в качестве параметра
#($ARG1$) системное имя телефона:
check_command check_phone! "SEP689CE2E6F022"
}
Листинг 4. Сервис для проверки статуса телефона
define service{
use generic-service
host_name Phone_1
service_description Phone Status
check_command check_snmp!-o .1.3.6.1.4.1.9.9.156. 1.2.1.1.7.$HOSTOUTPUT$ -C public -c 2
}
Листинг 5. Сервис для проверки причины отключения телефона
define service{
use generic-service
host_name Phone_1
service_description Phone Unreg Reason
check_command check_snmp!-o .1.3.6.1.4.1.9.9.156.1.2.1.1.26.$HOSTOUTPUT$ -C public -m /usr/share/snmp/mibs/CISCO-CCM-MIB.txt
}
--------------------------------------------------
Игорь Решетов
Сервер аудио- и видеоконференций
Apache OpenMeetings
deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main
deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main
deb http://ftp.us.debian.org/debian jessie contrib non-free
deb http://ftp.us.debian.org/debian jessie contrib
# apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
# apt-get update
# apt-get install oracle-java8-installer
# apt-get install oracle-java8-set-default
# java –version
# apt-get install libreoffice
# apt-get install imagemagick gdebi libgif4 libgif-dev synaptic zlib1g-dev liboil0.3 libart-2.0-2 unzip make install build-essential libfreetype6-dev
# cd /opt
# wget http://sourceforge.net/projects/sox/files/ sox/14.4.2/sox-14.4.2.tar.gz
# tar xzvf sox-14.4.2.tar.gz
# cd /opt/sox-14.4.2
# ./configure
# make && make install
# cd /opt
# wget http://old-releases.ubuntu.com/ubuntu/pool/universe/s/swftools/swftools_0.9.0-0ubuntu1_amd64.deb
# dpkg -i swftools_0.9.0-0ubuntu1_amd64.deb
# wget http://old-releases.ubuntu.com/ubuntu/pool/universe/s/swftools/swftools_0.9.0-0ubuntu1_i386.deb
# dpkg -i swftools_0.9.0-0ubuntu1_i386.deb
# echo "swftools hold" | dpkg --set-selections
# apt-get install flashplugin-nonfree
# cd /opt
# wget http://jodconverter.googlecode.com/files/ jodconverter-core-3.0-beta-4-dist.zip
# unzip jodconverter-core-3.0-beta-4-dist.zip
# apt-get -y --force-yes install autoconf automake libass-dev libfreetype6-dev libgpac-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev nasm libx264-dev cmake mercurial libopus-dev
# wget https://cwiki.apache.org/confluence/download/ attachments/27838216/ ffmpeg_script_compile_Ubuntu_Debian.zip?version= 3&modificationDate=1443530338096&api=v2
# ./ffmpeg.sh
# apt-get install python-software-properties
# apt-get install software-properties-common
# apt-get install mariadb-server
# mysql -u root –p
# CREATE DATABASE DATABASE DEFAULT CHARACTER SET 'utf8';
# GRANT ALL PRIVILEGES ON DATABASE.* TO 'openmeetings'@'localhost' DENTIFIED BY '123456' WITH GRANT OPTION;
# quit
# mkdir /opt/red5307
# cd /opt/red5307
# wget http://apache.rediris.es/openmeetings/3.0.7/bin/ apache-openmeetings-3.0.7.zip
# unzip apache-openmeetings-3.0.7.zip
# chown -R nobody /opt/red5307
# cd /opt
# wget http://repo1.maven.org/maven2/mysql/mysql-connector-java/ 5.1.36/mysql-connector-java-5.1.36.jar
# cp /opt/mysql-connector-java-5.1.36.jar /opt/red5307/webapps/openmeetings/WEB-INF/lib
# cd /opt/red5307/webapps/openmeetings/WEB-INF/classes/META-INF
# mv persistence.xml persistence.xml-ori
# mv mysql_persistence.xml persistence.xml
, Url=jdbc:mysql://localhost:3306/openmeetings
, Url=jdbc:mysql://localhost:3306/DATABASE
, Username=root
, Username=openmeetings
, Password=" />
, Password=123456" />
# wget https://cwiki.apache.org/confluence/download/ attachments/27838216/red5?version= 3&modificationDate=1443596054913&api=v2
# mv red5?version=3 red5
# cp red5 /etc/init.d/
# chmod +x /etc/init.d/red5
# /etc/init.d/mysql start
# /etc/init.d/red5 start
------------------------------------------------
Александр Пичкасов
Управление и поддержка
почтовых баз Exchange 2013
Листинг 1
Get-MailboxDatabase -Status | ft name,databasesize,availablenewmailboxspace
eseutil /ms
dism /online /enable-feature:windowsserverbackup
dism /online /enable-feature:windowsserverbackupsnapin
dism /online /enable-feature: microsoft-hyper-v-management-powerhell /all
dism /online /enable-feature:microsoft-hyper-v /quiet
#Создание виртуального диска и тома на нем удобно
#оформить в виде функции
function Create-VolumeOnVHD ($filenamevhd,$sizedisk) {
#Создание виртуального диска
New-VHD -Path "$filenamevhd" -SizeBytes $sizedisk –Dynamic | Out-Null
#Монтирование виртуального диска, сохранение индекса в переменной
$numdisk = (Mount-DiskImage -ImagePath "$filenamevhd" -PassThru | Get-DiskImage).number
#Инициализация диска, создание раздела, сохранение
#раздела в переменной
$newpartition = Initialize-Disk -Number $numdisk -PassThru | New-Partition -AssignDriveLetter –UseMaximumSize
#Форматирование тома
Format-Volume –DriveLetter $newpartition.DriveLetter –Force -Confirm:$false | Out-Null
return $newpartition
}
#Задание имен файлов виртуальных дисков
#(те же имена используются для каталогов монтирования)
#Создание каталога для файлов виртуальных дисков
mkdir c:\vhds
$setname = 'diskAdb','diskAlogs'
foreach ($filename in $setname) {
$newpart = Create-VolumeOnVHD -filenamevhd "C:\vhds\$filename.vhd" -sizedisk 5000000000
#Создание каталога и монтирование тома
mkdir c:\$filename | Out-Null
mountvol c:\$filename $newpart.AccessPaths[1]
#Удаление пути доступа формата DriveLetter для корректной
#обработки резервного копирования
mountvol $newpart.AccessPaths[0] /d
}
New-MailboxDatabase -Name "MailboxDB" -Server (hostname) -EdbFilePath C:\diskAdb\mailboxdb\mailboxdb.edb -LogFolderPath C:\diskAlogs\mailboxdblogs
Mount-Database MailboxDB
$ad0=(Get-AcceptedDomain)[0]
$pass = ConvertTo-SecureString 'Pa$$w0rd' -AsPlainText –Force
New-Mailbox -Name "Antonio" -LastName "Marini" -Database "MailboxDB" -Password $pass -ResetPasswordOnNextLogon $false -DisplayName "Antonio Marini" -Alias antonio -UserPrincipalName "antonio@$ad0"
#Отправка сообщения для инициации почтового ящика
Send-MailMessage -SmtpServer localhost -From "administrator@$ad0" -To "antonio@$ad0" -Subject "Initiate Antonio mailbox"
#Проверка создания структуры в базе
Get-MailboxDatabase mailboxdb | Get-MailboxStatistics | ? {$_.displayname -eq "Antonio Marini"}
#Отключение почтового ящика
Disable-Mailbox antonio –Confirm:$false
#Создание резервной копии
$wbpolicy = New-WBPolicy
$wbbackuptarget = New-WBBackupTarget -VolumePath c:
$wbvolume1 = Get-WBVolume -VolumePath C:\diskAdb
$wbvolume2 = Get-WBVolume -VolumePath C:\diskAlogs
Add-WBBackupTarget -Policy $wbpolicy -Target $wbbackuptarget
Add-WBVolume -Policy $wbpolicy -Volume $wbvolume1
Add-WBVolume -Policy $wbpolicy -Volume $wbvolume2
Set-WBVssBackupOption -Policy $wbpolicy –VssFullBackup
Start-WBBackup -Policy $wbpolicy
#Создание нового почтового ящика
New-Mailbox -Name "Alonzo" -LastName "Manchini" -Database "MailboxDB" -Password $pass -ResetPasswordOnNextLogon $false -DisplayName "Alonzo Manchini" -Alias alonzo -UserPrincipalName "alonzo@$ad0"
Send-MailMessage -SmtpServer localhost -From "administrator@$ad0" -To "alonzo@$ad0" -Subject "Initiate Alonzo mailbox"
#Контроль состояния базы
Get-MailboxDatabase mailboxdb | Get-MailboxStatistics | ? {$_.displayname -eq "Alonzo Manchini"}
#*Имитация* очистки базы по истечении периода хранения
#удаленных сообщений
Get-MailboxStatistics -Database MailboxDB | ? {$_.DisconnectReason -eq "Disabled"} | foreach {Remove-StoreMailbox -Database $_.database -Identity $_.mailboxguid -MailboxState Disabled –Confirm:$false}
#Создание очередной резервной копии
Start-WBBackup -Policy $wbpolicy
#*Имитация* выхода из строя физических дисков
Dismount-DiskImage -ImagePath C:\vhds\diskAdb.vhd
Dismount-DiskImage -ImagePath C:\vhds\diskAlogs.vhd
#Контроль состояния базы
Get-MailboxDatabase mailboxdb -Status | ft name,mounted –a
#Для исключения нежелательных попыток монтирования базы
#подсистемой управляемой доступности (Managed Availability)
Set-MailboxDatabase mailboxdb -MountAtStartup $false
#Некорректное отключение точек монтирования требует
#повторного создания каталогов
cmd /c rmdir c:\diskAdb
cmd /c rmdir c:\diskAlogs
mkdir c:\diskAdb
mkdir c:\diskAlogs
$newname = 'diskBdb','diskBlogs'
foreach ($filename in $newname) {
#Создание тома на виртуальном диске
$newpart = Create-VolumeOnVHD -filenamevhd "C:\vhds\$filename.vhd" -sizedisk 5000000000
#Монтирование томов
if ($filename –eq "diskBdb") { mountvol c:\diskAdb $newpart.AccessPaths[1]}
if ($filename –eq "diskBlogs") {mountvol c:\diskAlogs $newpart.AccessPaths[1]}
#Удаление пути доступа для корректной обработки резервного
#копирования
mountvol $newpart.AccessPaths[0] /d
}
##Восстановление томов из резервной копии
#Получение набора данных последней резервной копии
$wbbackupset = (Get-WBBackupSet)[(Get-WBBackupSet).count-1]
#Просмотр содержимого резервной копии
$wbbackupset
#Новому тому присвоен отличный от исходного идентификатор,
#поэтому восстановление в исходное местоположение
#невозможно, требуется указание целевого тома
$targetvolume = Get-WBVolume -VolumePath C:\diskAdb
Start-WBVolumeRecovery -BackupSet $wbbackupset -VolumeInBackup $wbbackupset.Volume[0] -RecoveryTargetVolume $targetvolume -Force
$targetvolume = Get-WBVolume -VolumePath C:\diskAlogs
Start-WBVolumeRecovery -BackupSet $wbbackupset -VolumeInBackup $wbbackupset.Volume[1] -RecoveryTargetVolume $targetvolume –Force
#Данные восстановлены, подключаем базу
Mount-Database MailboxDB
#Проверим доступность и содержимое почтовой базы
Get-MailboxDatabase mailboxdb | Get-MailboxStatistics
#Возврат возможности автоматического монтирования базы
#при старте сервера и поддержки работоспособности
#системой Managed Availability
Set-MailboxDatabase mailboxdb -MountAtStartup $true
##Восстановление файлов из резервной копии
#Получение набора данных предпоследней резервной копии
$wbbackupset = (Get-WBBackupSet)[(Get-WBBackupSet).count-2]
#Просмотр содержимого набора резервной копии
$wbbackupset
#Монтирование файлов резервной копии для просмотра
$backupvolume1 = Get-WBBackupVolumeBrowsePath -BackupSet $wbbackupset -VolumeInBackup $wbbackupset.Volume[0]
$backupvolume2 = Get-WBBackupVolumeBrowsePath -BackupSet $wbbackupset -VolumeInBackup $wbbackupset.Volume[1]
#Просмотр каталогов резервной копии
dir $backupvolume1
dir $backupvolume2
#Восстановление файлов базы данных из резервной копии
#в альтернативное местоположение
mkdir c:\recovery
Start-WBFileRecovery -BackupSet $wbbackupset -SourcePath $backupvolume1\mailboxdb -TargetPath C:\recovery\ -Recursive –Force
#Создание базы восстановления, для журналов транзакций
#указываем прежнее имя каталога
New-MailboxDatabase -name RecoveryDB -Server (hostname) -Recovery -EdbFilePath C:\recovery\mailboxdb\mailboxdb.edb -LogFolderPath C:\recovery\mailboxdblogs
#Восстановление журналов транзакций в альтернативное
#(по отношению к исходному) местоположение
Start-WBFileRecovery -BackupSet $wbbackupset -SourcePath $backupvolume2\mailboxdblogs -TargetPath C:\recovery\ -Recursive –Force
#Получение информации о задействованных префиксах
#для журналов транзакций (пример вывода на рис. 3)
dir c:\recovery\mailboxdblogs\
Get-MailboxDatabase -server (hostname) | ft name,logfileprefix
#Переименование журналов транзакций для корректного
#создания и монтирования базы (префикс E02 – частный случай)
Get-ChildItem C:\recovery\mailboxdblogs\ | Rename-Item -NewName {$_.Name -Replace "e01", "e02"}
#Подключение базы и проверка доступности
Mount-Database recoverydb
Get-MailboxDatabase recoverydb | Get-MailboxStatistics | ? {$_.disconnectreason -ne $null}
#Проверка учетной записи
Get-User Antonio
#Включение поддержки почты для существующего пользователя
Enable-Mailbox -Identity antonio -Alias antonio -Database MailboxDB
#Выбор почтового ящика для восстановления
$storemailbox = Get-MailboxDatabase recoverydb | Get-MailboxStatistics | ? {$_.displayname -eq "Antonio Marini"}
#Создание запроса на восстановление, необходим параметр
#AllowLegacyDNMismatch, поскольку целевым выбран новый
#почтовый ящик
New-MailboxRestoreRequest -SourceDatabase $storemailbox.Database -SourceStoreMailbox $storemailbox.displayname -TargetMailbox antonio –AllowLegacyDNMismatch
#Проверка состояния запроса на восстановление
Get-MailboxRestoreRequest
#Если запрос длительное время остается в состоянии Queued,
#выполните
Get-MailboxRestoreRequest | Resume-MailboxRestoreRequest
#По завершении восстановления необходимо удалить базу
#восстановления, а также ее файлы.
Remove-MailboxDatabase recoverydb -Confirm:$false
Remove-Item C:\recovery -Recurse
--------------------------------------------
Сергей Болдин
Учет сетевых принтеров,
или Снова SCCM, SQL Server, ExtJS
Листинг 1. Запрос на выборку данных
SELECT DISTINCT MachineID, PortName00, Name00, Status00, [Nom Kab], [Inv Nom], Password, Department, Description
FROM dbo.PRINTER_DEVICE_DATA
WHERE MachineID = 16777769
Листинг 2. Добавление полей в data.php
while ($row = mssql_fetch_assoc($result)) {
//применяем перекодировку
$row[Description] = iconv('CP1251','UTF8',$row[Description]);
// устанавливаем статус и окрашиваем в красный цвет
if(strcmp($row[Status00],"Error")==0) {
$row[Status00]="Ошибка";
$row[Status00]="" .$row[Status00]."";}
// устанавливаем статус и окрашиваем в желтый цвет
if(strcmp($row[Status00],"Degraded")==0){
$row[Status00]="Оффлайн";
$row[Status00]="" .$row[Status00]."";}
// устанавливаем статус и окрашиваем в зеленый цвет
if(strcmp($row[Status00],"Unknown")==0){
$row[Status00]="Готов";
$row[Status00]="" .$row[Status00]."";}
$output[]=$row;}
Листинг 3. Добавление полей в data_upd.php
//присвоение переменным новых значений
$Inv_Nom=$params['Inv Nom'];
$Description=iconv('UTF8','CP1251',$params['Description']);
//запись значений поля в БД
$sql="Update dbo.printer_device_data SET
[Inv Nom]='".$Inv_Nom."',
[Description]=N'".$Description."'
Where [Name00]='".$Name00."' ";
renderer: function(val)
{
return ''+val+'';
}
--------------------------------------
Валерий Михеичев
Оптимизация SQL-запросов в Oracle
Часть 2. Практические рекомендации
Select v.* from v$sql_monitor v where v.sid=91 and v.session_serial#=6941 order by v.sid, v.session_serial#, v.sql_exec_start, v.sql_id, key;
Select p.* from v$sql_plan_monitor p where p.key=KEY order by p.plan_line_id;
Select c.sql_id, c.name, c.position, c.value_string, c.last_captured from v$sql_bind_capture c where c.sql_id=SQL_ID and c.child_address=SQL_CHILD_ADDRESS order by position;
Select sid, serial#, blocking_session from v$session where sid=SID and serial#=SESION_SERIAL# and blocking_session >0;
Select a.* from (select s.status status_ses, m.key, m.status status_monitor, s.sid sid, s.serial# serial#, s.blocking_session who_sid, m.sql_exec_start sql_start,m.sql_id,s.sql_id sql_id_last,
round((sysdate-s.sql_exec_start)*24*3600) rab_sec_last, round(elapsed_time/1000000) elapsed_sec, round(cpu_time/1000000) cpu_sec,
round(elapsed_time/1000000-cpu_time/1000000) wait_sec, m.sql_text,
(select v.sql_text from v$sql v where v.sql_id=s.sql_id and rownum=1) sql_text_last
from v$sql_monitor m, v$session s where m.sid(+)=s.sid and m.session_serial#(+)=s.serial#
and S.status='ACTIVE' ) a where (a.sql_id is not null or a.sql_id_last is not null)
and a.sid=91 and a.serial#=6941 order by a.sid, a.serial#,a.sql_start, a.rab_sec_last;
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR (REPORT_LEVEL => 'ALL', TYPE => 'TEXT',
SQL_ID => ‘fkpsng443bsx’) FROM DUAL;
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR (REPORT_LEVEL => 'ALL', TYPE => 'HTML',
SQL_ID => ‘fkpsng443b1sx’) FROM DUAL;
Select * from table(dbms_workload_repository.awr_report_text(
(select dbid from v$database), (select instance_number from v$instance), (select max(snap_id)-1 from sys.wrm$_snapshot), (select max(snap_id) from sys.wrm$_snapshot)) );
Select * from table( dbms_workload_repository.ash_global_report_text(
(select dbid from v$database),(select instance_number from v$instance), (select max(begin_interval_ time)-1/2 from sys.wrm$_snapshot), (select max(end_interval_time) from sys.wrm$_snapshot), l_sid=>91, l_sql_id=>'gwsuu2rr7nctk' ) ) ;
Select * from TABLE(dbms_workload_repository. awr_sql_report_text(
(select dbid from v$database), (select instance_number from v$instance),
(select max(snap_id)-1 from sys.wrm$_snapshot), (select max(snap_id) from sys.wrm$_snapshot),'6vsq64jf1d08p') );
begin dbms_workload_repository.add_colored_sql(sql_id => '39a47xjppcz4y');end;
Select * from sys.wrm$_colored_sql;
begin dbms_workload_repository.remove_colored_sql ( sql_id => '39a47xjppcz4' );end;
/*+ opt_param('optimizer_index_cost_adj' 1) */
/*+ opt_param('optimizer_index_caching' 95*/
/*+ opt_param('optimizer_index_caching' 95) opt_param('optimizer_index_cost_adj' 1) */
alter session set optimizer_index_caching=95;
alter session set optimizer_index_cost_adj=1;
/*+ opt_param('_optim_peek_user_binds' 'false') */
alter session set "_optim_peek_user_binds"=false;
alter session set optimizer_features_enable ='11.2.0.3’;
/*+ optimizer_features_enable ('11.2.0.3') */
/*+ optimizer_features_enable ('11.1.0.7') */
Select * from agreemen a, vp_docsum pf where a.isn= pf.agrisn;
Select * from docsum s1, docsum s2 where s1.рarentisn = s2.isn;
Select * from docsum s1, docsum s2 where s1.parentisn = s2.isn;
/*+ use_nl(pf.ds.s1 pf.ds.s2) index(pf.ds.s1 x_docsum_parent) index(pf.ds.s2 x_docsum_agr) */
Select name, value from v$parameter where name in ('compatible','optimizer_features_enable');
-----------------------------------------------------
Александр Календарев
Использование Cassandra
в системах сбора и анализа данных
$ sudo docker pull cassandra
$ sudo docker run --name cassandra -d cassandra
$ sudo docker exec -it cassandra /bin/bash
root@cfe6bc684594:/# cqlsh
cqlsh> CREATE KEYSPACE stat WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
cqlsh> use stat
cqlsh:test>
cqlsh> show host
cqlsh:stats> CREATE TABLE clicks (
key timeuuid PRIMARY KEY,
ts timestamp,
banner_id int,
site_id int,
ip int,
referer ascii,
ua ascii
);
$ sudo apt-get install libuv-dev libgmp-dev openssl-dev libssl-dev
$ git clone https://github.com/datastax/php-driver.git
$ cd php-driver
$ git submodule update --init
$ cd ext
$ sudo ./install.sh
withContactPoints('localhost')
->build();
$keyspace = 'stats';
// создание соединения
$session = $cluster->connect($keyspace);
// создание uuid
$cql = sprintf('INSERT INTO clicks (key,ts,banner_id,site_id,ip,referer,ua)
$uuid = Type::timeuuid()->create();
VALUES (%s,now(), %d,%d,%d,\'%s\',\'%s\' )',
$uuid,
$_GET['banner_id'],
$_GET['site_id'],
ip2long($_SERVER['HTTP_REAL_IP']),
$_SERVER['HTTP_USER_AGENT'],
$_SERVER['HTTP_REFERER']);
$statement = new Cassandra\SimpleStatement($cql);
// асинхронное исполнение
$future = $session->executeAsync($statement);
$ curl -H 'User-Agent:test' http://localhost/click.php?banner_id=123&site_id=567
$ sqlsh
cqlsh> use stats;
cqlsh:stats>select * from clicks;
cqlsh:stats> CREATE TABLE stats (
webmaster_id int,
date timestamp,
banner_id int,
site_id int,
country_id int,
click_count counter,
hit_count counter,
lead_count counter,
summa counter,
PRIMARY KEY ((webmaster_id, date), banner_id, site_id, country_id )
);
cqlsh:stats> CREATE TABLE tmp1 (
id int PRIMARY KEY,
value int);
cqlsh:stats> UPDATE tmp1 SET value = value + 1 WHERE id = 1;
cqlsh:stats>CREATE TABLE tmp2 (
id int PRIMARY KEY,
value counter);
cqlsh:stats> UPDATE tmp2 SET value = value + 1 WHERE id = 1;
cqlsh:stats> select * from tmp2;
$hit_str = $is_hit ? ',hit_counter = hit_counter +1' : '';
$cql = sprintf('UPDATE stats
SET click_count = click_count +1 %s
WHERE
webmaster_id = %d,
date = %d,
banner_id = %d,
site_id = %d,
country_id = %d',
$hit_str, $webmaster, $date, $banner_id, $sit_id, $country_id);
$statement = new Cassandra\SimpleStatement($cql);
// асинхронное исполнение
$future = $session->executeAsync($statement);
define( DAY_IN_SEC, 24 * 60 * 60);
$stat = [];
$stat[] = [];
$stat[][] = [];
for($date=mktime(0,0,0,1,1,2016); $date < mktime(0,0,0,1,10,2016); $date += DAY_IN_SEC ) {
$cql=sprintf('SELECT * FROM stats WHERE
webmaster_id = $d,
date = %d',
$webmaster_id,$date);
$future = $session->executeAsync(new Cassandra\SimpleStatement($cql));
$result = $future->get(); // ожидание результата
// итерация по полученному множеству колонок
foreach ($result as $row) {
if (!isset($stat[row['banner_id]] [row['site_id]][row['country_id]])) {
$stat[row['banner_id]] [row['site_id]][row['country_id]] = 0;
}
$stat[$date][row['banner_id]][row['site_id]] [row['country_id]] += $row['hit_count'];
}
UPDATE … SET … IP = IP + [<значение IP>]
------------------------------------------------------
Олег Филиппов,
Git на службе у 1С-ника
*.xml
*.htm
*.html
*.Form
oscript.exe gitsync.os init <каталог хранилища конфигурации> <локальный каталог GIT>
oscript.exe gitsync.os < каталог хранилища> <удаленный каталог Git в GITLab, включая логин и пароль> <Каталог репозитория Git>
------------------------------------------------------
Андрей Пахомов
Современное клиент-серверное приложение
для Android. Часть 2
...
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setActionBar(toolbar);
getActionBar().setDisplayShowTitleEnabled(false);
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.settings_popup);
SharedPreferences sp = getSharedPreferences("city", MODE_PRIVATE);
String cityName = sp.getString("userCity", "London, GB");
final EditText editField= (EditText)dialog.findViewById(R.id.editField);
editField.setText(cityName);
Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
dialogButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sp.edit().putString("userCity",editField.getText().toString()).commit();
dialog.dismiss();}});
Picasso.with(itemVH.NDImage.getContext())
.load(days.get(i).getImage())
.resize(100, 100)
.centerCrop().into(itemVH.NDImage);
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.openweathermap.org")
.addConverterFactory(GsonConverterFactory.create())
.build();
call=retroAPI.loadForecast(cityName, "metric", "7", devID);
call.enqueue(new Callback() {
@Override
public void onResponse(Response response, Retrofit retrofit) {
private DayFrct getDayForecast( JsonParser jsonParser, int i)
{ String date=jsonParser.dayData.get(i).getDate();
String dayTemp=jsonParser.dayData.get(i).tempInfo. getDayTemp();
Date date = new Date(unixtime*1000L);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM"); // the format of your date
String formattedDate = sdf.format(date);
DayFrct day = new DayFrct(...,dayTemp,nightTemp,mainWeather);
return day;}
days = new ArrayList<>();
setToday(getDayForecast(response.body(), 0), cityName);
private void setToday(DayData day, String cityname)
{TextView city= (TextView)findViewById(R.id.cityName);
moreData.setText(day.getMainWeather());}
for (int i = 1; i < response.body().dayData.size(); i++)
{days.add(getDayForecast(response.body(), i));}
adapter=new FrcstAdapter(days);
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2,1);
myRview.setLayoutManager(manager);
myRview.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
...
call.enqueue(...);}});
---------------------------------------------
Александр Майоров
Релиз TypeScript 1.7
Асинхронное программирование с async/await
$ npm update typescript
$ npm install typescript
/* printDelayed is a 'Promise' */
async function printDelayed(elements: string[]) {
for (const element of elements) {
await delay(500);
console.log(element);
}
}
async function delay(milliseconds: number) {
return new Promise(resolve => {
setTimeout(resolve, milliseconds);
});
}
printDelayed(["Hello", "asynchronous", "world"])
.then(() => console.log("Printed all elements") );
var __awaiter = (this && this.__awaiter) || function(thisArg, _arguments, Promise, generator) {
return new Promise(function (resolve, reject) {
generator = generator.call(thisArg, _arguments);
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value :
new Promise(function(resolve) { resolve(value); }); }
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
function step(verb, value) {
var result = generator[verb](value);
result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
}
step("next", void 0);
});
};
function printDelayed(elements) {
return __awaiter(this, void 0, Promise, function* () {
for (const element of elements) {
yield delay(500);
console.log(element);
}
});
}
function delay(milliseconds) {
return __awaiter(this, void 0, Promise, function* () {
return new Promise(resolve => {
setTimeout(resolve, milliseconds);
});
});
}
printDelayed(["Hello", "asynchronous", "world"])
.then(() => console.log("Printed all elements"));
interface Model {
setupBase(): this;
}
interface AdvancedModel extends Model {
setupAdvanced(): this;
}
interface SuperAdvancedModel extends AdvancedModel {
setupSuperAdvanced(): this;
}
declare function createModel(): SuperAdvancedModel;
newModel = newModel
.setupBase()
.setupAdvanced()
.setupSuperAdvanced();
let squared = 2 ** 2; // same as: Math.pow(2, 2) or 2 * 2
let cubed = 2 ** 3; // same as: Math.pow(2, 3) or 2 * 2 * 2
let num = 2;
num **= 2; // same as: num = num * num or num = Math.pow(num, 2);
//tsconfig.json targeting node.js v4 and beyond
{
"compilerOptions": {
"module": "commonjs",
"target": "es6"
}
}
declare module JSX {
interface IntrinsicElements {
["my-custom-element"]: MyCustomElementClass
}
}
let a: "foo" | number = "foo"; // valid
let b: "bar" | "baz" = "foo"; // invalid
let tradition: "hello world" = 'hello world';
let quotes: "hello'world" = 'hello\'world';
type CardinalDirection = "North" | "East" | "South" | "West";
function move(distance: number, direction: CardinalDirection) {
// ...
}
-----------------------------------------------------
Антон Карев,
Многопоточный клиент-сервер
для распределенных вычислений
int main(DWORD argc, LPTSTR argv[])
{
// … //
while (TRUE)
{
// генерация задания (делаем строку для передачи на сервер)
wsprintf(s, "%i",rand() % (L_MAX-L_MIN) + L_MIN);
if (send(ClientSock, s, strlen(s)+1, 0) == SOCKET_ERROR)
break;
printf(""Задача создана\n"");
// засыпаем до генерации следующей задачи
Sleep(periodJob);
}
// … //
}
int main(DWORD argc, LPCSTR argv[])
{
// … //
// Инициализация события для синхронизации обращений
// к printf.
hEvent_printf = CreateEvent(NULL, FALSE, TRUE, "printf");
// Инициализация семафоров для синхронизации потоков
// клиентов.
// ------
// hSemaphoreFree – находится в сигнальном состоянии,
// когда доступна хотя бы одна ячейка в массиве задач
// hSemaphoreJob – находится в сигнальном состоянии,
// когда в массиве есть хотя бы одна задача
// hSemaphoreCons – находится в сигнальном состоянии,
// когда есть хотя бы один свободный потребитель
hSemaphoreFree = CreateSemaphore(NULL, MAX_TASKS, MAX_TASKS, "FreeCell");
hSemaphoreJob = CreateSemaphore(NULL, 0, MAX_TASKS, "Job");
hSemaphoreCons = CreateSemaphore(NULL, 0, MAX_CLIENTS, "Consumer");
// Инициализация очереди "потребители" //
for (ith = 0; ith < MAX_CLIENTS; ith++)
{
srv_arg[ith].number = ith; // порядковый номер потока
srv_arg[ith].status = 0; // статус – ячейка пустая
srv_arg[ith].sock = 0; // сокет – отсутствует
srv_arg[ith].srv_thd = 0; // хендл сокета – отсутствует
}
// Инициализация критической секции
InitializeCriticalSection(&csl);
EnterCriticalSection(&csl);
// Инициализация очереди задач
for (ith = 0; ith < MAX_TASKS; ith++)
{
Task[ith].length = 0; // длительность задачи в у.е.
Task[ith].status = 0; // ячейка свободна
}
LeaveCriticalSection(&csl);
// … //
// Поиск пустой ячейки в массиве аргументов потока
// сервера. //
while (TRUE)
{
// пройти по всем клиентам
for (ith = 0; ith < MAX_CLIENTS;)
{
if (srv_arg[ith].status == 1 || srv_arg[ith].status == 3)
// Поток остановлен, нормально или по требованию завершения //
{
// ждем полного завершения потока
WaitForSingleObject(srv_arg[ith].srv_thd, INFINITE);
// освобождаем системные ресурсы занятые
// этим потоком
CloseHandle(srv_arg[ith].srv_thd);
// параметры: хендл объекта, который нужно
// освободить
// устанавливаем признак свободной ячейки
srv_arg[ith].status = 0;
}
if (srv_arg[ith].status == 0)
// если ячейка освободилась, то начать
// проход по клиентам заново
break;
// циклический счетчик: 0..MAX_CLIENTS-1,
// 0..MAX_CLIENTS-1, ...
ith = (ith+1) % MAX_CLIENTS;
// если пройдены все клиенты, ждем секунду
// и начинаем заново
if (ith == 0) Sleep(1000);
// прекращаем цикл опроса//
}
// … //
}
int main(DWORD argc, LPCSTR argv[])
{
// … //
// Ожидаем завершения активного потока сервера //
shutdown(SrvSock, 2);
closesocket(SrvSock);
WSACleanup();
// Предыдущие две функции вызываются для корректного
// размыкания соединения.
// Сервер сначала закрывает сокет, созданный функцией
// accept, а не прослушивающий сокет. Сервер не может
// закрыть прослушивающий сокет, пока не завершится сам
// или уже не будет принимать подключения клиента.
// пробегаем по всем клиентам в целях их отключения
for (ith = 0; ith < MAX_CLIENTS; ith++)
// ячейка занята (есть подключение)?
if (srv_arg[ith].status != 0)
{ // да – ждем его завершения и освобождаем ресурсы
WaitForSingleObject(srv_arg[ith].srv_thd, INFINITE);
CloseHandle(srv_arg[ith].srv_thd);
}
DeleteCriticalSection(&csl);
// … //
}
DWORD WINAPI Server(LPVOID pThArg)
// функция потока сервера
{
// делаем отображение параметра
SERVER_ARG *ThArg = ((SERVER_ARG *) pThArg);
// … //
while (TRUE)
{
switch (what)
{
// … //
case 1: // producer – производитель
// получить задачу от производителя
if (recv(ThArg->sock, buf, sizeof(buf), 0) == SOCKET_ERROR)
break; // ошибка – пропустить обработку
// подождать, пока станет доступной хотя бы
// одна ячейка для задачи
WaitForSingleObject(hSemaphoreFree, INFINITE);
// подождать, пока освободится критическая
// секция, и занять ее
EnterCriticalSection(&csl);
// найти свободную ячейку в очереди задач
for (iCell = 0; iCell < MAX_TASKS && Task[iCell].status != 0; iCell++);
// занять свободную ячейку
// количество условных операций в задаче
Task[iCell].length = atoi(buf);
// признак занятой и необработанной ячейки
Task[iCell].status = 1;
// увеличить счетчик необработанных задач
jobCounter++;
// выйти из критической секции
LeaveCriticalSection(&csl);
// сообщить о том, что стала доступна еще одна
// задача. Вызовом этой функции мы
// разблокируем один из потоков-потребителей,
// которые ожидают прихода задачи
ReleaseSemaphore(hSemaphoreJob, 1, NULL);
WaitForSingleObject(hEvent_printf, INFINITE);
printf("пришла задача от %i. Необработанных задач в очереди: %i\n", ThArg->number, jobCounter);
if (jobCounter == MAX_TASKS)
printf("Очередь заданий переполнена!\n");
SetEvent(hEvent_printf);
}
}
// … //
}