МАСТЕРКОМ

IT-СИСТЕМЫ ПРОСТО И ДЛЯ ВСЕХ

SEO

Статья на тему DevOps.

 

Не будем занудствовать, а просто скинем пару лайф-хаков.

Как забэкапить 1С 8.3 в Windows, если есть синхронизация бэкапов в Яндекс.Cloud через Duplicaty?

 

@echo off

rem бэкапим базу 1С во временное хранилище, для синхронизации с облаком

"C:\Program Files\7-zip\7z.exe" a -t7z -mx5 -scsWIN -ssw "D:\backup\1c\1Cback-%date%-%time:~0,2%.%time:~3,2%.%time:~6,2%.7z" "C:\1c_base"

rem перемещаем файлы из временной папки Duplicaty в конечное хранилище

forfiles -p "D:\backup\1c" -s -m *.7z -d -3 -c "cmd /c if /i @isdir equ false move @path D:\backup\"

rem удаляем старые файлы из хранилища

forfiles -p "D:\backup" -s -m *.7z -d -60 -c "cmd /c if /i @isdir equ false del /q /s @path"

Как видно всё просто. Почти, и вот это "почти" и приходиться "обходить" дополнительной папкой. С Duplicaty есть проблема в том, что он АБСОЛЮТНО не смотрит на давность файлов. Он заливает ВСЁ как есть на диске. И существующая в ней функция удаления применима ТОЛЬКО к самим архивами создаваемым Duplicaty на удалённом сервере.

Создаём .bat файл с данным содержимым и в "Планировщике заданий" Виндовс указываем путь до него и периодичность запуска.

Расшифруем параметры:

a -t7z -mx5 -scsWIN -ssw указываем степень сжатия и тип архива
%date%-%time:~0,2%.%time:~3,2%.%time:~6,2% "вызываем" системное время в имя файла
-s -m *.7z -d -60 -c удалить файлы старше 60-ти дней
/c if /i @isdir equ false del /q /s @path где и как их искать

 

Как забэкапить 1С 7.7 в Ubuntu?

 

5 0 * * 6 tar -cP /var/www | /bin/gzip -9 -c > /media/hdd/backup/ubun_1c77_`date '+\%Y-\%m-\%d'`.tar.gz
40 4 * * * cp /media/hdd/backup/ubun_1c77_`date '+\%Y-\%m-\%d'`.tar.gz /var/backmedia/ubun_1c77_`date '+\%Y-\%m-\%d'`.tar.gz

Тут посложнее.

На нужно набрать комманду sudo crontab -e и попасть в CRON, где и прописать задание.

Расшифруем параметры:

5 0 * * 6 время запуска (тут каждую субботу в 00:05)
tar -cP /var/www все папки со своей структурой помещаем в "портфель" (верхним каталогом будет корень системы)
| /bin/gzip -9 -c > создать архив из pipe и вывести его в файл с "родным" расширением .tar.gz
cp что куда копируем в резервное хранилище
`date '+\%Y-\%m-\%d'` выводим в имя файла год-месяц-день

В конце нажать Ctrl+X, подтвердить изменение нажав Y, потом Enter.

 

Как забэкапить ВСЮ MySQL базу в Ubuntu?

 

40 1 * * * /usr/bin/mysqldump -uXXXX -P3306 -h127.0.0.1 -p'YYYYY' --all-databases | /bin/gzip -9 -c > /media/hdd/backup/mysql_db_`date '+\%Y-\%m-\%d'`.gz

А тут надо "почесать репу".

Делаем аналогично предыдущему через CRON, но незабываем, что он очень капризен к нестандартному синтаксису!

Расшифруем параметры:

mysqldump -XXXX что будем бэкапить
-PXXXXX -h127.0.0.1 -p'XXXXXX' порт, адрес, пароль от базы
--all-databases какие базы будем бэкапить

 

Как забэкапить 1С 7.7 в Windows, вместе со всеми файлами?

 

@echo off

setlocal enableextensions enabledelayedexpansion

:: directory for backup in Petrozavodsk

set drS=G:\
set drD=D:\backup
set drL=D:\backup\logs

:: set time mark

set d=%DATE:~0,2%
set m=%DATE:~3,2%
set y=%DATE:~6,4%
set curdate=%y%.%m%.%d%
set h=%time:~0,2%
set m=%time:~3,2%
set s=%time:~6,2%
set curtime=%h%.%m%.%s%

:: exception file or folder

set incl=D:\backup\exclus.txt

:: name archive

set arh=ZZ-1C77-%date%.zip

:: max LZMA2

