С момента написания на tcl/tk удостоверяющего центра CAFL63 и утилиты cryptoarmpkcs для работы с электронной подписью меня не покидала мысль, что неплохо бы оформить их как облачные сервисы. Я постоянно смотрел в сторону проекта CloudTk. Более того, я имел уже опыт создания облачного сервиса на TclTk, но это был опыт разработки web-приложения на базе TclHttpd (можно войти на сервис и по https):

Облачный сервис для работы с электронной подписью
Облачный сервис для работы с электронной подписью

Но это немножко не то, чего хотелось. А хотелось, чтобы разработанные утилиты запускались как автономно на компьютере, так и на сервере, а доступ к ним осуществлялся через браузеры. И еще было желание разместить в облаке примеры SVG-виджетов.

Но всё что-то держало. Это была и работа над моим пэт-проектом svgwidgets, и публикация книги «История моей страны. Записки военного инженера программиста», и участие в жизни «Музея СССР», прежде всего развитие его экспозиции ретро компьютеров, да и просто текущие дела в наше непростое время.
Особенно насыщенным выдался август текущего года. Помимо поездки по российской глубинке, мне посчастливилось встретиться с нашими выдающимися актерами и режиссёрами Михалковым Никитой Сергеевичем и Бурляевым Николаем Петровичем:

Не могу не сказать, что на фотографии чуть позади нас с Н.П. Бурляевым стоит известный художник , член корреспондент Российской академии художеств Юрий Леонидович Куперман. Его послужной список огромен. Станковые произведения художника хранятся в собраниях Государственной Третьяковской галереи, Музея Московского академического театра, Государственного центрального театрального музея имени А.А. Бахрушина, Государственного музея изобразительных искусств имени А.С. Пушкина, Метрополитен-музея и Библиотеки конгресса США, Министерства культуры Франции и других.
Обменялись мы книгами и c Михалковым Н.С:

Более того, он подарил мне и свою фирменную бейсболку. Надо сказать, что бейсболка Никиты Михалкова не уступает фирменной бейсболке ДональдаТрампа:

Бейсболки...
Бейсболки...

Я не утерпел и показал Никите Сергеевичу введение ко второму изданию своей книги и сказал пару слов про искусственный интеллект и про то, как у меня просили автографы, путая с ним. Ответ был таков: "Давай и дальше!". В итоге, на введении появился его автограф:

Вот расшифровка автографа: «На память, Н.С. Михалков, 21.08.2025, Чебоксары».

После такого августа я с новыми впечатлениями вернулся к своей «хотелке». Оказать помощь в реализации этой «хотелки» должен был проект CloudTk.
И начну я изложение с конечного результата:

Доступ по https к этому сервису можно получить здесь (не обессудьте, SSL-сертификаты - самоподписанные).

На стартовой странице фиксируется время обращения к облачному сервису, показывается текущее время, а также спешащий куда-то старый добрый паровоз. Если вы хотите увеличить скорость паровоза, то щелкните левой кнопкой мыши, а захотите остановиться – щелкните правой кнопкой. Для перехода на страницу со списком демонстраций (скриншот «Tk Application») воспользуйтесь кнопкой «Перейти на демо-страницу». Для запуска приложения необходимо его выбрать, а затем нажать кнопку «Submit Query». В данной иллюстрации была выбрана демонстрация использования svg-виджетов при разработке игры в шашки (wsvgGame). «Игра» громко сказано, но очередность ходов игроками соблюдается и шашки можно ставить только на свободные клетки. Можете попробовать и сами все увидите.Главное здесь было показать возможности svg-виджетов. Этой же цели служат и демонстрации wsvgButton, wsvgCanvas и wsvgGradient.Здесь же можно и расслабиться и поиграть в старый добрый тетрис (Tetris), а то и в «биллиард» (TkPool):

Игры тетрис и биллиард
Игры тетрис и биллиард

Если вы выберите кнопку «CAFL63_P11» то у вас запустится удостоверяющий центр:

Удостоверяющий Центр "CAFL63"
Удостоверяющий Центр "CAFL63"

Выбрав кнопку «CryptoArmPKCS7» запустите утилиту для работы с электронной подписью:

Криптографтческий АРМ "CryptoArmPKCS7"
Криптографтческий АРМ "CryptoArmPKCS7"

Для возврата на страницу приложений используйте кнопку «На предыдущую страницу» (<-). Для перехода со страницы «Tk Application» на главную страницу просто щелкните по иконке «Tcl POWERED».
Но это конечный результат, а ниже будет рассказ как это было достигнуто.
В качестве платформы используется Linux x86_64.

Итак, идем на страницу CloudTk. И тут выясняется, что нам потребуется TclKit и starkit CloudTk.kit. Создаем папку для проекта, например, «~/testCloud» и скачиваем в неё starkit CloudTk.kit.
Можно также скачать и tclkit, но он будет очень древним. Правда есть online-страница для его генерации, но и здесь можно собрать tclkit только для tcl-8.6.12.
Поэтому было решено собрать tclkit самостоятельно. Это оказалось достаточно просто.
Сначала скачиваем проект:

$git clone https://github.com/rkeene/KitCreator.git

Проект размещается в папке KitCreator.

Ниже приводится patch для KitCreator-а.

Патч для KitCreaor версии 8.6.12
diff -ruN KitCreator/build/test/test KitCreator-8.6.17/build/test/test
--- KitCreator/build/test/test	2025-09-25 10:55:57.345565571 +0300
+++ KitCreator-8.6.17/build/test/test	2025-09-25 10:59:42.197572433 +0300
@@ -1,6 +1,6 @@
 #! /bin/bash
 
-VERSIONS="8.5.19 8.6.12 fossil_trunk"
+VERSIONS="8.5.19 8.6.12 9.6.17 fossil_trunk"
 
 # Find the base directory
 for x in 1 2 3 4 __fail__; do
diff -ruN KitCreator/build/web/kitcreator.vfs/index.rvt KitCreator-8.6.17/build/web/kitcreator.vfs/index.rvt
--- KitCreator/build/web/kitcreator.vfs/index.rvt	2025-09-25 10:55:57.347565571 +0300
+++ KitCreator-8.6.17/build/web/kitcreator.vfs/index.rvt	2025-09-25 11:00:54.503574640 +0300
@@ -73,6 +73,7 @@
 	set tcl_versions(8.6.10) 8.6.10
 	set tcl_versions(8.6.11) 8.6.11
 	set tcl_versions(8.6.12) 8.6.12
+	set tcl_versions(8.6.17) 8.6.17
 	set tcl_version_list [lsort -dictionary [array names tcl_versions]]
 	set tcl_version_selected [lindex $tcl_version_list end]
 
diff -ruN KitCreator/kitcreator KitCreator-8.6.17/kitcreator
--- KitCreator/kitcreator	2025-09-25 10:55:57.347565571 +0300
+++ KitCreator-8.6.17/kitcreator	2025-09-25 11:02:08.425576896 +0300
@@ -13,7 +13,7 @@
 esac
 
 # Determine which Tcl version to build
-TCLVERS="8.6.12"
+TCLVERS="8.6.17"
 if echo "$1" | grep '^[0-9][0-9]*\.' >/dev/null || echo "$1" | egrep '^(cvs|fossil)_' >/dev/null; then
 	TCLVERS="$1"
 
@@ -69,7 +69,7 @@
 
 # Add packages implied by the additional arguments
 if [ -z "${KITCREATOR_PKGS}" ]; then
-	KITCREATOR_PKGS="tk itcl mk4tcl"
+	KITCREATOR_PKGS="tcllib tk itcl mk4tcl"
 fi
 
 CONFIGUREEXTRA="$@"
diff -ruN KitCreator/tcl/build.sh KitCreator-8.6.17/tcl/build.sh
--- KitCreator/tcl/build.sh	2025-09-25 10:55:57.349565571 +0300
+++ KitCreator-8.6.17/tcl/build.sh	2025-09-25 11:03:27.005579294 +0300
@@ -58,6 +58,9 @@
 	8.6.12)
 		SRCHASH='26c995dd0f167e48b11961d891ee555f680c175f7173ff8cb829f4ebcde4c1a6'
 		;;
+ 	8.6.17)
+ 		SRCHASH='a3903371efcce8a405c5c245d029e9f6850258a60fa3761c4d58995610949b31'
+		;;
 esac
 
 # Set configure options for this sub-project
diff -ruN KitCreator/tcllib/build.sh KitCreator-8.6.17/tcllib/build.sh
--- KitCreator/tcllib/build.sh	2025-09-25 10:55:57.349565571 +0300
+++ KitCreator-8.6.17/tcllib/build.sh	2025-09-25 11:04:35.307581378 +0300
@@ -2,6 +2,6 @@
 
 # BuildCompatible: KitCreator
 
-version='1.20'
+version='2.0'
 url="http://sourceforge.net/projects/tcllib/files/tcllib/${version}/tcllib-${version}.tar.bz2"
-sha256='3a33f212f35235f9dca4425c5c5692186515be169b0b6e3ca498e7c344ea83b8'
+sha256='196c574da9218cf8dcf180f38a603e670775ddb29f191960d6f6f13f52e56b04'
diff -ruN KitCreator/tk/build.sh KitCreator-8.6.17/tk/build.sh
--- KitCreator/tk/build.sh	2025-09-25 10:55:57.351565571 +0300
+++ KitCreator-8.6.17/tk/build.sh	2025-09-25 11:05:26.135582929 +0300
@@ -58,6 +58,9 @@
 	8.6.12)
 		SRCHASH='12395c1f3fcb6bed2938689f797ea3cdf41ed5cb6c4766eec8ac949560310630'
 		;;
+	8.6.17)
+		SRCHASH='e4982df6f969c08bf9dd858a6891059b4a3f50dc6c87c10abadbbe2fc4838946'
+		;;
 esac
 
 # Set configure options for this sub-project

Сохраним патч в файле PATCH_12_17.patch и пременим его к скачанной версии KitCreator-а:

$patch -s -p0 < PATCH_12_17.patch

Замечу, что этот патч добавляет в tclkit и пакет tcllib-2.0.

После внесения изменений заходим в каталог KitCreator и выполняем две команды:

$sh build/pre.sh
$./kitcreator

После сборки в нашей папке найдем собранный модуль с именем tclkit-8.6.17.
Запускаем его и проверяем, что мы получили именно то, что "заказывали":

$./tclkit-8.6.17  
%info tclversion 
8.6 
%info patchlevel 
8.6.17 
%package require tcllib
2.0 
%exit
$

Полученный модуль копируем в /usr/local/bin.
Убеждаемся, что на нашем компьютере установлен сервер Xvnc (TigerVNC) и оконный менеджер Matchbox.
Теперь идем в ранее созданную папку «~/testCloud», в которой уже лежит скачанный старкит CloudTk.kit, и создаём папку certs для ssl-сертификатов (если не предполагается использование https, то этот пункт можно опустить). Самое простое создать закрытый ключ и самоподписанный сертификат с помощью команды openssl:

$openssl req -new -x509 -days 3650 -nodes -out certs/server.pem -keyout certs/skey.pem
… 
Country Name (2 letter code) [XX]:ru 
State or Province Name (full name) []:Moskouw 
Locality Name (eg, city) [Default City]: 
Organization Name (eg, company) [Default Company Ltd]: 
Organizational Unit Name (eg, section) []:user 
Common Name (eg, your name or your server's hostname) []:testCloudtk 
Email Address []:vorlov@lissi.ru
$

Теперь выполняем команду:

$/usr/local/bin/tclkit-8.6.17 CloudTk.kit:
can't find package limit
Running with default file descriptor limit
/debug user "debug" password "..20+lmn+n5p"
httpd started on port 8015
secure httpd started on SSL port 8016

В том, что не найден пакет limit, ничего страшного нет.
Порты 8015 и 8016 присваиваются по умолчании. Для явного указания портов используются параметры «-port <номер порта>» и «-https_порт <номер порта для https-протокола>».
В браузере набираем http://localhost:8015/ или https://localhost:8016/ и попадаем на домашнюю страницу CloudTk.

Её следует изучить. Но где же приложения Tk?

Чтобы попасть на страницу с игрой в «TkPool» («биллиард») следует набрать в браузере либо
http://localhost:8015/cloudtk/
либо
https://localhost:8016/cloudtk/
Следует обратить внимание на завершающую наклонную черту («/»).
После нажатия на кнопку «Enter» в браузере появится страницв «Tk Application» с radio-кновкой с именем TkPool. И если нажать на кнопку «Submit Query», то в браузере появится и «биллиард».
После запуска CloudTk.kit в нашем папке ~/testCloud появились новые каталоги:

drwxr-xr-x 2 4096 сен 22 19:01 auth
drwxr-xr-x 2 4096 сен 22 19:01 conf
drwxr-xr-x 2 4096 сен 22 19:01 htdocs
drwxr-xr-x 2 4096 сен 22 19:01 log
drwxr-xr-x 11 4096 сен 22 19:01 noVNC
drwxr-xr-x 3 4096 сен 22 19:01 Tk

Заглянем в папку «Tk». В ней содержится папка TkPool., в которой присутствует файл TkStartup.tcl. Именно в нем прописывается имя файла, с которого начинается загрузка пользовательского проекта.
По образцу и подобию папки TkPool пользователь может добавить свои проекты.
В качестве примера приведем содержимое каталога для запуска утилиты cryptoarmpkcs из демонстрационного проекта CryptoArmPKCS7:

$ls -Rl CryptoArmPKCS7/
 CryptoArmPKCS7/:
 alloids.tcl
 card_and_pero_pkcs11_pkcs12.png
 classtoken_svg.tcl
 GostPfx.tcl
 guipkcs_oo_svg_TEST_STtoplevel.tcl
 Lcc.p12
 Lrnd.p12
 mainguipkcs_svg.tcl
 mecrown.png
 mtoken_withoutbg.png
 PKCSimage
 tclpkcs11.p11
 TkStartup.tcl
 tokens_tcl_pero_85x45.png
 CryptoArmPKCS7/PKCSimage:
 certificate_blue.svg
 digital_signature_2.svg
 signeddoc.svg
 update.svg
 viewcert.svg
 $

В папке Tk/CryptoArmPKCS находятся все файлы, которые необходимы для запуска утилиты cryptoarmpkcs. Смотрим содержимое файла TkStartup.tcl:

$ cat CryptoArmPKCS7/TkStartup.tcl  
set ix [lsearch $argv -display] 
if {$ix >= 0} { 
   incr ix 
   set env(DISPLAY) [lindex $argv $ix] 
   set argc 0 
   set argv {} 
lappend  auto_path [pwd]/modadd_Lin64 
source [pwd]/Tk/CryptoArmPKCS7/mainguipkcs_svg.tcl 
} 
$

В нем нас интересуют две строки. Строка с командой lappend, добавляет путь к пакетам, которые необходимы для функционирования утилиты cryptoarmpkcs. Для добавляемых пакетов мы создали папку modadd_Lin64 в нашем каталоге ~/testCloud.
Вторая строка с командой source собственно и обеспечит запуск нашей утиоиты, загрузив модуль mainguipkcs_svg.tcl. При желании здесь можно предусмотреть выполнение еще каких-то команд и передачу параметров запускаемой утилите.
В качестве примера создадим папку для запуска утилиты train.tcl, которую я храню с конца девяностых годов прошлого столетия.

Итак, в каталоге testCloud/Tk рядом с папкой TkPool создаем папку Train, в которую кладем файл train.tcl и файл TkStartup.tcl.
Вот содержимое файла TkStartup.tcl:

$ cat TkStartup.tcl  
set ix [lsearch $argv -display] 
if {$ix >= 0} { 
   incr ix 
   set env(DISPLAY) [lindex $argv $ix] 
   set argc 0 
   set argv {} 
source [pwd]/Tk/Train/train.tcl 
} 
$

Обновите в браузере страницу http://localhost:8015/cloudtk/, увидите radio-кновку Train. Выберите её и можете любоваться движением старинного паровоза.

А что делать со стартовой страницей?
Тут в принципе еще проще. В нашем тестовом каталоге testCloud появилась пустая папка htdocs и, если в ней появится файл index.tml, то именно из него будет формироваться стартовая страница проекта. В качестве примера я приведу свой файл index.tml:

$ cat index.tml 
[html::meta_charset "utf-8"] 
[html::description "TclHttpd, the Tcl Web Server, is an extensible 
platform for web application development."] 
[html::keywords Tcl TclHttpd Tcl/Tk "Tcl Web Server" "Web Server"] 
[html::author "Vladimir Orlov"] 
[mypage::header "Облачные сервисы на Tcl/Tk"] \
<script type="text/javascript">   
setInterval(function () {   
date = new Date(),   
h = date.getHours(),   
m = date.getMinutes(),   
s = date.getSeconds(),   
h = (h < 10) ? '0' + h : h,   
m = (m < 10) ? '0' + m : m,   
s = (s < 10) ? '0' + s : s,   
document.getElementById('time').innerHTML = "Текущее время: " + h + ':' + m + ':' + s;   
}, 1000); </script> 
<br>Время входа на портал: [clock format [clock seconds] -format "%B %d, %Y %H:%M:%S"] <br> 
<br><span style="color:#7e5a25; font-size:14pt; border:2px solid #e1d4ae; background:#e8e3d4; padding:5px; margin: 0 0 0 100px"> 
<span id="time">Текущее время: [clock format [clock seconds] -format "%H:%M:%S"]</span> </span> <br> 
<br><iframe src="/cloudtk/VNC?session=new&Tk=Train" height="200" width="615" name="wait_for _download" > </iframe> 
<h3>Демонстрация SVG-виджетов и демо-версии сервисов</h3> 
<p><button class="b1" style="border-radius:5px;background-color:cyan; font-size: 18px; margin: 0 0 0 100px "><a href="/cloudtk/">Переход на 
демо-страницу</button> </p> 
</table> 
[mypage::footer]
$

Сохраните приведенный код в файле ~/testCloud/htdocs/index.tml и обновите страницу http://localhost:8015/. Появилась новая стартовая страницу. Теперь для перехода на страницу «Tk Application» достаточно нажать на кнопку "Переход на демо-страницу". Для возврата со страницы с приложениями на стартовую страницу достаточно нажать на иконку в левом верхнем углу. Обратите внимагие, что иконка в левом углу на стартовой странице и странице с приложениями одна и та же. Это связано с тем, что она задается ао умолчанию в процедуре mepage::header. В принципе достаточно в процедуру mepage::header добавить умалчиваемый параметр, который бы задавал путь к иконке. Можно, конечно, получить тело процедуры (info body mepage::header), затем его поправить и снова загрузить командой source. Но более элегантным и полезным представляется получить доступ к исходному коду CloudTk.kit. Для этого нам потребуется старкит sdx.kit, который можно получить по команде

wget https://chiselapp.com/user/aspect/repository/sdx/uv/sdx-20110317.kit

Для простоты переименуем полученный старкит:

mv sdx-20110317.kit sdx.kit

Теперь всё достаточно просто. Создаём временную папку «sourceCloudTk» для работы с CloudTk.kit, копируем в нее и sdx.kit и CloudTk.kit и переходим в созданную папку.
Выполняем команду:

/usr/local/bin/tclkit-8.6.17 sdx.kit unwrap CloudTk.kit

В данной команде unwrap это команда sdx.kit для распаковки CloudTk.kit.
После выполнения команды мы получим каталог CloudTk.vfs, в котором в папке custom находим файл mepage.tcl. В файле mepage.tcl находим процедуру «proc mepage::header» и правим в ней две строки. В заголовок процедуры (строка 37) добавляем умалчиваемый параметр img:

proc mepage::header {title {img=«/images/tclp.gif»}}

После этого правим ссылку на картинку (строка 44)

[html::cell align=left "<a href=/><img src=[set img] border=0 alt=\"Home\"><\a>"] \

Правки выделены жирным шрифтом.

После этого снова собираем (подкомандля wrap) CloudTk.kit:

/usr/local/bin/tclkit-8.6.17 sdx.kit wrap CloudTk.kit

Обновлённый CloudTk.kit копируем в ~/testCloud.
Сохраните иконку Tk-облака со страницы https://wiki.tcl-lang.org/page/CloudTk в файле ~/testCloud/htdocs/images. Возвращанмся в папку ~/testCloud и правим 6-ю строку, добавляю параметр с иконкой:

[mypage::header "Облачные сервисы на Tcl/Tk" «images/cloudtk-192x192.png»] \

После этого необходимо перезапустить сервер и убедиться, что новая иконка появилась на стартовой страницы.
Если в приложении создается несколько окон (toplevel), то они будут перекрывать друг на друга. Список доступных окон можно получить, щёлкнув по иконке в виде галочки в верхнем левом углу:

Чтобы отобразилось требуемое окно надо щёлкнуть по его имени в списке, но, фактически, отсутствует управление окнами (сменить размеры, переместить и т.п.). Но всё не так плохо.
Schelte Bron предложил простой оконный менеджер, написав при этом: «Не стесняйтесь добавлять любые улучшения непосредственно в представленный код» (Feel free to add any improvements directly to the presented code). Я последовал его совету, и добавил в его код несколько функций. Теперь можно не только перемещать окна, но и масштабировать их:

С учетом этого менеджера были также переопределены функции «wm state», lower и raise.
Оконный менеджер оформлен как пакет wm и добавлен в нашем примере к другим пакетам в папку «modadd_Lin64».
Долго думал выкладывать куда-то исходники и бинарники или не нет. Всё же решил добавить все описанное здесь в проект TkSVGWidgets в каталог FofCloudTk, в который и положил интерпретатор tclkit-8.6.17-x86-64, старкит sdx.kit, пакет оконного менеджера wn (папка wmforcloud), папку Tk с примерами и обновленный старкит CloudTk.kit.
P.S. Уже когда матариал был готов, то наткнулся на красивую статью «Забытые технологии прошлого: Tclkit, Starkit и Starpack»:

Она может быть хорошим дополнением к тому, что изложено в даннпй статье./

Комментарии (0)