GitLab para Proyecto de Entrega Continua en Tecnologías InterSystems: Contenedores

Este artículo es una continuación de un artículo sobre la organización de los procesos de Integración continua / Entrega continua que automatizan el ensamblaje, las pruebas y la entrega de aplicaciones aplicables a soluciones basadas en la plataforma InterSystems.


Considere temas como:


  • Contenedores 101
  • Contenedores en diferentes etapas del ciclo de desarrollo de software.
  • Entrega continua con contenedores

Contenedores 101


Se han escrito muchos artículos y libros sobre contenedores y contenedorización, por lo que aquí haré una pequeña introducción que, sin embargo, no pretende ser final. Entonces comencemos.


Los contenedores, técnicamente, son un método de virtualización en el que el núcleo del sistema operativo admite varias instancias aisladas de espacio de usuario (contenedores), en lugar de uno. Esto se ve visualmente así:


Docker vs VM


Es importante tener en cuenta que los contenedores no son máquinas virtuales, aquí hay un buen artículo sobre sus diferencias.


Beneficios de contenedores


Existen varios beneficios al usar contenedores:


  • Portabilidad
  • Efectividad
  • Aislamiento
  • Ligereza
  • Inmutabilidad

Portabilidad


El contenedor contiene la aplicación junto con todas las dependencias. Esto facilita la ejecución de aplicaciones en diversos entornos, como servidores físicos, máquinas virtuales, entornos de prueba y entornos de productos y nubes.


Además, la portabilidad consiste en el hecho de que después de que la imagen de Docker esté ensamblada y funcione correctamente, funcionará en cualquier lugar si Docker funciona allí, es decir. en servidores Windows, Linux y MacOS.


Efectividad


Al trabajar con aplicaciones de máquinas virtuales, ¿realmente necesita procesos del sistema operativo, programas del sistema, etc.? Como regla general, no, solo el proceso de su solicitud es interesante. Los contenedores proporcionan exactamente esto: solo aquellos procesos que son claramente necesarios se inician en el contenedor, y nada más. Debido a que los contenedores no requieren un sistema operativo separado, usan menos recursos. Una máquina virtual a menudo ocupa varios gigabytes, mientras que un contenedor puede ser tan pequeño como unos pocos megabytes, lo que le permite ejecutar muchos más contenedores que máquinas virtuales en un solo servidor.


Debido a que los contenedores tienen un mayor nivel de utilización del servidor, se requiere menos hardware, lo que resulta en menores costos.


Aislamiento


Los contenedores aíslan la aplicación de todos los demás procesos, y aunque varios contenedores pueden ejecutarse en el mismo servidor, pueden ser completamente independientes entre sí. Cualquier interacción entre contenedores debe declararse explícitamente. Si un contenedor falla, no afecta a otros contenedores y puede reiniciarse rápidamente. La seguridad también se ve reforzada por este aislamiento. Por ejemplo, explotar la vulnerabilidad de un servidor web en un host puede dar acceso a un atacante a todo el servidor, pero en el caso de un contenedor, un atacante solo obtendrá acceso al contenedor del servidor web.


Ligereza


Dado que los contenedores no requieren un sistema operativo separado, se pueden iniciar, detener o reiniciar en cuestión de segundos, lo que acelerará todos los procesos relacionados, incluidos los procesos de integración continua. Puede comenzar a desarrollar más rápido y no perder el tiempo configurando su entorno.


Inmutabilidad


La infraestructura inmutable consta de componentes inmutables que se reemplazan para cada implementación y no se actualizan. La coherencia reduce la inconsistencia y le permite replicar y moverse fácil y rápidamente entre diferentes estados de su aplicación. Más sobre inmutabilidad .


Nuevas características


Todos estos beneficios le permiten administrar su infraestructura y aplicaciones de una nueva manera.


Orquestación


Las máquinas y servidores virtuales con el tiempo a menudo adquieren "personalidad", lo que lleva a muchas sorpresas generalmente desagradables en el futuro. Una solución a este problema es Infraestructura como Código (IoC): administración de infraestructura que utiliza un modelo descriptivo que utiliza un sistema de control de versiones.