echo started at backup_%date%_%curtime% >> "%drL%\backup_log_%date%.txt"
"%ProgramFiles%\7-Zip\7z.exe" a -tzip -ssw -mx=5 -scsWIN "%drD%\%arh%" "%drS%" -x@"%incl%" -bso2 2>> "%drL%\backup_log_%date%.txt"
echo stoped at backup_%date%_%curtime% >> "%drL%\backup_log_%date%.txt"

:: upload Moscow base 1C to our server

"%ProgramFiles%\7-zip\7z.exe" x "%drD%\http\msk\YY-1C81-%date%.7z" -r -y -o"G:\YYYY\" 2>> "%drL%\backup_log_%date%.txt"

:: upload Sankt-Petersburg base 1C to our server

"%ProgramFiles%\7-zip\7z.exe" x "%drD%\http\spb\XX-1C77-%curdate%.7z" -r -y -o"G:\XXX\XXX\" 2>> "%drL%\backup_log_%date%.txt"

:: recursive delete old arhive & MMSQL files & files

forfiles -p "%drD%" -s -m *.zip -d -4 -c "cmd /c if /i @isdir equ false del /q /s @path"
forfiles -p "%drD%" -s -m *.bkp -d -4 -c "cmd /c if /i @isdir equ false del /q /s @path"
forfiles -p "%drD%" -s -m *.bak -d -4 -c "cmd /c if /i @isdir equ false del /q /s @path"
forfiles -p "%drD%" -s -m *.7z -d -4 -c "cmd /c if /i @isdir equ false del /q /s @path"
del /f /s /q "D:\1c_base\sale\*"

endlocal
exit

Ну это вообще МЕГА "палочка-выручалочка". Но не забывайте, что в "старых" версиях Windows, BAT выполняется в DOS в кодировке OEM 866! Для начала создайте файл в Notepad++ и смените в нём кодировку "Кирилица" - "OEM 866".

Ещё один момент - это использования файла списка исключений при бэкапе "exclus.txt". Каждая новая строка в нём - новое исключение.

G:\System Volume Information
G:\temp
*.LCK

Как забэкапить 1С 7.7 в SQL Express Windows?

 

Тут надо создать файл 1CMMSQLEbackup.sql вот с таким содежимым.

declare @path varchar(max)=N'D:\backup\backup_'+convert(varchar(max),getdate(),102)+'.bkp'
BACKUP DATABASE [ncm] TO DISK = @path WITH COPY_ONLY, NOFORMAT, NOINIT, NAME = N'ncm-backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10
GO

Расшифруем параметры:

declare @path указываем директорию
N это декларируемое имя - величина произвольная, как хотите так и называйте
'+convert(varchar(max),getdate(),102)+' задаём дату файла от системного времени
[ncm] название нашей базы данных

При желании, можете задать и проверку архива.

declare @backupSetId as int
declare @path varchar(max)=N'D:\backup\backup_'+convert(varchar(max),getdate(),102)+'.bkp'
select @backupSetId = position from msdb..backupset where database_name=N'ncm-backup' and backup_set_id=(select max(backup_set_id) from msdb..backupset where database_name=N'ncm-backup' )
if @backupSetId is null begin raiserror(N'Ошибка верификации. Сведения о резервном копировании для базы данных "ncm-backup" не найдены.', 16, 1) end
RESTORE VERIFYONLY FROM  DISK = @path WITH  FILE = @backupSetId,  NOUNLOAD,  NOREWIND
GO

Создаём в "Планировщике заданий" Виндовс задачу - указываем периодичность запуска и путь до самой программы.

"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE"

И указываем дополнительный аргумент.

-S .\sqlexpress -i "D:\backup\1CMMSQLEbackup.sql"

Расшифруем параметры:

...\SQLCMD.EXE SQL в коммандной строке
-S .\sqlexpress тут имя Вашего экземпляра SQL сервера
-i "D:\backup\1CMMSQLEbackup.sql" путь до запускаемого файла

Один момент! Если Вы переносите базу с сервера на сервер! То слетают привязки к пользователю! По непонятной причине данные привзки храняться в мастере донора, и нужно переназначать права в реципиенте КАЖДЫЙ РАЗ, когда восстанавливается база!

USE [ncm]
GO
EXEC [nw].dbo.sp_changedbowner @loginame = N'nw', @map = false
GO

 

Как уменьшить файл журнала .LDF SQL Express Windows?

 

Тут надо создать файл 1CMSSQLElogcleared.sql вот с таким содежимым.

USE [ncm]
GO
ALTER DATABASE [ncm] SET RECOVERY SIMPLE
GO
DBCC SHRINKFILE (N'ncm_log' , 0,)
ALTER DATABASE [ncm] SET RECOVERY FULL
GO

