UMGUM.COM 

XWiki + ShortURLs ( Избавление URL документа в "XWiki" от избыточных составляющих. )

6 мая 2020  (обновлено 6 июля 2020)

OS: "Linux Debian 9/10", "Linux Ubuntu Server 16/18 LTS".
Apps: "Ansible", "XWiki", "Docker", "Docker Compose".

Задача: избавление URL документа в "XWiki" от избыточных составляющих.

Сразу после установки "XWiki" из дистрибутива типичный URL современного режима отображения "Domain-based wiki access" выглядит следующим образом (с бессмысленными "bin" и "view" в середине):

https://xwiki.example.net/[xwiki/]bin/view/level0/level1/level2/

Это некрасиво, и я не первый, кто захотел избавиться от лишних слов в строке адреса документа - тому посвящена отдельная инструкция "ShortURLs" на сайте разработчиков "XWiki".

Первая ненужная составляющая URL "xwiki" легко убирается в случае, если "Tomcat" обслуживает только один "сервлет" и отсутствует необходимость выбора между web-приложениями. Достаточно установить xwiki-сервлет "as ROOT" и оставить пустым параметр "xwiki.webapppath" в "xwiki.cfg" - в собираемом разработчиками "XWiki" официальном docker-контейнере это уже сделано.

Вторая нежелательная составляющая URL "bin" удаляется сложнее всего. Это указатель на один из главных сервлетов обработки страницы ("Struts"), а кроме него есть ещё несколько вспомогательных, и нельзя просто перенаправить весь трафик в одно место "по умолчанию" - придётся вычленять из запросов те, что предназначены НЕ главному сервлету, отправлять их по назначению, и только все ОСТАЛЬНЫЕ отправлять главному сервлету ("Struts").

Третья невнятная составляющая URL "view" убирается проще всего - активацией параметра "xwiki.showviewaction=0" в "xwiki.cfg". При этом в дальнейшем указание "view" не вызовет ошибки - будет показана запрашиваемая страница - но в URL, генерируемом самой "XWiki" этой составляющей уже не будет.

Для применения изменений на любом этапе изменения режима отображения URL требуется перезапуск сервиса.

В итоге мы должны достигнуть следующего отображения адреса документа:

https://xwiki.example.net/level0/level1/level2/


Подготовка ansible-скрипта для создания модификации docker-образа "XWiki".

Как было отмечено выше, первый и третий этапы нормализации строки URL крайне просты, а вот в работе над вторым пришлось совершить столько взаимосвязанных настроек, что я счёл необходимым изложить их в виде скрипта, в процессе исполнения которого делается всё необходимое. Так проще обеспечить неизменность финальной конфигурации и снизить риск человеческой ошибки. На привычном "Bash" писать всё менее интересно, так что в этот раз применим для автоматизации "Ansible".

В самом простом изложении задача ansible-скрипта состоит в том, чтобы загрузить свежую версию docker-образа "XWiki", модифицировать содержимое docker-образа и создать на основе внесённых изменений новый docker-образ, который впоследствии будет применён для запуска web-сервиса.

Важно учитывать, что операции доработки контейнера важно делать или до первого запуска web-приложения в нём, или уже ПОСЛЕ успешной первичной настройки web-приложения, с заведением административного пользователя, как минимум. Если запустить контейнер, а потом сохранить его состояние - впоследствии неправильно написанный автоматический конфигуратор "XWiki" в "docker-entrypoint.sh" попросту не запустится.

Устанавливаем интерпретатор ansible-скриптов:

# apt-get install --no-install-recommends ansible

Создаём выделенную для автоматизации модификации "XWiki" директорию:

# mkdir -p /usr/local/etc/devops/images/xwiki
# cd /usr/local/etc/devops/images/xwiki

Загружаем исходный код проекта, в котором "XWiki" упаковывается в docker-образ - нам оттуда понадобятся конфигурационные файлы, преобразуемые в процессе:

# git clone https://github.com/xwiki-contrib/docker-xwiki.git ./docker-xwiki

Заготавливаем директорию для "самоподписанных" SSL-сертификатов, которые будут автоматически добавлены в список доверенных (необходимо для подключения к LDAP-серверам, как минимум):

# mkdir -p /usr/local/etc/ansible/xwiki-cacerts
# cp ./ss-rootCA.crt /usr/local/etc/ansible/xwiki-cacerts

Описываем правила обработки запросов библиотекой "UrlRewriteFilter":

# mkdir -p /usr/local/etc/ansible/xwiki-shorturls
# cd /usr/local/etc/ansible/xwiki-shorturls
# vi ./urlrewrite.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite decode-using="null">
  <rule>
    <note>
     Ensure that URLs ending with .gwtrpc are not modified.
     Note: Not needed with XWiki 9.7+ since the GWT editor has been removed.
    </note>
    <from>^/(.*)\.gwtrpc$</from>
    <to type="forward" last="true">-</to>
  </rule>
  <rule>
    <note>
      Ensure that URLs that must not be served by the Struts Servlet are not modified.
    </note>
    <from>^/((bin|resources|skins|asyncrenderer|rest|webdav|xmlrpc|wiki|webjars)/(.*)|robots\.txt)$</from>  
    <to type="forward" last="true">-</to>
  </rule>
  <rule>
    <note>
      For all other URLs we prepend the "/bin/" prefix so that they get routed to the XWiki Action Servlet.
    </note>
    <from>^/(.*)$</from>
    <to type="forward">/bin/$1</to>
  </rule>
  <outbound-rule>
    <note>
      Rewrite outbound URLs to remove the "/bin" part when there are two paths after it.
    </note>
    <from>/bin/(.*)/(.*)$</from>
    <to>/$1/$2</to>
  </outbound-rule>
  <outbound-rule>
    <note>
      Rewrite outbound URLs to remove the "/bin" part when there's a single path after it.
    </note>
    <from>/bin/(.*)$</from>
    <to>/$1</to>
  </outbound-rule>
  <outbound-rule>
    <note>
      Rewrite outbound URLs to remove the "/bin" part it's the last path.
    </note>
    <from>/bin$</from>
    <to>/</to>
  </outbound-rule>