Cuando se usa IoC, el equipo de implementación del entorno siempre trae el entorno de destino a la misma configuración, independientemente del estado inicial del entorno. Esto se logra configurando automáticamente un entorno existente o volviendo a crear el entorno desde cero.


Con IoC, los desarrolladores realizan cambios en la descripción del entorno. Posteriormente, el entorno de destino se modifica a un nuevo estado. Si necesita hacer cambios el miércoles, se edita su descripción.


Todo esto es mucho más fácil de hacer con contenedores. Cerrar el contenedor e iniciar uno nuevo lleva unos segundos, y asignar una nueva máquina virtual lleva unos minutos.


Escalamiento


Las herramientas de orquestación también pueden proporcionar escala horizontal en función de la carga actual. Es posible ejecutar tantos contenedores como se requiera actualmente y escalar la aplicación en consecuencia. Todo esto también reduce el costo de la aplicación.


Contenedores en diferentes etapas del ciclo de vida del software.


Considere los beneficios de los contenedores en varias etapas del ciclo de vida del software.


Ciclo de vida del software


Desarrollo


La ventaja más importante es la facilidad de iniciar el desarrollo. Después de instalar Docker , es suficiente ejecutar dos comandos: docker pull para cargar la imagen y docker run para iniciarla. Todas las dependencias ya están resueltas en la etapa de compilación de la aplicación.


Depuración


Todos los entornos son consistentes y sus definiciones existen; además, es fácil implementar el entorno necesario. Es suficiente para que docker pull el contenedor de interés y lo ejecute.


Prueba / QA


En caso de error, el entorno del problema y las condiciones para reproducir el error se pueden transferir con el contenedor. Todos los cambios de infraestructura están "documentados". El número de variables está disminuyendo: versiones de bibliotecas, marcos, SO ... Es posible ejecutar varios contenedores para paralelizar las pruebas.


La entrega


El uso de contenedores le permite construir una vez, además de usar contenedores, necesita un alto nivel de automatización de los procesos de ensamblaje e implementación. La entrega en contenedor de una aplicación puede ser más segura debido al aislamiento adicional.


Entrega continua


Pasemos de la teoría a la práctica. Aquí hay una vista general de nuestra solución de automatización de ensamblaje y entrega:


CD


Se pueden distinguir tres etapas principales:


  • Asamblea
  • La entrega
  • Lanzamiento

Asamblea


En el artículo anterior, el ensamblaje fue incremental: consideramos la diferencia entre el entorno actual y la nueva base de código y cambiamos nuestro entorno para que correspondiera a la nueva base de código. Con contenedores, cada ensamblaje está completo. El resultado de la compilación es una imagen de Docker que se puede ejecutar en cualquier lugar.


La entrega


Después de que nuestra imagen se compila y se prueba, se carga en el Registro de Docker, una aplicación especializada para alojar la imagen de Docker. Allí puede reemplazar la imagen anterior con el mismo nombre (etiqueta). Por ejemplo, debido a un nuevo compromiso con la rama maestra, hemos reunido una nueva imagen ( MyProject/MyApp:master ), y si se pasan las pruebas, podemos actualizar la imagen en el Docker Registry y todos los que descarguen MyProject/MyApp:master obtendrán una nueva versión.


Lanzamiento


Finalmente, la imagen debe iniciarse. Un sistema de CD, como GitLab, puede administrar esto directamente o con la ayuda de un orquestador especializado, pero el proceso generalmente es el mismo: algunas imágenes se lanzan, se verifica periódicamente el rendimiento y se actualiza si hay una nueva versión disponible.


Consulte el seminario web que explica estos pasos.


Alternativamente, en términos de commit:



En nuestra configuración de entrega continua, nosotros:


  • Confirmar código en el repositorio de GitLab
  • Recogemos la imagen
  • Probándolo
  • Publique una nueva imagen en nuestro Registro Docker
  • Actualice el contenedor anterior a la nueva versión desde el Registro Docker

