Escrito por

Sales Engineer at InterSystems
Artigo Danusa Calixto · Abr. 3, 2023 7m read

Entrega contínua de sua solução InterSystems usando GitLab – Parte IX: Arquitetura do contêiner

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como:

  • Git básico
  • Fluxo Git (processo de desenvolvimento)
  • Instalação do GitLab
  • Fluxo de trabalho do GitLab
  • Entrega contínua
  • Instalação e configuração do GitLab
  • CI/CD do GitLab
  • Por que contêineres?
  • Infraestrutura dos contêineres
  • CD usando contêineres
  • CD usando ICM
  • Arquitetura do contêiner

Neste artigo, falaríamos sobre como criar e implantar seu próprio contêiner.

%SYS durável

Como os contêineres são bastante efêmeros, eles não devem armazenar nenhum dado do aplicativo. O recurso %SYS Durável permite exatamente isso — armazenar configurações, definições, dados %SYS, etc. em um volume de host, especificamente:

  • O arquivo iris.cpf.
  • O diretório /csp, contendo a configuração do web gateway e os arquivos do log.
  • O arquivo /httpd/httpd.conf, o arquivo de configuração do servidor Web privado da instância.
  • O diretório /mgr, contendo o seguinte:
    • O banco de dados do sistema IRISSYS, composta pelos arquivos IRIS.DAT e iris.lck e diretório de stream, e iristemp, irisaudit, iris e os diretórios do usuário, com os bancos de dados do sistema IRISTEMP, IRISAUDIT, IRIS e USER.
    • O arquivo do registro de log de imagem de gravação, IRIS.WIJ.
    • O diretório /journal com os arquivos do registro de log.
    • O diretório /temp para arquivos temporários.
    • Arquivos de registro, incluindo messages.log, journal.log e SystemMonitor.log.

Arquitetura do contêiner

Por outro lado, precisamos armazenar o código do aplicativo dentro do nosso contêiner para atualizá-lo quando necessário.

Tudo isso nos leva a esta arquitetura:

Para fazer isso durante o tempo de compilação, precisamos, no mínimo, criar um banco de dados adicional (para armazenar o código do aplicativo) e mapeá-lo no namespace do aplicativo. No meu exemplo, eu usaria o namespace USER para manter os dados do aplicativo, como ele já existe e é durável.

Instalador

Com base no descrito acima, nosso instalador precisa:

  • Criar o namespace/banco de dados APP
  • Carregar o código no namespace APP
  • Mapear as classes do aplicativo para o namespace USER
  • Fazer todas as outras instalações (nesse caso, criei o web app CSP e o app REST)

Class MyApp.Hooks.Local
{

Parameter Namespace = "APP";

/// See generated code in zsetup+1^MyApp.Hooks.Local.1 XData Install [ XMLNamespace = INSTALLER ] { <Manifest>

</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")) }

}

Para criar o banco de dados não durável, usei um subdiretório de /usr/irissys/mgr, que não é persistente. Observe que a chamada para ##class(%File).ManagerDirectory() retorna um caminho para o diretório durável, e não para o diretório do contêiner interno.

 

Configuração da entrega contínua

Confira a parte VII para ver as informações completas, mas tudo o que você precisa fazer é adicionar estas duas linhas (em negrito) à configuração existente.

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 argumento do volume monta o diretório do host para o contêiner e a variável ISC_DATA_DIRECTORY mostra ao InterSystems IRIS qual diretório usar. Para citar a documentação:

  • Ao executar um contêiner InterSystems IRIS usando essas opções, ocorre o seguinte:
  • O volume externo especificado é montado.
  • Se o diretório %SYS durável especificado pela variável de ambiente ISC_DATA_DIRECTORY, iconfig/ no exemplo anterior, já existe e contém os dados %SYS duráveis, todos os ponteiros internos da instância são redefinidos para esse diretório e a instância usa os dados que contém.
  • Se o diretório %SYS durável especificado na variável de ambiente ISC_DATA_DIRECTORY já existir, mas não conter os dados %SYS duráveis, nenhum dado é copiado e a instância é executada usando os dados na árvore de instalação dentro do contêiner, ou seja, os dados específicos da instância não são persistentes. Por esse motivo, é recomendável incluir nos scripts uma verificação para essa condição antes de executar o contêiner.
  • Se o diretório %SYS durável especificado por ISC_DATA_DIRECTORY não existir:
  • É criado o diretório %SYS durável.
  • Os diretórios e arquivos listados no conteúdo do Diretório %SYS Durável são copiados dos locais instalados para o diretório %SYS durável (os originais permanecem no local).
  • Todos os ponteiros internos da instância são redefinidos para o diretório %SYS durável e a instância usa os dados que contém.

 

Atualizações

Quando o aplicativo evoluir e uma nova versão (contêiner) for lançada, às vezes é necessário executar algum código. Pode ser antes ou depois dos hooks de compilação, das migrações do esquema e dos testes de unidade, mas é necessário executar código arbitrário. Por isso, você precisa de um framework que gerencie seu aplicativo. Em artigos anteriores, descrevi a estrutura básica desse framework, mas, é claro, ele pode ser consideravelmente ampliado para atender a requisitos específicos do aplicativo.

Conclusão

A criação de um aplicativo em contêiner requer algumas considerações, mas o InterSystems IRIS oferece vários recursos para facilitar esse processo.