Расшифруем параметры:

SET RECOVERY SIMPLE переводим базу в режим архивирования SIMPLE
N'ncm_log' это имя лог файла
SET RECOVERY FULL возвращаем базу в режим архивирования FULL
[ncm] название нашей базы данных

Тут надо понимать, что РАБОЧАЯ база данных ВСЕГДА должна архивироваться в режиме FULL! А вот сервисные операции легче делать в режиме SIMPLE. Да, никто не спорит, что можно открыть SQL Server Management Studio (SSMS) и выполнить все манипуляции от туда. По сути, все скрипты выше и взяты напрямую из SSMS. Но не забываем, что у нас SQL Express и 90% автоматической работы с базами ему недоступны.

 

Как настроить SFTP в Windows 10?

 

Начнём с простого. FTPS - это FTP over SSL, его легко настроить в IIS, но толку с него 0.0%. Если мы хотим шифровать ВЕСЬ трафик, то нужен STPS - это SSH FTP, т.е. передача данных идёт в шифрованном туннеле. Для этого используем стандартный OpenSSH сервер перекочивавший в Win10.

Идём по пути "Пуск - Параметры - Приложения - Дополнительные параметры - Добавить компонент - Добавление дополнительного компонента - Сервер OpenSSH". Ждём окончания установки. И в "Службах Виндовс" ищем sshd OpenSSH SSH Server, его надо будет переключить в автоматический режим работы (лучше с задержкой старта) и запустить!

Запуск нужен для создания файлов в директории "C:\ProgramData\ssh\". А редактировать будем sshd_config. Ниже пункты которые должны быть или раскоментированны, или добавлены в файл:

PermitRootLogin no
AuthorizedKeysFile	.ssh/authorized_keys
PasswordAuthentication yes
AllowUsers you_sftuser
Subsystem	sftp	sftp-server.exe
Match User you_sftuser
	AllowTcpForwarding no
	ChrootDirectory C:\...\you_data

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

Расшифруем параметры:

you_sftuser имя пользователя (имена или группы, тогда Group пишем) в Windows, для которого открываем доступ
C:\...\you_data это директория к которой мы даём доступ данному пользователю (это решит проблему с брадмауером блокирующим 22 порт, но незабудьте выдать на эту директорию права в самой ОС)
PermitRootLogin блочим доступ "суперу"
...Keys... ключи по умолчанию лежат в папке самого пользователя; если не хотите создавать свои ключи и сертификаты - НИЧЕГО НЕ ТРОГАЙТЕ!

 

Теперь о подключении. Если у нас Windows, то в BAT файле пишем:

cd /d "D\backup\curl\bin\"
start /wait curl.exe -k sftp://XXX.XXX.XXX.XXX:1XX2/spb/ -u login:password -T "D\backup\sql.zip"

Не забываем, что curl, дожен быть с поддержкой SSL! Кроме этого, аргумент "-k" нужен Windows, чтобы обходить ошибочное понимание этого сертификата.

 

Если у нас Linux, то в Crontab пишем:

0 14 * * 6 lftp sftp://user:password@XXX.XXX.XXX.XXX:YYYY -e "put -c -O /ptz/ /var/backmedia/ptz_mail-chat_`date '+\%Y-\%m-\%d'`.tar.gz; exit"

Не забываем, что lftp, дожен быть с ключами SSL! Для этого, под root, сначала авторизируемся через sftp, и на вопрос о сохранении ключей пишем yes. При устаревании ключа или замене сервера удаляем файл по пути root/.ssh/known_host, или ключ старого сервера в этом файле!

sftp -oPort=1XXX2 login@XXX.XXX.XXX.XXX

 

Как использовать Robocopy в Windows 10 для копирования файла?

 

Robocopy - это программа для копирования файлов и папок, в том числе по сети и с атрибутами. Расширенный аналог copy и xcopy!

robocopy C:\Users\samba\Favorites\backup\ \\XXX.XXX.XXX.XXX\backup\ ваш_файл.7z /z /r:3 /mt

Расшифруем параметры:

/z режим перезапуска
/r:3 кол-во попыток (по умолчанию один миллион!), обычно идёт с параметром /w - ждать сколько-то секунд (по умолчанию 30сек.)
/mt режим многопоточности (по умолчанию выставит 8 потоков), эксперименты показали, что ставить больше, чем по умолчанию, есть смысл при локальном копировании множества файлов на многоядерном CPU

С Robocopy есть 2 проблемы. Во-первых, как видите, он не допускает ЭКРАНИРОВАНИЯ пути! Ну и параметр /z - абсолютно НИВЕЛИРУЕТ многопоточность; проблема в том, что при передаче по сети он проверяет каждый заголовок пакета, и файл в 3Гб с ним копируется 15 минут, а без него 1,5 минуты.

 

Как сверить файл при копировании на удалённый сервер, через hach file?

 

Тут задачу разбиваем на две части. Сначала получаем сам хэш, через встроенную в Windows утилиту.

certutil -hashfile "%drD%\1C77.bkp" MD5 | findstr ^[0-9a-f]$ >> "%drD%\1C77-sql-hash-ptz.txt"

Расшифруем параметры:

MD5 режим хэширования, вплоть до SHA 256
| findstr ^[0-9a-f]$ >> "поток выводим" в текстовой файл

Теперь вторая проблема. Хэш в зависимости от центрального процессора, типа операционной системы, программы посчёта. Может быть разным, и записывается в текстовый файл то же, как угодно. Поэтому нужно искать железо и ПО - одного рода. Остальное, решаем кодом сравнения хэша файла созданного на удалённой машине, и хэша с файла полученного на текущей машине.

FC /C /W /L "%drD%\1C77-sql-hash-ptz.txt" "%drD%\1C77-sql-hash-spb.txt"
if %errorlevel%==0 (goto step1) else (goto erase-spb-file)
:erase-spb-file
del /f /s /q "%drD%\1C77.bkp
:step1

Расшифруем параметры:

FC /C /W /L утилита сравнения: без регистра, без пробелов и табуляции, в формате ASCII
%errorlevel%==0 уровень ошибок, их всего 4, нас интересует только 0
goto step1 и goto erase-spb-file если хэш верен - идём дальше, если нет, то стираем бракованный файл

 

Как записывать разговоры и идентифицировать звонящего на MyPBX SOHO в связке с 1С

 

Вколачиваем код ниже в файл mypbx\persistent\var\lib\asterisk\db\custom-cfg\extensions_custom.conf (папка виртуальная, не пугаемся) соответственно Вашим транкам. Не забываем чистить папку souds-monitor вручную! Этот код сам этого не делает, и кода память станции закончится - она завистнет наглухо!!!

[macro-trunkdial-failover-0.3]
exten = s,1,NOOP(do call out)
exten = s,2,GotoIf(${DB_EXISTS(oblacklist/${ARG3})}?Blacklist-Handle,s,1)
exten = s,3,Gotoif($[${LEN(${FromSystemAlert})}>0]?6:4)})
exten = s,4,Gotoif($[${LEN(${ARG$[${ARG1}+4]})}>0]?5:6)
exten = s,5,Goto(s,6)
exten = s,6,Set(TCOUNT=4)
exten = s,n,Set(CDR(userfield)=Outbound)
exten = s,n,Set(OldCallerID=${IF($[${LEN(${PINUSER_CONTEXT})} > 0]?${PINUSER_CONTEXT:13}:${MACRO_CONTEXT:13})})
exten = s,n,Set(TOUCH_MONITOR=${OldCallerID}-${ARG3})
exten = s,n,NOOP(${DOD_${ARG${TCOUNT}}_${OldCallerID}})
exten = s,n(callnamed),Set(fname=out_${STRFTIME(${EPOCH},,%Y.%m.%d-%H.%M.%S)}-${CALLERID(number)}-${ARG3})
exten = s,n(callrecord),MixMonitor(/persistent/var/lib/asterisk/sounds/monitor/${fname}.wav,b)
exten = s,n,Set(TIMEOUT(absolute)=${IF($[${LEN(${ABSOLUTE_TIMEOUT_${OldCallerID}})} > 0]?${ABSOLUTE_TIMEOUT_${OldCallerID}}:${ABSOLUTE_TIMEOUT})})
exten = s,n,Set(DLSTAT=UNKNOW})
exten = s,n,SetCktCustom(sendrpid,no,no)
exten = s,n,Gotoif(${ARG1}>0?1-dial,1)
exten = 1-dial,1,Gotoif($[$[${TCOUNT}-3]>${ARG1}]?nextrouter,1)
exten = 1-dial,2,Gotoif($[${LEN(${DOD_${ARG${TCOUNT}}_${OldCallerID}})} > 2]?setdod,1:1-dial,3)
exten = 1-dial,3,Set(CALLERID(name)=${IF($[${LEN(${CID_${ARG${TCOUNT}}})} > 2]?${CID_${ARG${TCOUNT}}}:${CALLERID(name)})})
exten = 1-dial,4,Set(CALLERID(num)=${IF($[${LEN(${CID_${ARG${TCOUNT}}})} > 2]?${CID_${ARG${TCOUNT}}}:${CALLERID(num)})})
exten = 1-dial,5,Set(_SIPSRTP=${SIPPEER(${ARG${TCOUNT}},srtpcapable)})
exten = 1-dial,6,Set(OUTDIALOPT=${IF($[${LEN(${GSM_${ARG${TCOUNT}}})} > 0]?tTkKWwXxr:${DIALOPTIONS})})
exten = 1-dial,7,NOOP(null for std)
exten = 1-dial,8,Gotoif($[${LEN(${FromSystemAlert})}>0]?sys-dial,1)})
exten = 1-dial,9,Dial(${${ARG${TCOUNT}}}/${ARG2}${PREFIX_${ARG${TCOUNT}}}${ARG3},,${OUTDIALOPT})
exten = 1-dial,n,Goto(1-${DIALSTATUS},1)
exten = sys-dial,1,Macro(sysdial,${${ARG${TCOUNT}}}/${ARG2}${PREFIX_${ARG${TCOUNT}}}${ARG3},,${OUTDIALOPT})
exten = setdod,1,Set(CALLERID(name)=${DOD_${ARG${TCOUNT}}_${OldCallerID}})
exten = setdod,2,Set(CALLERID(num)=${DOD_${ARG${TCOUNT}}_${OldCallerID}})
exten = setdod,3,Goto(1-dial,5)
exten = 1-BUSY,1,Set(DLSTAT=9-${DIALSTATUS})
exten = 1-BUSY,2,Goto(2-dial,1)
exten = 1-CHANUNAVAIL,1,Set(DLSTAT=9-${DIALSTATUS})
exten = 1-CHANUNAVAIL,2,Goto(2-dial,1))
exten = 1-CONGESTION,1,Set(DLSTAT=9-${DIALSTATUS})
exten = 1-CONGESTION,2,Goto(2-dial,1)
exten = 2-dial,1,Set(TCOUNT=$[${TCOUNT}+1])
exten = 2-dial,2,Goto(1-dial,1)
exten = 1-out,1,playback(all-busy-now-try-call-later)
exten = 1-out,2,Hangup()
exten = 9-BUSY,1,playback(all-busy-now-try-call-later)
exten = 9-BUSY,2,Hangup()
exten = 9-CHANUNAVAIL,1,playback(all-busy-now-try-call-later)
exten = 9-CHANUNAVAIL,2,Hangup()
exten = 9-CONGESTION,1,playback(all-busy-now-try-call-later)
exten = 9-CONGESTION,2,Hangup()
exten = nextrouter,1,GotoIf($[${LEN(${NEXTROUTER})} > 0]?${NEXTROUTER},${ORGINEXTEN},1:${DLSTAT},1)
exten = h,1,NOOP(no thing to do)

[macro-incoming_pstnin]
exten = s,1,Set(CDR(userfield)=Inbound)
exten = s,n,GotoIf(${DB_EXISTS(blacklist/${CALLERID(num)})}?Blacklist-Handle,s,1)
exten = s,n,FindForMobile(${CALLERID(num)})
exten = s,n,GotoIf($[${LEN(${MobileToExten})}>1]?mobile-exten-match,${MobileToExten},1)
exten = s,n,Set(TRUNKDID=${IF($[${ARG2}=s]?${CALLERID(name)}:${ARG2})})
exten = s,n,Set(CALLERID(name)=PTZ)
exten = s,n(callnamed),Set(fname=in_${STRFTIME(${EPOCH},,%Y.%m.%d-%H.%M.%S)}-${CALLERID(number)}-${ARG2})
exten = s,n(callrecforwarding),Set(AUDIOHOOK_INHERIT(MixMonitor)=yes)
exten = s,n(callrecord),MixMonitor(/persistent/var/lib/asterisk/sounds/monitor/${fname}.wav,b)
exten = s,n,GotoByTimeCondition(default,voicemenu-custom-welcome,660,1,,voicemenu-custom-notwork,661,1,4_nov,voicemenu-custom-notwork,661,1)
exten = s,102,Goto(Blacklist-Handle,s,1)

Yeastar уже не выпускает такие станции, но такой код может ещё помочь в старших версиях. В нижнем сигменте теперь продают S20, там уже всё из коробки. Но в последних версиях, поменяна философия настроек! Особенно "больно" пришлось межстанционым звонкам. Теперь для входящего звонка нужно в нашей АТС создать "Входящий маршрут", в нём указать "Шаблон DID" номера нашей станции, указать линии группы, и в "Направление" указать номера нашей станции, на которые возможен вызов.