Para esto necesitamos:


  • Docker
  • Registro de Docker
  • Dominio registrado (opcional, pero deseable)
  • Herramientas GUI (opcional)

Docker


En primer lugar, necesitamos iniciar Docker. Recomendaría comenzar con un único servidor con una versión común de Linux, como Ubuntu, RHEL o Suse. No recomiendo comenzar con distribuciones como CoreOS, RancherOS, etc., no están dirigidas a principiantes. Recuerde cambiar el controlador de almacenamiento a devicemapper .


Si hablamos de implementaciones a gran escala, utilizando herramientas de orquestación como Kubernetes, Rancher o Swarm, puede automatizar la mayoría de las tareas, pero no las discutiremos (al menos en el marco de este artículo).


Registro de Docker


Este es el primer contenedor que necesitamos ejecutar, es una aplicación independiente que nos permite almacenar y distribuir imágenes de Docker. Debe usar el Registro Docker si desea:


  • Controla dónde se almacenan tus imágenes
  • Poseer un servidor de distribución de imágenes
  • Integre el almacenamiento y la distribución de imágenes en el proceso de desarrollo.

Aquí está la documentación sobre el inicio y la configuración de Docker Registry.


Connect Docker Registry y GitLab


Para conectar el Registro Docker a GitLab, debe ejecutar el Registro Docker con soporte HTTPS . Utilizo Let's Encrypt para obtener certificados, y seguí estas instrucciones para obtener un certificado. Después de verificar que se puede acceder al Registro de Docker a través de HTTPS (puede verificarlo en el navegador), siga estas instrucciones para conectar el Registro de Docker a GitLab. Estas instrucciones difieren según la instalación de GitLab y la configuración que necesita. En mi caso, la configuración fue agregar el certificado y la clave del Registro Docker a /etc/gitlab/ssl , y estas líneas a /etc/gitlab/gitlab.rb :


 registry_external_url 'https://docker.domain.com' gitlab_rails ['registry_api_url'] = "https://docker.domain.com" 

Después de reconfigurar GitLab , apareció una nueva pestaña de Registro, que proporciona información sobre cómo nombrar correctamente las imágenes creadas para que aparezcan aquí.



Dominio


En nuestra configuración de entrega continua, crearemos automáticamente una imagen para cada rama, y ​​si la imagen pasa las pruebas, se publica en el Registro de Docker y se inicia automáticamente, por lo que nuestra aplicación se implementará automáticamente desde todas las ramas, por ejemplo:


  • Varias ramas de <featureName>.docker.domain.com en <featureName>.docker.domain.com
  • Versión de prueba en master.docker.domain.com
  • Versión de preprod.docker.domain.com en preprod.docker.domain.com
  • Versión del producto en prod.docker.domain.com

Para hacer esto, necesitamos un nombre de dominio y un registro DNS comodín que redirija las solicitudes a * .docker.domain.com a la dirección IP de docker.domain.com . Alternativamente, puede usar varios puertos.


Nginx


Como tenemos varios entornos, necesitamos redirigir automáticamente las solicitudes a subdominios al contenedor correcto. Para esto, podemos usar Nginx como proxy inverso. Aquí hay una guía .


Herramientas GUI


Para comenzar a trabajar con contenedores, puede usar la línea de comandos o una de las interfaces gráficas. Hay muchos disponibles, por ejemplo:


  • Ranchero
  • Microbadger
  • Portainer
  • Docker simple ui
  • ...

Le permiten crear contenedores y administrarlos desde la GUI en lugar de la CLI. Así es como se ve Rancher:


Ranchero


Corredor de Gitlab


Como antes, para ejecutar scripts en otros servidores, necesitamos instalar el corredor GitLab. Esta pregunta se describe en detalle en un artículo anterior .


Tenga en cuenta que debe usar el Shell ejecutor, no el Docker. Executor Docker se usa cuando necesitas algo dentro de la imagen, por ejemplo, cuando creas una aplicación de Android en un contenedor java, y solo necesitas apk. En nuestro caso, el artefacto es el contenedor completo, y esto requiere el ejecutor Shell.


Configuración de entrega continua


Ahora que todos los componentes necesarios están configurados, puede comenzar a crear una configuración de entrega continua.


Asamblea


Primero, necesitamos armar una imagen.


Nuestro código, como siempre, se almacena en el repositorio, la configuración del CD en gitlab-ci.yml , pero además (para mejorar la seguridad) almacenaremos varios archivos relacionados con la imagen en el servidor de compilación.


Gitlab.xml


Contiene código de devolución de llamada para CD. Fue desarrollado en un artículo anterior y está disponible en GitHub . Esta es una pequeña biblioteca para descargar código, ejecutar varias devoluciones de llamada y código de prueba. Es preferible usar submódulos git para incluir este proyecto o algo similar en su repositorio. Los submódulos son mejores porque es más fácil mantenerlos actualizados. Otra alternativa es crear una versión en GitLab y descargarla usando el comando ADD ya en el momento de la compilación.


iris.key


Clave de licencia. Puede cargarse durante el ensamblaje del contenedor y no almacenarse en el servidor. No es seguro almacenar la clave en el repositorio. Puede obtener una clave de prueba en WRC o probar InterSystems IRIS Experience .


pwd.txt


Archivo que contiene la contraseña predeterminada. Nuevamente, almacenar la contraseña en el repositorio es bastante inseguro.


load_ci.script


Un guión que:



 set sc = ##Class(Security.System).Get("SYSTEM",.Properties) write:('sc) $System.Status.GetErrorText(sc) set AutheEnabled = Properties("AutheEnabled") set AutheEnabled = $ZBOOLEAN(+AutheEnabled,16,7) set Properties("AutheEnabled") = AutheEnabled set sc = ##Class(Security.System).Modify("SYSTEM",.Properties) write:('sc) $System.Status.GetErrorText(sc) zn "USER" do ##class(%SYSTEM.OBJ).Load(##class(%File).ManagerDirectory() _ "GitLab.xml","cdk") do ##class(isc.git.Settings).setSetting("hooks", "MyApp/Hooks/") do ##class(isc.git.Settings).setSetting("tests", "MyApp/Tests/") do ##class(isc.git.GitLab).load() halt 

Tenga en cuenta que la primera línea se deja en blanco intencionalmente. Si este script inicial es siempre el mismo, puede guardarlo en el repositorio.


gitlab-ci.yml


Ahora, pasemos a la configuración de entrega continua:


 build image: stage: build tags: - test script: - cp -r /InterSystems/mount ci - cd ci - echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt - mv temp.txt load_ci.script - cd .. - docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.domain.com/test/docker:$CI_COMMIT_REF_NAME . 

¿Qué está pasando aquí?


En primer lugar, dado que el proceso de ensamblaje de imágenes solo puede acceder a subdirectorios del directorio base; en nuestro caso, el directorio raíz del repositorio, debe copiar el directorio "secreto" (que tiene GitLab.xml , iris.key , pwd.txt y load_ci.skript ) a repositorio clonado.


Además, se requiere un usuario / contraseña para acceder al terminal, por lo que los agregaremos a load_ci.script (para esto necesitamos una línea vacía al comienzo de load_ci.script ).


Finalmente, creamos una imagen Docker y la docker.domain.com/test/docker:$CI_COMMIT_REF_NAME : docker.domain.com/test/docker:$CI_COMMIT_REF_NAME


donde $CI_COMMIT_REF_NAME es el nombre de la sucursal. Tenga en cuenta que la primera parte de la etiqueta de la imagen debe coincidir con el nombre del repositorio en GitLab para que se pueda ver en la pestaña Registro (hay instrucciones más completas para el etiquetado correcto disponibles allí).


Dockerfile


Docker Image se crea usando Dockerfile , aquí está:


 FROM docker.intersystems.com/intersystems/iris:2018.1.1.613.0 ENV SRC_DIR=/tmp/src ENV CI_DIR=$SRC_DIR/ci ENV CI_PROJECT_DIR=$SRC_DIR COPY ./ $SRC_DIR RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ \ && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ \ && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt \ && iris start $ISC_PACKAGE_INSTANCENAME \ && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script \ && iris stop $ISC_PACKAGE_INSTANCENAME quietly 

Se realizan las siguientes acciones:


  • Tomamos la imagen de InterSystems IRIS como base. Debería estar en su Registro Docker. Si no ha trabajado con Docker antes, pruebe First Look: Docker , que describe cómo obtener una imagen IRIS de InterSystems, agregarla al Registro de Docker e iniciarla manualmente.
  • En primer lugar, copie nuestro repositorio (y el directorio "secreto") dentro del contenedor.
  • Copie la clave de licencia y GitLab.xml en el directorio mgr .
  • Cambie la contraseña al valor de pwd.txt . Tenga en cuenta que pwd.txt se elimina durante esta operación.
  • Inicia InterSystems IRIS.
  • El load_ci.script se load_ci.script .
  • InterSystems IRIS se detiene.

Aquí hay un registro de compilación parcial
 Running with gitlab-runner 10.6.0 (a3543a27) on docker 7b21e0c4 Using Shell executor... Running on docker... Fetching changes... Removing ci/ Removing temp.txt HEAD is now at 5ef9904 Build load_ci.script From http://gitlab.eduard.win/test/docker 5ef9904..9753a8d master -> origin/master Checking out 9753a8db as master... Skipping Git submodules setup $ cp -r /InterSystems/mount ci $ cd ci $ echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt $ mv temp.txt load_ci.script $ cd .. $ docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME . Sending build context to Docker daemon 401.4kB Step 1/6 : FROM docker.intersystems.com/intersystems/iris:2018.1.1.613.0 ---> cd2e53e7f850 Step 2/6 : ENV SRC_DIR=/tmp/src ---> Using cache ---> 68ba1cb00aff Step 3/6 : ENV CI_DIR=$SRC_DIR/ci ---> Using cache ---> 6784c34a9ee6 Step 4/6 : ENV CI_PROJECT_DIR=$SRC_DIR ---> Using cache ---> 3757fa88a28a Step 5/6 : COPY ./ $SRC_DIR ---> 5515e13741b0 Step 6/6 : RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt && iris start $ISC_PACKAGE_INSTANCENAME && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script && iris stop $ISC_PACKAGE_INSTANCENAME quietly ---> Running in 86526183cf7c . Waited 1 seconds for InterSystems IRIS to start This copy of InterSystems IRIS has been licensed for use exclusively by: ISC Internal Container Sharding Copyright (c) 1986-2018 by InterSystems Corporation Any other use is a violation of your license agreement %SYS> 1 %SYS> Using 'iris.cpf' configuration file This copy of InterSystems IRIS has been licensed for use exclusively by: ISC Internal Container Sharding Copyright (c) 1986-2018 by InterSystems Corporation Any other use is a violation of your license agreement 1 alert(s) during startup. See messages.log for details. Starting IRIS Node: 39702b122ab6, Instance: IRIS Username: Password: Load started on 04/06/2018 17:38:21 Loading file /usr/irissys/mgr/GitLab.xml as xml Load finished successfully. USER> USER> [2018-04-06 17:38:22.017] Running init hooks: before [2018-04-06 17:38:22.017] Importing hooks dir /tmp/src/MyApp/Hooks/ [2018-04-06 17:38:22.374] Executing hook class: MyApp.Hooks.Global [2018-04-06 17:38:22.375] Executing hook class: MyApp.Hooks.Local [2018-04-06 17:38:22.375] Importing dir /tmp/src/ Loading file /tmp/src/MyApp/Tests/TestSuite.cls as udl Compilation started on 04/06/2018 17:38:22 with qualifiers 'c' Compilation finished successfully in 0.194s. Load finished successfully. [2018-04-06 17:38:22.876] Running init hooks: after [2018-04-06 17:38:22.878] Executing hook class: MyApp.Hooks.Local [2018-04-06 17:38:22.921] Executing hook class: MyApp.Hooks.Global Removing intermediate container 39702b122ab6 ---> dea6b2123165 [Warning] One or more build-args [CI_PROJECT_DIR] were not consumed Successfully built dea6b2123165 Successfully tagged docker.domain.com/test/docker:master Job succeeded 

Lanzamiento


Tenemos una imagen, ejecútala. En el caso de las ramas de características, simplemente puede destruir el contenedor antiguo y comenzar uno nuevo. En el caso del entorno del producto, podemos iniciar el contenedor temporal primero y reemplazar el contenedor del medio si las pruebas pasan con éxito.


Primero, la secuencia de comandos para eliminar el contenedor anterior.


 destroy old: stage: destroy tags: - test script: - docker stop iris-$CI_COMMIT_REF_NAME || true - docker rm -f iris-$CI_COMMIT_REF_NAME || true 

Este script destruye el contenedor en ejecución y siempre tiene éxito (de manera predeterminada, Docker devuelve un error al intentar detener / eliminar un contenedor inexistente).


Después de eso, lanzamos un nuevo contenedor y lo registramos como un entorno.


 run image: stage: run environment: name: $CI_COMMIT_REF_NAME url: http://$CI_COMMIT_REF_SLUG.docker.eduard.win/index.html tags: - test script: - docker run -d --expose 52773 --volume /InterSystems/durable/$CI_COMMIT_REF_SLUG:/data --env ISC_DATA_DIRECTORY=/data/sys --env VIRTUAL_HOST=$CI_COMMIT_REF_SLUG.docker.eduard.win --name iris-$CI_COMMIT_REF_NAME docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME --log $ISC_PACKAGE_INSTALLDIR/mgr/messages.log 

El contenedor Nginx redirige automáticamente las solicitudes utilizando la VIRTUAL_HOST entorno VIRTUAL_HOST al puerto especificado, en este caso, 52773.


Dado que es necesario almacenar algunos datos (contraseñas,% SYS, datos de la aplicación) en el host en InterSystems IRIS, existe una funcionalidad Durable% SYS que le permite almacenar datos en el host como:


  • iris.cpf es el archivo de configuración principal.
  • El /csp con archivos de aplicaciones web.
  • /httpd/httpd.conf con configuración privada del servidor Apache.
  • El directorio /mgr en el que están almacenados:
    • Bases de datos IRISSYS , IRISTEMP , IRISAUDIT , IRIS , USER .
    • IRIS.WIJ .
    • Directorio /journal almacenamiento de revistas.
    • El directorio /temp para archivos temporales.
    • Registra messages.log , journal.log , SystemMonitor.log .

Para habilitar Durable% SYS, se especifica el argumento de volume que ISC_DATA_DIRECTORY directorio ISC_DATA_DIRECTORY host y la variable ISC_DATA_DIRECTORY establece el directorio para almacenar archivos Durable% SYS. Este directorio no debería existir, se creará automáticamente.


Por lo tanto, la arquitectura de nuestra aplicación en contenedores es la siguiente:


arquitectura de aplicaciones en contenedores


Para construir una aplicación de este tipo, debemos crear al menos una base de datos adicional (para guardar el código de la aplicación) y crear su asignación en el área de la aplicación. Utilicé el alcance USER para almacenar datos de la aplicación, ya que este alcance se agregó a Durable% SYS de forma predeterminada. El código de la aplicación se almacena en un contenedor para que pueda actualizarse.


Según lo anterior, % Installer debería:


  • Crear área de aplicación / base de datos
  • Subir código al área de la aplicación
  • Cree clases de mapeo de nuestra aplicación en el área de USER
  • Realizar otra configuración (creé una aplicación web CSP y una aplicación web REST)