</urlrewrite>

Пишем ansible-скрипт, посредством которого осуществляются все необходимые преобразования:

# cd /usr/local/etc/ansible
# vi ./01.xwiki-ldapssl-shorturls.yml

- name: Completion of the XWiki container configuration with the addition of support "self-signed" SSL (for LDAP authentication) and "urlrewrite" rules
  any_errors_fatal: true
  gather_facts: false
  hosts: 127.0.0.1
  connection: local
  tasks:

  - name: Preventive delete temporary container
    shell: docker rm tmp-xwiki-web || true

  #- name: Preventive delete target container
  #  shell: docker rm --name selfmade:lts-mysql-tomcat-ldapssl-shorturls || true

  - name: Pull original XWiki image
    shell: docker pull xwiki:lts-mysql-tomcat

  - name: Create temporary container
    shell: docker create --name tmp-xwiki-web xwiki:lts-mysql-tomcat

  - name: Clear file before fetch from temporary container
    file: path='./xwiki-shorturls/docker-entrypoint.sh' state=absent

  - name: Fetch file from temporary
    shell: docker cp tmp-xwiki-web:/usr/local/bin/docker-entrypoint.sh ./xwiki-shorturls/docker-entrypoint.sh

  - name: Adding certificate installation to the Java keystore in container
    lineinfile:
      path: ./xwiki-shorturls/docker-entrypoint.sh
      insertafter: "^function first_start()"
      line: "  for I in /etc/ssl/xwiki/* ; do /opt/java/openjdk/bin/keytool -import -noprompt -trustcacerts -alias \"Added CA certificat ${I}\" -file \"${I}\" -storetype JKS -keystore /opt/java/openjdk/lib/security/cacerts -keypass changeit -storepass changeit ; done"

  - name: Upload file into container
    shell: docker cp ./xwiki-shorturls/docker-entrypoint.sh tmp-xwiki-web:/usr/local/bin/docker-entrypoint.sh

  - name: Upload files of CA-certificates
    shell: docker cp ./xwiki-cacerts/ tmp-xwiki-web:/etc/ssl/xwiki

  - name: Clear file before fetch from temporary container
    file: path='./xwiki-shorturls/web.xml' state=absent

  - name: Fetch file from temporary
    shell: docker cp tmp-xwiki-web:/usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml ./xwiki-shorturls/web.xml

  - name: Download "urlrewrite" library distribution file
    get_url:
      url: https://repo1.maven.org/maven2/org/tuckey/urlrewritefilter/4.0.3/urlrewritefilter-4.0.3.jar
      dest: ./xwiki-shorturls/urlrewritefilter-4.0.3.jar

  - name: Add configuration "urlrewrite" in global
    lineinfile:
      path: ./xwiki-shorturls/web.xml
      insertafter: "<description>XWiki Application</description>"
      line: "\n  <!-- Custom filter inserted for support XWiki Short-URLs:\n       https://www.xwiki.org/xwiki/bin/view/Documentation/AdminGuide/ShortURLs/ -->\n  <filter>\n    <filter-name>UrlRewriteFilter</filter-name>\n    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>\n  </filter>\n  <filter-mapping>\n    <filter-name>UrlRewriteFilter</filter-name>\n    <url-pattern>/*</url-pattern>\n    <dispatcher>REQUEST</dispatcher>\n    <dispatcher>FORWARD</dispatcher>\n  </filter-mapping>"

  - name: Upload file into container
    shell: docker cp ./xwiki-shorturls/web.xml tmp-xwiki-web:/usr/local/tomcat/webapps/ROOT/WEB-INF/

  - name: Upload file into container
    shell: docker cp ./xwiki-shorturls/urlrewrite.xml tmp-xwiki-web:/usr/local/tomcat/webapps/ROOT/WEB-INF/

  - name: Upload file into container
    shell: docker cp ./xwiki-shorturls/urlrewritefilter-4.0.3.jar tmp-xwiki-web:/usr/local/tomcat/webapps/ROOT/WEB-INF/lib/

  - name: Create target image from temporary container
    shell: docker commit tmp-xwiki-web selfmade:lts-mysql-tomcat-ldapssl-shorturls

  - name: Delete temporary container
    shell: docker rm tmp-xwiki-web || true

  - name: Prune dangling images
    shell: docker image prune -f

Запускаем ansible-скрипт и читаем выводимые им сообщения:

# cd /usr/local/etc/ansible
# ansible-playbook ./01.xwiki-ldapssl-shorturls.yml --connection=local

Применение подготовленной docker-образа в конфигурации "Docker Compose".

Если описываемый выше ansible-скрипт отработал корректно, то приготовленный им docker-образ можно применить для запуска инстанса "XWiki":

# vi ./docker-compose.yml

version: "3"
services:
  xwiki:
    container_name: "xwiki-web"
    #image: "xwiki:lts-mysql-tomcat"
    image: "selfmade:lts-mysql-tomcat-ldapssl-shorturls"
    ....

Полностью останавливаем и запускаем (с пересозданием) docker-контейнер с "XWiki":

# systemctl stop xwiki-docker && systemctl start xwiki-docker


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )