Newer
Older
///////////////////////////////////////////////////////////////////////////////////////////////////
// Прикладной интерфейс
Перем мНастройки;
Перем Лог;
Перем мИдентификаторКластера;
Перем ЭтоWindows;
Процедура ЗарегистрироватьКоманду(Знач ИмяКоманды, Знач Парсер) Экспорт
ОписаниеКоманды = Парсер.ОписаниеКоманды(ИмяКоманды, "Управление сеансами информационной базы");
Сосна Евгений
committed
Парсер.ДобавитьПозиционныйПараметрКоманды(ОписаниеКоманды, "Действие", "lock|unlock|kill");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "-ras", "Сетевой адрес RAS, по умолчанию localhost:1545");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "-rac", "Команда запуска RAC, по умолчанию находим в каталоге установки 1с");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "-db", "Имя информационной базы");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-db-user",
"Пользователь информационной базы");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-db-pwd",
"Пароль пользователя информационной базы");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-cluster-admin",
"Администратор кластера");
Сосна Евгений
committed
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-cluster-pwd",
"Пароль администратора кластера");
Сосна Евгений
committed
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-v8version",
"Маска версии платформы 1С");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-lockmessage",
"Сообщение блокировки");
Сосна Евгений
committed
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-lockuccode",
"Ключ разрешения запуска");
Сосна Евгений
committed
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-lockstart",
"Время старта блокировки пользователей, время указываем как '2040-12-31T23:59:59'");
Сосна Евгений
committed
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-lockstartat",
"Время старта блокировки через n сек");
Парсер.ДобавитьКоманду(ОписаниеКоманды);
КонецПроцедуры
Функция ВыполнитьКоманду(Знач ПараметрыКоманды) Экспорт
ПрочитатьПараметры(ПараметрыКоманды);
Если Не ПараметрыВведеныКорректно() Тогда
Возврат МенеджерКомандПриложения.РезультатыКоманд().НеверныеПараметры;
КонецЕсли;
Если мНастройки.Действие = "lock" Тогда
УстановитьСтатусБлокировкиСеансов(Истина);
ИначеЕсли мНастройки.Действие = "unlock" Тогда
УстановитьСтатусБлокировкиСеансов(Ложь);
ИначеЕсли мНастройки.Действие = "kill" Тогда
УстановитьСтатусБлокировкиСеансов(Истина);
ОтключитьСуществующиеСеансы();
Иначе
Лог.Ошибка("Неизвестное действие: " + мНастройки.Действие);
Возврат МенеджерКомандПриложения.РезультатыКоманд().НеверныеПараметры;
КонецЕсли;
Возврат МенеджерКомандПриложения.РезультатыКоманд().НеРеализовано;
КонецФункции
Процедура ПрочитатьПараметры(Знач ПараметрыКоманды)
мНастройки = Новый Структура;
Для Каждого КЗ Из ПараметрыКоманды Цикл
Лог.Отладка(КЗ.Ключ + " = " + КЗ.Значение);
КонецЦикла;
мНастройки.Вставить("АдресСервераАдминистрирования", ПараметрыКоманды["-ras"]);
мНастройки.Вставить("ПутьКлиентаАдминистрирования", ПараметрыКоманды["-rac"]);
мНастройки.Вставить("ИмяБазыДанных", ПараметрыКоманды["-db"]);
мНастройки.Вставить("АдминистраторИБ", ПараметрыКоманды["-db-user"]);
мНастройки.Вставить("ПарольАдминистратораИБ", ПараметрыКоманды["-db-pwd"]);
мНастройки.Вставить("АдминистраторКластера", ПараметрыКоманды["-cluster-admin"]);
мНастройки.Вставить("ПарольАдминистратораКластера", ПараметрыКоманды["-cluster-pwd"]);
Сосна Евгений
committed
мНастройки.Вставить("ИспользуемаяВерсияПлатформы", ПараметрыКоманды["-v8version"]);
мНастройки.Вставить("КлючРазрешенияЗапуска", ПараметрыКоманды["-lockuccode"]);
мНастройки.Вставить("СообщениеОблокировке", ПараметрыКоманды["-lockmessage"]);
мНастройки.Вставить("ВремяСтратаБлокировки", ПараметрыКоманды["-lockstart"]);
мНастройки.Вставить("ВремяСтратаБлокировкиЧерез", ПараметрыКоманды["-lockstartat"]);
мНастройки.Вставить("Действие", ПараметрыКоманды["Действие"]);
Сосна Евгений
committed
//Получим путь к платформе если вдруг не установленна
мНастройки.ПутьКлиентаАдминистрирования = ПолучитьПутьКRAC(мНастройки.ПутьКлиентаАдминистрирования, мНастройки.ИспользуемаяВерсияПлатформы);
Если ПустаяСтрока(мНастройки.АдресСервераАдминистрирования) Тогда
мНастройки.АдресСервераАдминистрирования = "localhost:1545";
КонецЕсли;
КонецПроцедуры
Функция ПараметрыВведеныКорректно()
Успех = Истина;
Если Не ЗначениеЗаполнено(мНастройки.АдресСервераАдминистрирования) Тогда
Лог.Ошибка("Не указан сервер администрирования");
Успех = Ложь;
КонецЕсли;
Если Не ЗначениеЗаполнено(мНастройки.ПутьКлиентаАдминистрирования) Тогда
Лог.Ошибка("Не указан клиент администрирования");
Успех = Ложь;
КонецЕсли;
Если Не ЗначениеЗаполнено(мНастройки.ИмяБазыДанных) Тогда
Лог.Ошибка("Не указано имя базы данных");
Успех = Ложь;
КонецЕсли;
Если Не ЗначениеЗаполнено(мНастройки.Действие) Тогда
Лог.Ошибка("Не указано действие lock/unlock");
Успех = Ложь;
КонецЕсли;
Возврат Успех;
КонецФункции
/////////////////////////////////////////////////////////////////////////////////
// Взаимодействие с кластером
Процедура УстановитьСтатусБлокировкиСеансов(Знач Блокировать)
КлючиАвторизацииВБазе = "";
Если ЗначениеЗаполнено(мНастройки.АдминистраторИБ) Тогда
КлючиАвторизацииВБазе = КлючиАвторизацииВБазе + СтрШаблон(" --infobase-user=""%1""", мНастройки.АдминистраторИБ);
КонецЕсли;
Если ЗначениеЗаполнено(мНастройки.ПарольАдминистратораИБ) Тогда
КлючиАвторизацииВБазе = КлючиАвторизацииВБазе + СтрШаблон(" --infobase-pwd=""%1""", мНастройки.ПарольАдминистратораИБ);
КонецЕсли;
Сосна Евгений
committed
ИдентификаторКластера = ИдентификаторКластера();
ИдентификаторБазы = ИдентификаторБазы();
КлючРазрешенияЗапуска = ?(ПустаяСтрока(мНастройки.КлючРазрешенияЗапуска), ИдентификаторБазы, мНастройки.КлючРазрешенияЗапуска);
ВремяБлокировки = мНастройки.ВремяСтратаБлокировки;
Если ПустаяСтрока(ВремяБлокировки) И Не ПустаяСтрока(мНастройки.ВремяСтратаБлокировкиЧерез) Тогда
Секунды = 0;
Попытка
Секунды = Число(мНастройки.ВремяСтратаБлокировкиЧерез);
Исключение
КонецПопытки;
Сосна Евгений
committed
ВремяБлокировки = Формат(ТекущаяДата()+Секунды,"ДФ='yyyy-MM-ddTHH:mm:ss'");
Сосна Евгений
committed
КонецЕсли;
КомандаВыполнения = СтрокаЗапускаКлиента() + СтрШаблон("infobase update --infobase=""%3""%4 --cluster=""%1""%2 --sessions-deny=%5 --denied-message=""%6"" --denied-from=""%8"" --permission-code=""%7""",
ИдентификаторКластера,
КлючиАвторизацииВКластере(),
ИдентификаторБазы,
КлючиАвторизацииВБазе,
?(Блокировать, "on", "off"),
Сосна Евгений
committed
мНастройки.СообщениеОблокировке,
КлючРазрешенияЗапуска,
ВремяБлокировки);
ЗапуститьПроцесс(КомандаВыполнения);
Лог.Информация("Сеансы " + ?(Блокировать, "запрещены", "разрешены"));
КонецПроцедуры
Функция ИдентификаторКластера()
Если мИдентификаторКластера = Неопределено Тогда
Лог.Информация("Получаю список кластеров");
КомандаВыполнения = СтрокаЗапускаКлиента() + "cluster list";
СписокКластеров = ЗапуститьПроцесс(КомандаВыполнения);
УИДКластера = Сред(СписокКластеров,(Найти(СписокКластеров,":")+1),Найти(СписокКластеров,"host")-Найти(СписокКластеров,":")-1);
мИдентификаторКластера = СокрЛП(СтрЗаменить(УИДКластера,Символы.ПС,""));
КонецЕсли;
Если ПустаяСтрока(мИдентификаторКластера) Тогда
ВызватьИсключение "Кластер серверов отсутствует";
КонецЕсли;
Возврат мИдентификаторКластера;
Если мИдентификаторБазы = Неопределено Тогда
мИдентификаторБазы = НайтиБазуВКластере();
КонецЕсли;
Возврат мИдентификаторБазы;
КомандаВыполнения = СтрокаЗапускаКлиента() + СтрШаблон("infobase summary list --cluster=""%1""%2",
ИдентификаторКластера(),
КлючиАвторизацииВКластере());
Лог.Информация("Получаю список баз кластера");
СписокБазВКластере = ЗапуститьПроцесс(КомандаВыполнения);
ЧислоСтрок = СтрЧислоСтрок(СписокБазВКластере);
НайденаБазаВКластере = Ложь;
Для К = 1 По ЧислоСтрок Цикл
СтрокаРазбора = СтрПолучитьСтроку(СписокБазВКластере,К);
ПозицияРазделителя = Найти(СтрокаРазбора,":");
Если Найти(СтрокаРазбора,"infobase")>0 Тогда
УИДИБ = СокрЛП(Сред(СтрокаРазбора,ПозицияРазделителя+1));
ИначеЕсли Найти(СтрокаРазбора,"name")>0 Тогда
ИмяБазы = СокрЛП(Сред(СтрокаРазбора,ПозицияРазделителя+1));
Сосна Евгений
committed
Если Нрег(ИмяБазы) = НРег(мНастройки.ИмяБазыДанных) Тогда
Сообщить("Получен УИД базы");
НайденаБазаВКластере = Истина;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не НайденаБазаВКластере Тогда
ВызватьИсключение "База "+мНастройки.ИмяБазыДанных +" не найдена в кластере";
КомандаВыполнения = "";
Если ЗначениеЗаполнено(мНастройки.АдминистраторКластера) Тогда
КомандаВыполнения = КомандаВыполнения + СтрШаблон(" --cluster-user=""%1""", мНастройки.АдминистраторКластера);
КонецЕсли;
Если ЗначениеЗаполнено(мНастройки.ПарольАдминистратораКластера) Тогда
КомандаВыполнения = КомандаВыполнения + СтрШаблон(" --cluster-pwd=""%1""", мНастройки.ПарольАдминистратораКластера);
КонецЕсли;
Возврат КомандаВыполнения;
Перем ПутьКлиентаАдминистрирования;
Если ЭтоWindows Тогда
ПутьКлиентаАдминистрирования = ЗапускПриложений.ОбернутьВКавычки(мНастройки.ПутьКлиентаАдминистрирования);
Иначе
ПутьКлиентаАдминистрирования = мНастройки.ПутьКлиентаАдминистрирования;
КонецЕсли;
Возврат ПутьКлиентаАдминистрирования + " " +
мНастройки.АдресСервераАдминистрирования + " ";
КонецФункции
Функция ЗапуститьПроцесс(Знач СтрокаВыполнения)
Перем ПаузаОжиданияЧтенияБуфера;
ПаузаОжиданияЧтенияБуфера = 10;
Процесс = СоздатьПроцесс(СтрокаВыполнения,,Истина);
ТекстБазовый = "";
Счетчик = 0; МаксСчетчикЦикла = 100000;
Пока Истина Цикл
Текст = Процесс.ПотокВывода.Прочитать();
Лог.Отладка("Цикл ПотокаВывода "+Текст);
Если Текст = Неопределено ИЛИ ПустаяСтрока(СокрЛП(Текст)) Тогда
Прервать;
КонецЕсли;
Счетчик = Счетчик + 1;
Если Счетчик > МаксСчетчикЦикла Тогда
Прервать;
КонецЕсли;
ТекстБазовый = ТекстБазовый + Текст;
sleep(ПаузаОжиданияЧтенияБуфера); //Подождем, надеюсь буфер не переполниться.
КонецЦикла;
Если Процесс.КодВозврата = 0 Тогда
Текст = Процесс.ПотокВывода.Прочитать();
ТекстБазовый = ТекстБазовый + Текст;
Лог.Отладка(ТекстБазовый);
Возврат ТекстБазовый;
Иначе
ВызватьИсключение "Сообщение от RAS/RAC
|" + Процесс.ПотокОшибок.Прочитать();
КонецЕсли;
Процедура ОтключитьСуществующиеСеансы()
Лог.Информация("Отключаю существующие сеансы");
СеансыБазы = ПолучитьСписокСеансов();
Для Каждого Сеанс Из СеансыБазы Цикл
Сосна Евгений
committed
Попытка
ОтключитьСеанс(Сеанс);
Исключение
Лог.Ошибка(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Функция ПолучитьСписокСеансов()
ТаблицаСеансов = Новый ТаблицаЗначений;
ТаблицаСеансов.Колонки.Добавить("Идентификатор");
ТаблицаСеансов.Колонки.Добавить("Приложение");
ТаблицаСеансов.Колонки.Добавить("Пользователь");
ТаблицаСеансов.Колонки.Добавить("НомерСеанса");
КомандаЗапуска = СтрокаЗапускаКлиента() + СтрШаблон("session list --cluster=""%1""%2 --infobase=""%3""",
ИдентификаторКластера(),
КлючиАвторизацииВКластере(),
ИдентификаторБазы());
СписокСеансовИБ = ЗапуститьПроцесс(КомандаЗапуска);
Данные = РазобратьПоток(СписокСеансовИБ);
Для Каждого Элемент Из Данные Цикл
ТекСтрока = ТаблицаСеансов.Добавить();
ТекСтрока.Идентификатор = Элемент["session"];
ТекСтрока.Пользователь = Элемент["user-name"];
ТекСтрока.Приложение = Элемент["app-id"];
ТекСтрока.НомерСеанса = Элемент["session-id"];
КонецФункции
Процедура ОтключитьСеанс(Знач Сеанс)
СтрокаВыполнения = СтрокаЗапускаКлиента() + СтрШаблон("session terminate --cluster=""%1""%2 --session=""%3""",
ИдентификаторКластера(),
КлючиАвторизацииВКластере(),
Сеанс.Идентификатор);
Лог.Информация(СтрШаблон("Отключаю сеанс: %1 [%2] (%3)", Сеанс.НомерСеанса, Сеанс.Пользователь, Сеанс.Приложение));
Сосна Евгений
committed
ЗапуститьПроцесс(СтрокаВыполнения);
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
Функция ПолучитьСписокСоединений()
СтрокаВыполнения = "%RacClient% %ХостСервера% connection %УидКластера% %АдминКластера% %ПарольАдминаКластера% list %Процесс% %УИДИБ% %АдминБазы% %ПарольАдминаБазы% > %ФайлПотока% 2> %ФайлОшибки%";
КомандаЗапускаПроцессы = СтрокаЗапускаКлиента() + СтрШаблон("process list --cluster=""%1""%2",
ИдентификаторКластера(),
КлючиАвторизацииВКластере());
Лог.Информация("Получаю список рабочих процессов");
СписокПроцессов = ВыполнитьКоманду(КомандаЗапускаПроцессы);
ЧислоСтрок = СтрЧислоСтрок(СписокПроцессов);
КонецФункции
Функция РазобратьПоток(Знач Поток) Экспорт
ТД = Новый ТекстовыйДокумент;
ТД.УстановитьТекст(Поток);
СписокОбъектов = Новый Массив;
ТекущийОбъект = Неопределено;
Для Сч = 1 По ТД.КоличествоСтрок() Цикл
Текст = ТД.ПолучитьСтроку(Сч);
Если ПустаяСтрока(Текст) или ТекущийОбъект = Неопределено Тогда
Если ТекущийОбъект <> Неопределено и ТекущийОбъект.Количество() = 0 Тогда
Продолжить; // очередная пустая строка подряд
КонецЕсли;
ТекущийОбъект = Новый Соответствие;
СписокОбъектов.Добавить(ТекущийОбъект);
КонецЕсли;
ПозицияРазделителя = Найти(Текст,":");
Если ПозицияРазделителя = 0 Тогда
Продолжить;
КонецЕсли;
СтрокаРазбораИмя = СокрЛП(Лев(Текст,ПозицияРазделителя-1));
СтрокаРазбораЗначение = СокрЛП(Сред(Текст,ПозицияРазделителя+1));
ТекущийОбъект[СтрокаРазбораИмя] = СтрокаРазбораЗначение;
КонецЦикла;
Если ТекущийОбъект <> Неопределено и ТекущийОбъект.Количество() = 0 Тогда
СписокОбъектов.Удалить(СписокОбъектов.ВГраница());
КонецЕсли;
Возврат СписокОбъектов;
КонецФункции
Сосна Евгений
committed
Функция ПолучитьПутьКRAC(ТекущийПуть, Знач ВерсияПлатформы="")
Если НЕ ПустаяСтрока(ТекущийПуть) Тогда
ФайлУтилиты = Новый Файл(ТекущийПуть);
Если ФайлУтилиты.Существует() Тогда
Лог.Отладка("Текущая версия rac "+ФайлУтилиты.ПолноеИмя);
Возврат ФайлУтилиты.ПолноеИмя;
КонецЕсли;
КонецЕсли;
Если ПустаяСтрока(ВерсияПлатформы) Тогда
ВерсияПлатформы="8.3";
КонецЕсли;
Конфигуратор = Новый УправлениеКонфигуратором;
ПутьКПлатформе = Конфигуратор.ПолучитьПутьКВерсииПлатформы(ВерсияПлатформы);
Лог.Отладка("Используемый путь для поиска rac "+ПутьКПлатформе);
КаталогУстановки = Новый Файл(ПутьКПлатформе);
Лог.Отладка(КаталогУстановки.Путь);
Сосна Евгений
committed
ИмяФайла = ?(ЭтоWindows, "rac.exe", "rac");
ФайлУтилиты = Новый Файл(ОбъединитьПути(Строка(КаталогУстановки.Путь), ИмяФайла));
Если ФайлУтилиты.Существует() Тогда
Лог.Отладка("Текущая версия rac "+ФайлУтилиты.ПолноеИмя);
Возврат ФайлУтилиты.ПолноеИмя;
КонецЕсли;
Возврат ТекущийПуть;
КонецФункции
/////////////////////////////////////////////////////////////////////////////////
СистемнаяИнформация = Новый СистемнаяИнформация;
ЭтоWindows = Найти(НРег(СистемнаяИнформация.ВерсияОС), "windows") > 0;
Лог = Логирование.ПолучитьЛог("vanessa.app.deployka");