Código% instalador
 Class MyApp.Hooks.Local { Parameter Namespace = "APP"; /// See generated code in zsetup+1^MyApp.Hooks.Local.1 XData Install [ XMLNamespace = INSTALLER ] { <Manifest> <Log Text="Creating namespace ${Namespace}" Level="0"/> <Namespace Name="${Namespace}" Create="yes" Code="${Namespace}" Ensemble="" Data="IRISTEMP"> <Configuration> <Database Name="${Namespace}" Dir="/usr/irissys/mgr/${Namespace}" Create="yes" MountRequired="true" Resource="%DB_${Namespace}" PublicPermissions="RW" MountAtStartup="true"/> </Configuration> <Import File="${Dir}Form" Recurse="1" Flags="cdk" IgnoreErrors="1" /> </Namespace> <Log Text="End Creating namespace ${Namespace}" Level="0"/> <Log Text="Mapping to USER" Level="0"/> <Namespace Name="USER" Create="no" Code="USER" Data="USER" Ensemble="0"> <Configuration> <Log Text="Mapping Form package to USER namespace" Level="0"/> <ClassMapping From="${Namespace}" Package="Form"/> <RoutineMapping From="${Namespace}" Routines="Form" /> </Configuration> <CSPApplication Url="/" Directory="${Dir}client" AuthenticationMethods="64" IsNamespaceDefault="false" Grant="%ALL" Recurse="1" /> </Namespace> </Manifest> } /// This is a method generator whose code is generated by XGL. /// Main setup method /// set vars("Namespace")="TEMP3" /// do ##class(MyApp.Hooks.Global).setup(.vars) ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 0, pInstaller As %Installer.Installer) As %Status [ CodeMode = objectgenerator, Internal ] { Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "Install") } /// Entry point ClassMethod onAfter() As %Status { try { write "START INSTALLER",! set vars("Namespace") = ..#Namespace set vars("Dir") = ..getDir() set sc = ..setup(.vars) write !,$System.Status.GetErrorText(sc),! set sc = ..createWebApp() } catch ex { set sc = ex.AsStatus() write !,$System.Status.GetErrorText(sc),! } quit sc } /// Modify web app REST ClassMethod createWebApp(appName As %String = "/forms") As %Status { set:$e(appName)'="/" appName = "/" _ appName #dim sc As %Status = $$$OK new $namespace set $namespace = "%SYS" if '##class(Security.Applications).Exists(appName) { set props("AutheEnabled") = $$$AutheUnauthenticated set props("NameSpace") = "USER" set props("IsNameSpaceDefault") = $$$NO set props("DispatchClass") = "Form.REST.Main" set props("MatchRoles")=":" _ $$$AllRoleName set sc = ##class(Security.Applications).Create(appName, .props) } quit sc } ClassMethod getDir() [ CodeMode = expression ] { ##class(%File).NormalizeDirectory($system.Util.GetEnviron("CI_PROJECT_DIR")) } } 

Observo que para crear una base de datos que no está en el host, uso el directorio /usr/irissys/mgr , ya que la llamada ##class(%File).ManagerDirectory() devuelve la ruta al directorio para Durable% SYS.


Pruebas


Ahora ejecuta las pruebas.


 test image: stage: test tags: - test script: - docker exec iris-$CI_COMMIT_REF_NAME irissession iris -U USER "##class(isc.git.GitLab).test()" 

La entrega


Se pasan las pruebas, publicaremos nuestra imagen en el Registro Docker.


 publish image: stage: publish tags: - test script: - docker login docker.domain.com -u user -p pass - docker push docker.domain.com/test/docker:$CI_COMMIT_REF_NAME 

El inicio de sesión / contraseña se puede pasar usando variables secretas .


Ahora la imagen se muestra en GitLab.



Y otros desarrolladores pueden descargarlo del Registro Docker. En la pestaña Entornos, todos nuestros entornos están disponibles para ver:


Conclusiones


Esta serie de artículos discute enfoques comunes para la integración continua. La automatización del ensamblaje, las pruebas y la entrega de su aplicación en las plataformas InterSystems es posible y fácil de implementar.


El uso de tecnologías de contenedorización ayudará a optimizar el desarrollo de aplicaciones y los procesos de implementación. La eliminación de inconsistencias entre entornos facilita las pruebas y la depuración. La orquestación le permite crear aplicaciones escalables.


Referencias


Source: https://habr.com/ru/post/es420749/


All Articles