GitLab para projeto de entrega contínua em tecnologias InterSystems: Containers

Este artigo é uma continuação de um artigo sobre a organização dos processos de Integração Contínua / Entrega Contínua que automatizam a montagem, teste e entrega de aplicativos aplicáveis ​​a soluções baseadas na plataforma InterSystems.


Considere tópicos como:


  • Contentores 101
  • Contêineres em diferentes estágios do ciclo de desenvolvimento de software
  • Entrega contínua com contêineres

Contentores 101


Muitos artigos e livros foram escritos sobre contêineres e contêineres; portanto, aqui farei uma pequena introdução, que, no entanto, não afirma ser final. Então, vamos começar.


Contêineres, tecnicamente, é um método de virtualização no qual o kernel do sistema operacional suporta várias instâncias isoladas do espaço do usuário (contêineres), em vez de um. Visualmente é assim:


Docker vs VM


É importante observar que os contêineres não são máquinas virtuais. Aqui está um bom artigo sobre suas diferenças.


Benefícios do contêiner


Existem vários benefícios no uso de contêineres:


  • Portabilidade
  • Eficácia
  • Isolamento
  • Leveza
  • Imutabilidade

Portabilidade


O contêiner contém o aplicativo junto com todas as dependências. Isso facilita a execução de aplicativos em vários ambientes, como servidores físicos, máquinas virtuais, ambientes de teste e ambientes de produtos e nuvens.


Além disso, a portabilidade consiste no fato de que, depois que a imagem do Docker for montada e funcionar corretamente, ela funcionará em qualquer lugar se o Docker funcionar lá, ou seja, nos servidores Windows, Linux e MacOS.


Eficácia


Ao trabalhar com aplicativos de máquinas virtuais, você realmente precisa de processos de SO, programas de sistema etc.? Como regra, não, apenas o processo do seu aplicativo é interessante. Os contêineres fornecem exatamente isso: apenas os processos claramente necessários são iniciados no contêiner e nada mais. Como os contêineres não exigem um sistema operacional separado, eles usam menos recursos. Uma máquina virtual costuma ocupar vários gigabytes, enquanto um contêiner pode ser tão pequeno quanto alguns megabytes, o que permite executar muito mais contêineres do que máquinas virtuais em um único servidor.


Como os contêineres têm um nível mais alto de utilização do servidor, menos hardware é necessário, resultando em custos mais baixos.


Isolamento


Os contêineres isolam o aplicativo de todos os outros processos e, embora vários contêineres possam ser executados no mesmo servidor, eles podem ser completamente independentes um do outro. Qualquer interação entre contêineres deve ser declarada explicitamente. Se um contêiner falhar, ele não afetará outros contêineres e poderá ser reiniciado rapidamente. A segurança também é aprimorada por esse isolamento. Por exemplo, explorar uma vulnerabilidade de servidor da web em um host pode dar ao invasor acesso a todo o servidor, mas no caso de um contêiner, um invasor terá acesso apenas ao contêiner do servidor da web.


Leveza


Como os contêineres não exigem um sistema operacional separado, eles podem ser iniciados, parados ou reiniciados em questão de segundos, o que acelerará todos os processos relacionados, incluindo os processos de Integração Contínua. Você pode começar a desenvolver mais rápido e não perder tempo configurando seu ambiente.


Imutabilidade


A infraestrutura imutável consiste em componentes imutáveis ​​que são substituídos para cada implantação e não são atualizados. A consistência reduz a inconsistência e permite replicar e mover com facilidade e rapidez entre os diferentes estados do seu aplicativo. Mais sobre imutabilidade .


Novos recursos


Todos esses benefícios permitem gerenciar sua infraestrutura e aplicativos de uma nova maneira.


Orquestração


Máquinas virtuais e servidores ao longo do tempo geralmente ganham "personalidade", o que leva a muitas surpresas geralmente desagradáveis ​​no futuro. Uma solução para esse problema é a infraestrutura como código (IoC) - gerenciamento de infraestrutura usando um modelo descritivo usando um sistema de controle de versão.


Ao usar a IoC, a equipe de implantação do ambiente sempre traz o ambiente de destino para a mesma configuração, independentemente do estado inicial do ambiente. Isso é possível configurando automaticamente um ambiente existente ou recriando o ambiente do zero.


Usando a IoC, os desenvolvedores fazem alterações na descrição do ambiente. Posteriormente, o ambiente de destino é modificado para um novo estado. Se você precisar fazer alterações na quarta-feira, sua descrição será editada.


Tudo isso é muito mais fácil de fazer com contêineres. Desligar o contêiner e iniciar um novo leva alguns segundos, e alocar uma nova máquina virtual leva alguns minutos.


Dimensionamento


As ferramentas de orquestração também podem fornecer escala horizontal com base na carga atual. É possível executar quantos contêineres forem necessários no momento e dimensionar o aplicativo de acordo. Tudo isso também reduz o custo do aplicativo.


Contêineres em diferentes estágios do ciclo de vida do software


Considere os benefícios dos contêineres em vários estágios do ciclo de vida do software.


Ciclo de vida do software


Desenvolvimento


A vantagem mais importante é a facilidade de iniciar o desenvolvimento. Após a instalação do Docker , basta executar dois comandos: docker pull para carregar a imagem e docker run para iniciá-lo. Todas as dependências já foram resolvidas no estágio de criação do aplicativo.


Depuração


Todos os ambientes são consistentes e suas definições existem; além disso, é fácil implantar o ambiente necessário. É o suficiente para fazer o docker pull o contêiner de interesse e executá-lo.


Teste / controle de qualidade


No caso de um erro, o ambiente do problema e as condições para reproduzir o erro podem ser transferidos com o contêiner. Todas as alterações na infraestrutura são "documentadas". O número de variáveis ​​está diminuindo - versões de bibliotecas, estruturas, SO ... É possível executar vários contêineres para paralelizar testes.


Entrega


O uso de contêineres permite criar uma vez, além de usar contêineres, você precisa de um alto nível de automação dos processos de montagem e implantação. A entrega do contêiner de um aplicativo pode ser mais segura devido ao isolamento adicional.


Entrega contínua


Vamos passar da teoria para a prática. Aqui está uma visão geral da nossa solução de automação de montagem e entrega:


CD


Podem ser distinguidos três estágios principais:


  • Assembléia
  • Entrega
  • Lançamento

Assembléia


No artigo anterior, a montagem foi incremental - consideramos a diferença entre o ambiente atual e a nova base de código e alteramos nosso ambiente para que correspondesse à nova base de código. Com contêineres, cada montagem está completa. O resultado da compilação é uma imagem do Docker que pode ser executada em qualquer lugar.


Entrega


Depois que nossa imagem é compilada e testada, ela é carregada no Docker Registry, um aplicativo especializado para hospedar a imagem do Docker. Lá, ele pode substituir a imagem anterior pelo mesmo nome (tag). Por exemplo, devido a uma nova confirmação na ramificação mestre, montamos uma nova imagem ( MyProject/MyApp:master ) e, se os testes forem aprovados, podemos atualizar a imagem no Docker Registry e todos que MyProject/MyApp:master download do MyProject/MyApp:master terão uma nova versão.


Lançamento


Finalmente, a imagem deve ser iniciada. Um sistema de CD, como o GitLab, pode gerenciar isso diretamente ou com a ajuda de um orquestrador especializado, mas o processo geralmente é o mesmo - algumas imagens são iniciadas, verificadas periodicamente quanto ao desempenho e atualizadas se uma nova versão se tornar disponível.


Confira o webinar explicando essas etapas.


Como alternativa, em termos de confirmação:



Em nossa configuração de entrega contínua, nós:


  • Confirmar código no repositório GitLab
  • Coletamos a imagem
  • Testando
  • Publique uma nova imagem em nosso Docker Registry
  • Atualize o contêiner antigo para a nova versão do Docker Registry

Para isso, precisamos:


  • Docker
  • Registro do Docker
  • Domínio registrado (opcional, mas desejável)
  • Ferramentas GUI (opcional)

Docker


Primeiro de tudo, precisamos iniciar o Docker. Eu recomendaria começar com um único servidor com uma versão comum do Linux, como Ubuntu, RHEL ou Suse. Não recomendo começar com distribuições como CoreOS, RancherOS etc. - elas não são direcionadas a iniciantes. Lembre-se de mudar o driver de armazenamento para devicemapper .


Se falamos de implantações em larga escala, usando ferramentas de orquestração como Kubernetes, Rancher ou Swarm, você pode automatizar a maioria das tarefas, mas não as discutiremos (pelo menos na estrutura deste artigo).


Registro do Docker


Este é o primeiro contêiner que precisamos executar, é um aplicativo independente que permite armazenar e distribuir imagens do Docker. Você precisa usar o Docker Registry se desejar:


  • Controle onde suas imagens são armazenadas
  • Possuir um servidor de distribuição de imagens
  • Integre o armazenamento e a distribuição de imagens no processo de desenvolvimento

Aqui está a documentação sobre como iniciar e configurar o Docker Registry.


Conecte o Docker Registry e o GitLab


Para conectar o Docker Registry ao GitLab, é necessário executar o Docker Registry com suporte HTTPS . Uso o Let's Encrypt para obter certificados e segui esta instrução para obter um certificado. Após verificar se o Docker Registry está acessível via HTTPS (você pode verificá-lo no navegador), siga estas instruções para conectar o Docker Registry ao GitLab. Essas instruções diferem dependendo da instalação do GitLab e da configuração necessária. No meu caso, a instalação foi adicionar o certificado e a chave do Docker Registry ao /etc/gitlab/ssl , e estas linhas ao /etc/gitlab/gitlab.rb :


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

Após reconfigurar o GitLab , uma nova guia Registro apareceu, fornecendo informações sobre como nomear corretamente as imagens criadas para que elas apareçam aqui.



Domínio


Em nossa configuração de entrega contínua, criaremos automaticamente uma imagem para cada filial e, se a imagem passar nos testes, ela será publicada no Docker Registry e será iniciada automaticamente, para que nosso aplicativo seja implantado automaticamente em todas as ramificações, por exemplo:


  • Vários ramos de <featureName>.docker.domain.com em <featureName>.docker.domain.com
  • Versão de teste em master.docker.domain.com
  • Versão de preprod.docker.domain.com em preprod.docker.domain.com
  • Versão do produto em prod.docker.domain.com

Para fazer isso, precisamos de um nome de domínio e um registro DNS curinga que redirecione as solicitações para * .docker.domain.com para o endereço IP de docker.domain.com . Como alternativa, você pode usar várias portas.


Nginx


Como temos vários ambientes, precisamos redirecionar automaticamente solicitações para subdomínios para o contêiner correto. Para isso, podemos usar o Nginx como um proxy reverso. Aqui está um guia .


Ferramentas GUI


Para começar a trabalhar com contêineres, você pode usar a linha de comandos ou uma das interfaces gráficas. Existem muitos disponíveis, por exemplo:


  • Rancheiro
  • Microbadger
  • Portainer
  • Interface simples do docker
  • ...

Eles permitem criar contêineres e gerenciá-los a partir da GUI em vez da CLI. Aqui está como Rancher se parece:


Rancheiro


Corredor do Gitlab


Como antes, para executar scripts em outros servidores, precisamos instalar o corredor GitLab. Esta pergunta é descrita em detalhes em um artigo anterior .


Observe que você precisa usar o executor Shell, não o Docker. O Executor Docker é usado quando você precisa de algo da imagem, por exemplo, ao criar um aplicativo Android em um contêiner java, e você só precisa de apk. No nosso caso, o artefato é o contêiner inteiro, e isso requer o executor Shell.


Configuração de entrega contínua


Agora que todos os componentes necessários estão configurados, você pode começar a criar uma configuração de entrega contínua.


Assembléia


Primeiro, precisamos montar uma imagem.


Nosso código, como sempre, é armazenado no repositório, a configuração do CD no gitlab-ci.yml , mas além disso (para melhorar a segurança), armazenaremos vários arquivos relacionados à imagem no servidor de compilação.


Gitlab.xml


Contém código de retorno de chamada para CD. Foi desenvolvido em um artigo anterior e está disponível no GitHub . Esta é uma pequena biblioteca para baixar código, executar vários retornos de chamada e código de teste. É preferível usar submodules git para incluir este projeto ou algo semelhante em seu repositório. Os submódulos são melhores porque é mais fácil mantê-los atualizados. Outra alternativa é criar uma versão no GitLab e baixá-la usando o comando ADD já em tempo de construção.


iris.key


Chave de licença. Ele pode ser carregado durante a montagem do contêiner e não armazenado no servidor. Não é seguro armazenar a chave no repositório. Você pode obter uma chave de avaliação no WRC ou experimentar o InterSystems IRIS Experience .


pwd.txt


Arquivo contendo a senha padrão. Novamente, armazenar a senha no repositório é bastante inseguro.


load_ci.script


Um script que:


  • Inclui autenticação de SO no InterSystems IRIS
  • Carrega GitLab.xml
  • Inicializa as configurações de retorno de chamada do GitLab
  • Carrega código

 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 

Observe que a primeira linha é intencionalmente deixada em branco. Se esse script inicial for sempre o mesmo, você poderá salvá-lo no repositório.


gitlab-ci.yml


Agora, vamos para a configuração de entrega contínua:


 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 . 

O que está acontecendo aqui?


Primeiro, como o processo de montagem da imagem pode acessar apenas subdiretórios do diretório base - no nosso caso, o diretório raiz do repositório, você precisa copiar o diretório "secret" (que possui GitLab.xml , iris.key , pwd.txt e load_ci.skript ) para repositório clonado.


Além disso, é necessário um usuário / senha para acessar o terminal, portanto os adicionaremos ao load_ci.script (para isso, precisamos de uma linha vazia no início do load_ci.script ).


Por fim, criamos uma imagem do Docker e a denominamos: docker.domain.com/test/docker:$CI_COMMIT_REF_NAME


onde $CI_COMMIT_REF_NAME é o nome da ramificação. Observe: a primeira parte da tag da imagem deve corresponder ao nome do repositório no GitLab para que possa ser vista na guia Registro (instruções mais completas para a marcação correta estão disponíveis lá).


Dockerfile


A imagem do Docker é criada usando o Dockerfile , aqui 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 

As seguintes ações são executadas:


  • Tomamos a imagem do InterSystems IRIS como base. Ele deve estar no seu Registro do Docker. Se você nunca trabalhou com o Docker antes, tente First Look: Docker , que descreve como obter uma imagem IRIS da InterSystems, adicione-a ao Registro do Docker e inicie-a manualmente.
  • Primeiro, copie nosso repositório (e o diretório "secreto") dentro do contêiner.
  • Copie a chave de licença e GitLab.xml para o diretório mgr .
  • Altere a senha para o valor de pwd.txt . Observe que o pwd.txt é excluído durante esta operação.
  • Inicia o InterSystems IRIS.
  • O load_ci.script é load_ci.script .
  • O InterSystems IRIS para.

Aqui está um log de construção 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 

Lançamento


Temos uma imagem, corra. No caso de ramificações de recursos, você pode simplesmente destruir o contêiner antigo e iniciar um novo. No caso do ambiente do produto, podemos iniciar o contêiner temporário primeiro e substituir o contêiner médio se os testes forem aprovados com êxito.


Primeiro, o script para excluir o contêiner antigo.


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

Esse script destrói o contêiner em execução e sempre é bem-sucedido (por padrão, o Docker retorna um erro ao tentar parar / excluir um contêiner inexistente).


Depois disso, lançamos um novo contêiner e o registramos como um ambiente.


 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 

O contêiner Nginx redireciona automaticamente as solicitações usando a VIRTUAL_HOST ambiente VIRTUAL_HOST para a porta especificada - nesse caso, 52773.


Como é necessário armazenar alguns dados (senhas,% SYS, dados do aplicativo) no host no InterSystems IRIS, existe a funcionalidade Durable% SYS que permite armazenar dados no host, como:


  • iris.cpf é o principal arquivo de configuração.
  • O /csp com arquivos de aplicativos da web.
  • /httpd/httpd.conf com configuração privada do servidor Apache.
  • O diretório /mgr no qual estão armazenados:
    • Bases de dados IRISSYS , IRISTEMP , IRISAUDIT , IRIS , USER .
    • IRIS.WIJ .
    • Diretório /journal armazena revistas.
    • O diretório /temp para arquivos temporários.
    • Registra messages.log , journal.log , SystemMonitor.log .

Para ativar o Durable% SYS, é especificado o argumento do volume que ISC_DATA_DIRECTORY diretório ISC_DATA_DIRECTORY host e a variável ISC_DATA_DIRECTORY define o diretório para armazenar os arquivos Durable% SYS. Este diretório não deve existir, será criado automaticamente.


Assim, a arquitetura do nosso aplicativo em contêiner é a seguinte:


arquitetura de aplicativo em contêiner


Para criar um aplicativo, precisamos pelo menos criar um banco de dados adicional (para salvar o código do aplicativo) e criar seu mapeamento na área de aplicativo. Usei o escopo USER para armazenar dados do aplicativo, pois esse escopo foi adicionado ao Durable% SYS por padrão. O código do aplicativo é armazenado em um contêiner para que possa ser atualizado.


Com base no exposto, % Installer deve:


  • Criar área de APP / banco de dados
  • Carregar código para a área APP
  • Crie classes de mapeamento de nosso aplicativo na área USER
  • Executar outra configuração (criei um aplicativo Web CSP e um aplicativo 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 criar um banco de dados que não esteja no host, uso o diretório /usr/irissys/mgr , pois a chamada ##class(%File).ManagerDirectory() retorna o caminho para o diretório do Durable% SYS.


Testes


Agora execute os testes.


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

Entrega


Após os testes, publicaremos nossa imagem no Docker Registry.


 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 

O login / senha pode ser passado usando variáveis ​​secretas .


Agora a imagem é exibida no GitLab.



E outros desenvolvedores podem fazer o download no Docker Registry. Na guia Ambientes, todos os nossos ambientes estão disponíveis para visualização:


Conclusões


Esta série de artigos discute abordagens comuns à integração contínua. Automatizar a montagem, teste e entrega do seu aplicativo nas plataformas da InterSystems é possível e fácil de implementar.


O uso de tecnologias de conteinerização ajudará a otimizar os processos de desenvolvimento e implantação de aplicativos. A eliminação de inconsistências entre ambientes facilita o teste e a depuração. A orquestração permite criar aplicativos escaláveis.


Referências


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


All Articles