#Open Exchange

0 Seguidores · 139 Postagens

As soluções para a Plataforma de Dados InterSystems, o Open Exchange, é uma galeria de soluções de software, ferramentas, e frameworks que foram desenvolvidos com a Plataforma de Dados InterSystems (Caché, Ensemble, HealthShare, InterSystems IRIS, InterSystems IRIS for Health) ou destinam-se a ajudar no desenvolvimento, implantação e suporte as soluções construídas com a Plataforma de Dados InterSystems.

Você pode usar qualquer um dos recursos ou pode publicar sua própria ferramenta, exemplo de tecnologia ou solução.

Descubra o Open Exchange.

Anúncio Angelo Bruno Braga · jan 4, 2021

Olá Comunidade,

Estamos felizes em convidá-los para o encontro online com os ganhadores do Concurso Analítico da InterSystems!

Dia e Horário: Segunda-Feira, 4 de Janeiro de 2021 – 12:00 horário de Brasília

O que lhe aguarda neste Encontro virtual? 

  • A biografia de nossos ganhadores.
  • Pequenas demonstrações de suas aplicações.
  • Uma discussão aberta sobre as tecnologias utilizadas, os bônus, espaço para esclarecimento de dúvidas e planos para os próximos concursos.

0
0 73
Anúncio Angelo Bruno Braga · Dez. 30, 2020

Olá Desenvolvedores,

Concurso Analítico InterSystems terminou. Obrigado a todos vocês que participaram de mais esta edição da nossa maratona de codificação !

E agora é hora de anunciarmos os ganhadores ! 

Nossos aplausos e congratulações vão para os seguintes desenvolvedores e suas aplicações:

🏆 Nominação de Experts  - os ganhadores são determinados por um juri especialmente selecionado:

🥇 1° lugar e US$2,000 vai para o projeto iris-analytics-notebook de @José Pereira

🥈 2° lugar e US$1,000 vai para o projeto website-analyzer de @Yuri Marx

0
0 96
Anúncio Angelo Bruno Braga · Dez. 21, 2020

Olá Desenvolvedores,

Esta semana é a semana de votação para o  Concurso Analítico InterSystems! Então, é a hora de você dar seu voto para as melhores soluções construídas utilizando a plataforma de dados InterSystems IRIS.

🔥 Você decide: VOTE AQUI 🔥

0
0 78
Artigo Lily Taub · Dez. 21, 2020 9m read

Introdução

A maior parte da comunicação servidor-cliente na web é baseada em uma estrutura de solicitação e resposta. O cliente envia uma solicitação ao servidor e o servidor responde a esta solicitação. O protocolo WebSocket fornece um canal bidirecional de comunicação entre um servidor e um cliente, permitindo que os servidores enviem mensagens aos clientes sem primeiro receber uma solicitação. Para obter mais informações sobre o protocolo WebSocket e sua implementação no InterSystems IRIS, consulte os links abaixo.

Este tutorial é uma atualização de "Asynchronous Websockets - um tutorial rápido" para Caché 2016.2+ e InterSystems IRIS 2018.1+.

Operação assíncrona vs síncrona

No InterSystems IRIS, uma conexão WebSocket pode ser implementada de forma síncrona ou assíncrona. O modo como a conexão WebSocket entre o cliente e o servidor opera é determinado pela propriedade “SharedConnection” da classe %CSP.WebSocket.

  • SharedConnection=1 : operação assíncrona

  • SharedConnection=0: operação síncrona

Uma conexão WebSocket entre um cliente e um servidor hospedado em uma instância do InterSystems IRIS inclui uma conexão entre a instância IRIS e o Web Gateway. Na operação síncrona de WebSocket, a conexão usa um canal privado. Na operação assíncrona de WebSocket, um grupo de clientes WebSocket compartilha um conjunto de conexões entre a instância IRIS e o Web Gateway. A vantagem de uma implementação assíncrona de WebSockets se destaca quando se tem muitos clientes se conectando ao mesmo servidor, pois esta implementação não exige que cada cliente seja tratado por uma conexão exclusiva entre o Web Gateway e a instância IRIS.

Neste tutorial, implementaremos WebSockets de forma assíncrona. Portanto, todas as janelas de bate-papo abertas compartilham um conjunto de conexões entre o Web Gateway e a instância IRIS que hospeda a classe do servidor WebSocket.

Visão geral da aplicação de chat

O “hello world” do WebSockets é uma aplicação de chat em que um usuário pode enviar mensagens que são transmitidas a todos os usuários logados na aplicação. Neste tutorial, os componentes da aplicação de chat incluem:

  • Servidor: implementado em uma classe que estende %CSP.WebSocket

  • Cliente: implementado por uma página CSP

A implementação desta aplicação de chat irá realizar o seguinte:

  • Os usuários podem transmitir mensagens para todas as janelas do chat abertas

  • Os usuários on-line aparecerão na lista “Usuários on-line” de todas as janelas de chat abertas

  • Os usuários podem alterar seu nome de usuário compondo uma mensagem começando com a palavra-chave “alias” e esta mensagem não será transmitida, mas atualizará a lista de “Usuários On-line”

  • Quando os usuários fecham a janela de chat, eles são removidos da lista de “Usuários on-line”

Para ver o código fonte da aplicação de chat, visite este repositório no GitHub.

O Cliente

O lado do cliente da nossa aplicação de chat é implementado por uma página CSP contendo o estilo para a janela do chat, a declaração da conexão WebSocket, eventos do WebSocket e métodos que tratam da comunicação de e para o servidor, e funções auxiliares que empacotam mensagens enviadas para o servidor e processam as mensagens de entrada.

Primeiro, veremos como a aplicação inicia a conexão WebSocket usando uma biblioteca Javascript WebSocket.

    ws = new WebSocket(((window.location.protocol === "https:")? "wss:":"ws:")
                    + "//"+ window.location.host + "/csp/user/Chat.Server.cls");

new cria uma nova instância da classe WebSocket. Isso abre uma conexão WebSocket com o servidor usando o protocolo "wss" (indica o uso de TLS para o canal de comunicação WebSocket) ou "ws". O servidor é especificado pelo número da porta do servidor web e nome do host da instância que define a classe Chat.Server (essas informações estão contidas na variável window.location.host). O nome de nossa classe no servidor (Chat.Server.cls) está incluído no URI de abertura do WebSocket como uma solicitação GET para o recurso no servidor.

O evento ws.onopen é disparado quando a conexão WebSocket é estabelecida com êxito, fazendo a transição de um estado de conectando para um estado aberto.

    ws.onopen = function(event){
        document.getElementById("headline").innerHTML = "CHAT - CONNECTED";
    };

Este evento atualiza o cabeçalho da janela do chat para indicar que o cliente e o servidor estão conectados.

Enviando mensagens

A ação de um usuário enviando uma mensagem aciona a função de envio. Essa função atua como um invólucro em torno do método ws.send, que contém a mecânica de envio da mensagem do cliente ao servidor pela conexão WebSocket.

function send() {
    var line=$("#inputline").val();
    if (line.substr(0,5)=="alias"){
        alias=line.split(" ")[1];
        if (alias==""){
            alias="default";
        }
        var data = {}
        data.User = alias
        ws.send(JSON.stringify(data));
        } else {
        var msg=btoa(line);
        var data={};
        data.Message=msg;
        data.Author=alias;
        if (ws && msg!="") {
            ws.send(JSON.stringify(data));
        }
    }
    $("#inputline").val("");
}

send envia pacotes as informações a serem enviadas ao servidor em um objeto JSON, definindo pares de chave/valor de acordo com o tipo de informação que está sendo enviada (atualização de alias ou mensagem geral). btoa traduz o conteúdo de uma mensagem geral em uma string ASCII codificada em base 64.

Recebendo mensagens

Quando o cliente recebe uma mensagem do servidor, o evento ws.onmessage é acionado.

ws.onmessage = function(event) {
    var d=JSON.parse(event.data);
    if (d.Type=="Chat") {
        $("#chat").append(wrapmessage(d));
            $("#chatdiv").animate({ scrollTop: $('#chatdiv').prop("scrollHeight")}, 1000);
    } else if(d.Type=="userlist") {
        var ul = document.getElementById("userlist");
        while(ul.firstChild){ul.removeChild(ul.firstChild)};
        $("#userlist").append(wrapuser(d.Users));
    } else if(d.Type=="Status"){
        document.getElementById("headline").innerHTML = "CHAT - connected - "+d.WSID;
    }
};

Dependendo do tipo de mensagem que o cliente recebe (“Chat”, “userlist” ou “status”), o evento onmessage chama wrapmessage ou wrapuser para popular as seções apropriadas da janela de chat com os dados de entrada. Se a mensagem recebida for uma atualização de status, o cabeçalho de status da janela do chat é atualizado com o ID do WebSocket, que identifica a conexão WebSocket bidirecional associada à janela do chat.

Componentes adicionais do cliente

Um erro na comunicação entre o cliente e o servidor aciona o método WebSocket onerror, que emite um alerta que nos notifica do erro e atualiza o cabeçalho de status da página.

ws.onerror = function(event) {
    document.GetElementById("headline").innerHTML = "CHAT - error";
    alert("Received error"); 
};

O método onclose é disparado quando a conexão WebSocket entre o cliente e o servidor é fechada, e atualiza o cabeçalho de status.

ws.onclose = function(event) {
    ws = null;
    document.getElementById("headline").innerHTML = "CHAT - disconnected";
}

O servidor

O lado do servidor da aplicação de chat é implementado pela classe Chat.Server, que estende de %CSP.WebSocket. Nossa classe de servidor herda várias propriedades e métodos de %CSP.WebSocket, alguns dos quais discutirei abaixo. Chat.Server também implementa métodos personalizados para processar mensagens de entrada e transmitir mensagens para o(s) cliente(s).

Antes de iniciar o servidor

OnPreServer() é executado antes de o servidor WebSocket ser criado e é herdado da classe %CSP.WebSocket.

Method OnPreServer() As %Status
{
    set ..SharedConnection=1
    if (..WebSocketID '= ""){ 
        set ^Chat.WebSocketConnections(..WebSocketID)=""
    } else {
        set ^Chat.Errors($INCREMENT(^Chat.Errors),"no websocketid defined")=$HOROLOG 
    }
    Quit $$$OK
}

Este método define o parâmetro da classe SharedConnection em 1, indicando que nossa conexão WebSocket será assíncrona e suportada por vários processos que definem conexões entre a instância InterSystems IRIS e o Web Gateway. O parâmetro SharedConnection só pode ser alterado em OnPreServer(). O OnPreServer() também armazena o ID WebSocket associado ao cliente no ^Chat.WebSocketConnections global.

O método do servidor

O corpo principal da lógica executada pelo servidor está contido no método Server().

Method Server() As %Status
{
    do ..StatusUpdate(..WebSocketID)
    for {       
        set data=..Read(.size,.sc,1) 
        if ($$$ISERR(sc)){
            if ($$$GETERRORCODE(sc)=$$$CSPWebSocketTimeout) {
                //$$$DEBUG("no data")
            }
            if ($$$GETERRORCODE(sc)=$$$CSPWebSocketClosed){
                kill ^Chat.WebSocketConnections(..WebSocketID)
                do ..RemoveUser($g(^Chat.Users(..WebSocketID))) 
                kill ^Chat.Users(..WebSocketID)
                quit  // Client closed WebSocket
            }
        } else{
            if data["User"{
                do ..AddUser(data,..WebSocketID)
            } else {
                set mid=$INCREMENT(^Chat.Messages)
                set ^Chat.Messages(mid)=data
                do ..ProcessMessage(mid)
            }
        }
    }
    Quit $$$OK
}

Este método lê as mensagens recebidas do cliente (usando o método Read da classe %CSP.WebSockets), adiciona os objetos JSON recebidos ao ^Chat.Messages global e chama o ProcessMessage() para encaminhar a mensagem a todos os outros clientes de chat conectados. Quando um usuário fecha sua janela de chat (encerrando assim a conexão WebSocket com o servidor), a chamada do método Server() para Read retorna um código de erro que avalia a macro $$$CSPWebSocketClosed e o método prossegue para tratar o encerramento de acordo.

Processamento e distribuição de mensagens

ProcessMessage() adiciona metadados à mensagem de chat recebida e chama o SendData(), passando a mensagem como um parâmetro.

ClassMethod ProcessMessage(mid As %String)
{
    set msg = ##class(%DynamicObject).%FromJSON($GET(^Chat.Messages(mid)))
    set msg.Type="Chat"
    set msg.Sent=$ZDATETIME($HOROLOG,3)
    do ..SendData(msg)
}

ProcessMessage() recupera a mensagem formatada em JSON do ^Chat.Messages global e a converte em um objeto do InterSystems IRIS usando a classe %DynamicObject e o método '%FromJSON. Isso nos permite editar facilmente os dados antes de encaminharmos a mensagem para todos os clientes de chat conectados. Adicionamos um atributo Type com o valor “Chat”, que o cliente usa para determinar como lidar com a mensagem recebida. SendData() envia a mensagem para todos os outros clientes de chat conectados.

ClassMethod SendData(data As %DynamicObject)
{
    set c = ""
    for {
        set c = $order(^Chat.WebSocketConnections(c))
        if c="" Quit
        set ws = ..%New()
        set sc = ws.OpenServer(c)
        if $$$ISERR(sc) { do ..HandleError(c,"open") } 
        set sc = ws.Write(data.%ToJSON())
        if $$$ISERR(sc) { do ..HandleError(c,"write") }
    }
}

SendData() converte o objeto do InterSystems IRIS de volta em uma string JSON (data.%ToJSON()) e envia a mensagem para todos os clientes de chat. SendData() obtém o ID WebSocket associado a cada conexão cliente-servidor do ^Chat.WebSocketConnections global e usa o ID para abrir uma conexão WebSocket por meio do método OpenServer da classe %CSP.WebSocket. Podemos usar o método OpenServer para fazer isso porque nossas conexões WebSocket são assíncronas - extraímos do pool existente de processos do IRIS-Web Gateway e atribuímos um ID WebSocket que identifica a conexão do servidor a um cliente de chat específico. Por fim, o método Write()%CSP.WebSocket envia a representação da string JSON da mensagem para o cliente.

Conclusão

Esta aplicação de chat demonstra como estabelecer conexões WebSocket entre um cliente e um servidor hospedado pelo InterSystems IRIS. Para continuar lendo sobre o protocolo e sua implementação no InterSystems IRIS, dê uma olhada nos links na introdução.

0
0 1264
Anúncio Angelo Bruno Braga · Dez. 7, 2020

Olá Comunidade!

Estamos gratos em convidar todos os desenvolvedores para o Webinar Inicial do Concurso Analítico da InterSystems! O tópico deste webinar será dedicado ao Concurso Analítico.

Neste webinar, nós iremos demonstrar o modelo-iris-analítico e responder as perguntas de como desenvolver, empacotar e publicar aplicações analíticas usando o InterSystems IRIS.

Dia & Horário: Segunda-feira, 7 de Dezembro — 14:00 Horário de Brasília

Palestrantes:  
🗣 @Carmen Logue, InterSystems Product Manager - Analytics and AI
🗣 @Evgeny Shvarov, InterSystems Developer Ecosystem Manager


<--break->

0
0 102
Artigo Evgeny Shvarov · Nov. 30, 2020 2m read

Olá, desenvolvedores!

Suponha que você publicou sua aplicação no Open Exchange com a versão 1.00. E, então, você adicionou um novo recurso excelente e faz um novo lançamento.

Você também pode fazer um novo lançamento da sua aplicação no Open Exchange.

Por que fazer lançamentos no Open Exchange? 

Esta é uma maneira de você destacar os novos recursos da sua aplicação. Quando você publica um novo lançamento, acontece o seguinte:

As notas de lançamento aparecem na página de Notícias do Open Exchange

A versão de sua aplicação muda

A aba de Histórico de Versão é atualizada

Todos os seus seguidores, sua aplicação ou sua empresa recebem uma notificação por e-mail.

O resumo semana e mensal do Open Exchange no OEX e no Developer Community incluirá uma nota sobre o seu lançamento.

Como fazer um novo lançamento

Abra a página da aplicação publicada e clique em Configurações-> Editar:

Faça alterações na descrição ou tag, se a nova versão trouxer essas alterações, e clique em Salvar. Salve-a mesmo que você não tenha nenhuma alteração nas propriedades da aplicação.

Em seguida, clique em 'Enviar  para aprovação para atualizar a versão e enviar as Notas de Lançamento:

Você verá a janela com o número da versão e notas de lançamento. 

Nós aumentamos automaticamente a versão secundária no número da versão atual, mas depende de você qual versão lançar ou até mesmo não alterar o número da versão. As notas de lançamento suportam Markdown, então prepare o texto markdown em qualquer editor compatível (ex., VSCode) e copie-o e cole-o aqui. Em seguida, clique no botão Enviar:

O markdown que enviei aqui:

## Atualização de imagem docker InterSystems IRIS 

Nesta versão eu atualizei uma imagem [InterSystems Docker](https://hub.docker.com/publishers/intersystems) com a nova versão 2019.4

Assim que a versão for aprovada, as notas de lançamento serão enviadas a todos os seus assinantes e publicadas na página de Notícias:

Envie seus comentários abaixo se você tiver alguma dúvida e também envie sugestões e relatórios de bug aqui.

Faça novos lançamentos de suas aplicações InterSystems no Open Exchange e fique atento!

0
0 69
Anúncio Angelo Bruno Braga · Nov. 23, 2020

Olá Desenvolvedores,

Concurso de Interoperabilidade da InterSystems chegou ao seu fim. Obrigado a todos pela participação em nossa empolgante maratona de codificação !

E agora é o momento de anunciarmos os vencedores ! 

 

Nossos aplausos e congratulações vão para os seguintes desenvolvedores e suas aplicações:

2
0 124
Anúncio Angelo Bruno Braga · Nov. 23, 2020

Olá Comunidade,

É um prazer convidá-los para o  encontro online com os ganhadores do Concurso de Interoperabilidade da InterSystems!

Dia e horário: Sexta-feira, 27 de Novembro de 2020 – 12:00 horário de Brasília

O que lhe aguarda neste encontro virtual ?

  • A biografia de nossos ganhadores.
  • Demonstrações de suas aplicações.
  • Uma discussão aberta sobre as tecnologias utilizadas, bônus, dúvidas e planos para os próximos concursos.

0
0 88
Artigo Mikhail Khomenko · Nov. 23, 2020 21m read

Imagine que você queira ver o que a tecnologia InterSystems pode oferecer em termos de análise de dados. Você estudou a teoria e agora quer um pouco de prática. Felizmente, a InterSystems oferece um projeto que contém alguns bons exemplos: Samples BI. Comece com o arquivo README, pulando qualquer coisa associada ao Docker, e vá direto para a instalação passo a passo. Inicie uma instância virtual, instale o IRIS lá, siga as instruções para instalar o Samples BI e, a seguir, impressione o chefe com belos gráficos e tabelas. Por enquanto, tudo bem. 

Inevitavelmente, porém, você precisará fazer alterações.

Acontece que manter uma máquina virtual sozinha tem algumas desvantagens e é melhor mantê-la com um provedor em nuvem. A Amazon parece sólida e você cria uma conta no AWS (gratuita para iniciar), lê que usar a identidade do usuário root para tarefas diárias é ruim e cria um usuário IAM normal com permissões de administrador.

Clicando um pouco, você cria sua própria rede VPC, sub-redes e uma instância virtual EC2, e também adiciona um grupo de segurança para abrir a porta web IRIS (52773) e a porta ssh (22) para você. Repete a instalação do IRIS e Samples BI. Desta vez, usa o script Bash ou Python, se preferir. Mais uma vez, impressiona o chefe.

Mas o movimento DevOps onipresente leva você a começar a ler sobre infraestrutura como código e você deseja implementá-la. Você escolhe o Terraform, já que ele é bem conhecido de todos e sua abordagem é bastante universal - adequada com pequenos ajustes para vários provedores em nuvem. Você descreve a infraestrutura em linguagem HCL e traduz as etapas de instalação do IRIS e Samples BI para o Ansible. Em seguida, você cria mais um usuário IAM para permitir que o Terraform funcione. Executa tudo. Ganha um bônus no trabalho.

Gradualmente, você chega à conclusão de que, em nossa era de microsserviços, é uma pena não usar o Docker, especialmente porque a InterSystems lhe diz como. Você retorna ao guia de instalação do Samples BI e lê as linhas sobre o Docker, que não parecem complicadas:

$ docker pull intersystemsdc/iris-community:2019.4.0.383.0-zpm
$ docker run --name irisce -d --publish 52773:52773 intersystemsdc/iris-community:2019.4.0.383.0-zpm
$ docker exec -it irisce iris session iris
USER>zpm
zpm: USER>install samples-bi

Depois de direcionar seu navegador para ttp://localhost:52773/csp/user/_DeepSee.UserPortal.Home.zen?$NAMESPACE=USER, você vai novamente ao chefe e tira um dia de folga por um bom trabalho.

Você então começa a entender que “docker run” é apenas o começo e você precisa usar pelo menos docker-compose. Não é um problema:

$ cat docker-compose.yml
version: "3.7"
services:
  irisce:
    container_name: irisce
    image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
    ports:
    - 52773:52773
$ docker rm -f irisce # We don’t need the previous container
$ docker-compose up -d

Então, você instala o Docker e o docker-compose com o Ansible e, em seguida, apenas executa o contêiner, que fará o download de uma imagem se ainda não estiver presente na máquina. Em seguida, você instala Samples BI.

Você certamente gosta do Docker, porque é uma interface simples e legal para várias coisas do kernel. Você começa a usar o Docker em outro lugar e geralmente inicia mais de um contêiner. E descobre que muitas vezes os contêineres devem se comunicar entre si, o que leva à leitura sobre como gerenciar vários contêineres. 

E você chega ao Kubernetes

Uma opção para mudar rapidamente de docker-compose para Kubernetes é usar o kompose. Pessoalmente, prefiro simplesmente copiar os manifestos do Kubernetes dos manuais e, em seguida, editá-los, mas o kompose faz um bom trabalho ao concluir sua pequena tarefa:

$ kompose convert -f docker-compose.yml
INFO Kubernetes file "irisce-service.yaml" created
INFO Kubernetes file "irisce-deployment.yaml" created

Agora você tem os arquivos de implantação e serviço que podem ser enviados para algum cluster do Kubernetes. Você descobre que pode instalar um minikube, que permite executar um cluster Kubernetes de nó único e é exatamente o que você precisa neste estágio. Depois de um ou dois dias brincando com a sandbox do minikube, você está pronto para usar uma implantação real e ao vivo do Kubernetes em algum lugar da nuvem AWS.

Preparação

Então, vamos fazer isso juntos. Neste ponto, faremos algumas suposições:

Primeiro, presumimos que você tenha uma conta no AWS, saiba seu ID e não use credenciais de root. Você criou um usuário IAM (vamos chamá-lo de “my-user”) com direitos de administrador e apenas acesso programático e armazenou suas credenciais. Você também criou outro usuário IAM, chamado “terraform”, com as mesmas permissões:

Em seu nome, o Terraform irá para sua conta no AWS e criará e excluirá os recursos necessários. Os amplos direitos de ambos os usuários são explicados pelo fato de que se trata de uma demonstração. Você salva as credenciais localmente para os dois usuários IAM:

$ cat ~/.aws/credentials
[terraform]
aws_access_key_id = ABCDEFGHIJKLMNOPQRST
aws_secret_access_key = ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890123
[my-user]
aws_access_key_id = TSRQPONMLKJIHGFEDCBA
aws_secret_access_key = TSRQPONMLKJIHGFEDCBA01234567890123

Observação: não copie e cole as credenciais acima. Eles são fornecidos aqui como um exemplo e não existem mais. Edite o arquivo ~/.aws/credentials e introduza seus próprios registros.

Em segundo lugar, usaremos o ID do conta AWS fictícia (01234567890) para o artigo e a região AWS “eu-west-1.” Sinta-se à vontade para usar outra região.

Terceiro, presumimos que você esteja ciente de que o AWS não é gratuito e que você terá que pagar pelos recursos usados.

Em seguida, você instalou o utilitário AWS CLI para comunicação via linha de comando com o AWS. Você pode tentar usar o aws2, mas precisará definir especificamente o uso do aws2 em seu arquivo de configuração do kube, conforme descrito aqui.

Você também instalou o utilitário kubectl para comunicação via linha de comando com AWS Kubernetes.

E você instalou o utilitário kompose para docker-compose.yml para converter manifestos do Kubernetes.

Finalmente, você criou um repositório GitHub vazio e clonou-o em seu host. Vamos nos referir ao seu diretório raiz como . Neste repositório, vamos criar e preencher três diretórios: .github/workflows/, k8s/, e terraform/.

Observe que todo o código relevante é duplicado no repositório github-eks-samples-bi para simplificar a cópia e a colagem.

Vamos continuar.

Provisionamento AWS EKS

Já conhecemos o EKS no artigo Implementando uma aplicação web simples baseado em IRIS usando o Amazon EKS. Naquela época, criamos um cluster semiautomático. Ou seja, descrevemos o cluster em um arquivo e, em seguida, iniciamos manualmente o utilitário eksctl de uma máquina local, que criou o cluster de acordo com nossa descrição. 

O eksctl foi desenvolvido para a criação de clusters EKS e é bom para uma implementação de prova de conceito, mas para o uso diário é melhor usar algo mais universal, como o Terraform. Um ótimo recurso, Introdução ao AWS EKS, explica a configuração do Terraform necessária para criar um cluster EKS. Uma ou duas horas gastas para conhecê-lo não será uma perda de tempo.

Você pode brincar com o Terraform localmente. Para fazer isso, você precisará de um binário (usaremos a versão mais recente para Linux no momento da redação do artigo, 0.12.20) e o usuário IAM “terraform” com direitos suficientes para o Terraform ir para o AWS. Crie o diretório /terraform/ para armazenar o código do Terraform:

$ mkdir /terraform
$ cd /terraform

Você pode criar um ou mais arquivos .tf (eles são mesclados na inicialização). Basta copiar e colar os exemplos de código da Introdução ao AWS EKS e, em seguida, executar algo como:

$ export AWS_PROFILE=terraform
$ export AWS_REGION=eu-west-1
$ terraform init
$ terraform plan -out eks.plan

Você pode encontrar alguns erros. Nesse caso, brinque um pouco com o modo de depuração, mas lembre-se de desligá-lo mais tarde:

$ export TF_LOG=debug
$ terraform plan -out eks.plan

$ unset TF_LOG

Esta experiência será útil, e muito provavelmente você terá um cluster EKS iniciado (use “terraform apply” para isso). Verifique no console do AWS:

Limpe-o quando você ficar entediado:

$ terraform destroy

Em seguida, vá para o próximo nível e comece a usar o módulo Terraform EKS, especialmente porque ele é baseado na mesma introdução ao EKS. No diretório examples/ você verá como usá-lo. Você também  encontrará outros exemplos lá.

Simplificamos um pouco os exemplos. Este é o arquivo principal em que os módulos de criação de VPC e de criação de EKS são chamados:

$ cat /terraform/main.tf
terraform {
  required_version = ">= 0.12.0"
  backend "s3" {
    bucket         = "eks-github-actions-terraform"
    key            = "terraform-dev.tfstate"
    region         = "eu-west-1"
    dynamodb_table = "eks-github-actions-terraform-lock"
  }
}

provider "kubernetes" {
  host                   = data.aws_eks_cluster.cluster.endpoint
  cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
  token                  = data.aws_eks_cluster_auth.cluster.token
  load_config_file       = false
  version                = "1.10.0"
}

locals {
  vpc_name             = "dev-vpc"
  vpc_cidr             = "10.42.0.0/16"
  private_subnets      = ["10.42.1.0/24", "10.42.2.0/24"]
  public_subnets       = ["10.42.11.0/24", "10.42.12.0/24"]
  cluster_name         = "dev-cluster"
  cluster_version      = "1.14"
  worker_group_name    = "worker-group-1"
  instance_type        = "t2.medium"
  asg_desired_capacity = 1
}

data "aws_eks_cluster" "cluster" {
  name = module.eks.cluster_id
}

data "aws_eks_cluster_auth" "cluster" {
  name = module.eks.cluster_id
}

data "aws_availability_zones" "available" {
}

module "vpc" {
  source               = "git::https://github.com/terraform-aws-modules/terraform-aws-vpc?ref=master"

  name                 = local.vpc_name
  cidr                 = local.vpc_cidr
  azs                  = data.aws_availability_zones.available.names
  private_subnets      = local.private_subnets
  public_subnets       = local.public_subnets
  enable_nat_gateway   = true
  single_nat_gateway   = true
  enable_dns_hostnames = true

  tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
  }

  public_subnet_tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/elb" = "1"
  }

  private_subnet_tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/internal-elb" = "1"
  }
}

module "eks" {
  source = "git::https://github.com/terraform-aws-modules/terraform-aws-eks?ref=master"
  cluster_name     = local.cluster_name
  cluster_version  = local.cluster_version
  vpc_id           = module.vpc.vpc_id
  subnets          = module.vpc.private_subnets
  write_kubeconfig = false

  worker_groups = [
    {
      name                 = local.worker_group_name
      instance_type        = local.instance_type
      asg_desired_capacity = local.asg_desired_capacity
    }
  ]

  map_accounts = var.map_accounts
  map_roles    = var.map_roles
  map_users    = var.map_users
}

Vejamos um pouco mais de perto o bloco "terraform" em main.tf:

terraform {
  required_version = ">= 0.12.0"
  backend "s3" {
    bucket         = "eks-github-actions-terraform"
    key            = "terraform-dev.tfstate"
    region         = "eu-west-1"
    dynamodb_table = "eks-github-actions-terraform-lock"
  }
}

Aqui, indicamos que seguiremos a sintaxe não inferior ao Terraform 0.12 (muito mudou em comparação com as versões anteriores) e também que Terraform não deve armazenar seu estado localmente, mas sim remotamente, no S3 bucket. 

É conveniente se o código do terraform possa ser atualizado de lugares diferentes por pessoas diferentes, o que significa que precisamos ser capazes de bloquear o estado de um usuário, então adicionamos um bloqueio usando uma tabela dynamodb. Leia mais sobre bloqueios na página State Locking (bloqueio de estado).

Como o nome do bucket deve ser único em toda o AWS, o nome “eks-github-actions-terraform” não funcionará para você. Pense por conta própria e certifique-se de que ele ainda não foi usado (se sim, você receberá um erro NoSuchBucket):

$ aws s3 ls s3://my-bucket
An error occurred (AllAccessDisabled) when calling the ListObjectsV2 operation: All access to this object has been disabled
$ aws s3 ls s3://my-bucket-with-name-that-impossible-to-remember
An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation: The specified bucket does not exist

Tendo criado um nome, crie o bucket (usamos o usuário IAM “terraform” aqui. Ele tem direitos de administrador para que possa criar um bucket) e habilite o controle de versão para ele (o que lhe salvará em caso de um erro de configuração):

$ aws s3 mb s3://eks-github-actions-terraform --region eu-west-1
make_bucket: eks-github-actions-terraform
$ aws s3api put-bucket-versioning --bucket eks-github-actions-terraform --versioning-configuration Status=Enabled
$ aws s3api get-bucket-versioning --bucket eks-github-actions-terraform
{
  "Status": "Enabled"
}

Com o DynamoDB, ser único não é necessário, mas você precisa criar uma tabela primeiro:

$ aws dynamodb create-table                                                                                     \
  --region eu-west-1                                                                                                           \
  --table-name eks-github-actions-terraform-lock                                              \
  --attribute-definitions AttributeName=LockID,AttributeType=S                \
  --key-schema AttributeName=LockID,KeyType=HASH                                   \
  --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

Lembre-se de que, em caso de falha do Terraform, você pode precisar remover um bloqueio manualmente do console AWS. Mas tenha cuidado ao fazer isso.

Com relação aos blocos do módulo eks/vpc em main.tf, a forma de referenciar o módulo disponível no GitHub é simples:

git::https://github.com/terraform-aws-modules/terraform-aws-vpc?ref=master

Agora vamos dar uma olhada em nossos outros dois arquivos Terraform (variables.tf e outputs.tf). O primeiro contém nossas variáveis Terraform:

$ cat /terraform/variables.tf
variable "region" {
  default = "eu-west-1"
}

variable "map_accounts" {
  description = "Additional AWS account numbers to add to the aws-auth configmap. See examples/basic/variables.tf for example format."
  type        = list(string)
  default     = []
}

variable "map_roles" {
  description = "Additional IAM roles to add to the aws-auth configmap."
  type = list(object({
    rolearn  = string
    username = string
    groups   = list(string)
  }))
  default = []
}

variable "map_users" {
  description = "Additional IAM users to add to the aws-auth configmap."
  type = list(object({
    userarn  = string
    username = string
    groups   = list(string)
  }))
  default = [
    {
      userarn  = "arn:aws:iam::01234567890:user/my-user"
      username = "my-user"
      groups   = ["system:masters"]
    }
  ]
}

A parte mais importante aqui é adicionar o usuário IAM “my-user” à variável map_users, mas você deve usar seu próprio ID de conta aqui no lugar de 01234567890.

O que isto faz? Quando você se comunica com o EKS por meio do cliente kubectl local, ele envia solicitações ao servidor da API Kubernetes, e cada solicitação passa por processos de autenticação e autorização para que o Kubernetes possa entender quem enviou a solicitação e o que elas podem fazer. Portanto, a versão EKS do Kubernetes pede ajuda ao AWS IAM com a autenticação do usuário. Se o usuário que enviou a solicitação estiver listado no AWS IAM (apontamos seu ARN aqui), a solicitação vai para a fase de autorização, que o EKS processa sozinho, mas de acordo com nossas configurações. Aqui, indicamos que o usuário IAM “my-user” é muito legal (grupo “system: masters”).

Por fim, o arquivo outputs.tf descreve o que o Terraform deve imprimir após concluir um job:

$ cat /terraform/outputs.tf
output "cluster_endpoint" {
  description = "Endpoint for EKS control plane."
  value       = module.eks.cluster_endpoint
}

output "cluster_security_group_id" {
  description = "Security group ids attached to the cluster control plane."
  value       = module.eks.cluster_security_group_id
}

output "config_map_aws_auth" {
  description = "A kubernetes configuration to authenticate to this EKS cluster."
  value       = module.eks.config_map_aws_auth
}

Isso completa a descrição da parte do Terraform. Voltaremos em breve para ver como vamos iniciar esses arquivos.

Manifestos Kubernetes

Até agora, cuidamos de onde iniciar a aplicação. Agora vamos ver o que executar. 

Lembre-se de que temos o docker-compose.yml (renomeamos o serviço e adicionamos alguns rótulos que o kompose usará em breve) no diretório /k8s/:

$ cat /k8s/docker-compose.yml
version: "3.7"
services:
  samples-bi:
    container_name: samples-bi
    image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
    ports:
    - 52773:52773
    labels:
      kompose.service.type: loadbalancer
      kompose.image-pull-policy: IfNotPresent

Execute o kompose e adicione o que está destacado abaixo. Exclua as anotações (para tornar as coisas mais inteligíveis):

$ kompose convert -f docker-compose.yml --replicas=1
$ cat /k8s/samples-bi-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    io.kompose.service: samples-bi
  name: samples-bi
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        io.kompose.service: samples-bi
    spec:
      containers:
      - image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
        imagePullPolicy: IfNotPresent
        name: samples-bi
        ports:
        - containerPort: 52773
        resources: {}
        lifecycle:
          postStart:
            exec:
              command:
              - /bin/bash
              - -c
              - |
                echo -e "write\nhalt" > test
                until iris session iris < test; do sleep 1; done
                echo -e "zpm\ninstall samples-bi\nquit\nhalt" > samples_bi_install
                iris session iris < samples_bi_install
                rm test samples_bi_install

        restartPolicy: Always

Usamos a estratégia de atualização de Recriar, o que significa que o pod será excluído primeiro e depois recriado. Isso é permitido para fins de demonstração e nos permite usar menos recursos.
Também adicionamos o postStart hook, que será disparado imediatamente após o início do pod. Esperamos até o IRIS iniciar e instalar o pacote samples-bi do repositório zpm padrão.
Agora adicionamos o serviço Kubernetes (também sem anotações):

$ cat /k8s/samples-bi-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    io.kompose.service: samples-bi
  name: samples-bi
spec:
  ports:
  - name: "52773"
    port: 52773
    targetPort: 52773
  selector:
    io.kompose.service: samples-bi
  type: LoadBalancer

Sim, vamos implantar no namespace "padrão", que funcionará para a demonstração.

Ok, agora sabemos onde e o que queremos executar. Resta ver como.

O fluxo de trabalho do GitHub Actions

Em vez de fazer tudo do zero, criaremos um fluxo de trabalho semelhante ao descrito em Implantando uma solução InterSystems IRIS no GKE usando GitHub Actions. Desta vez, não precisamos nos preocupar em construir um contêiner. As partes específicas do GKE são substituídas pelas específicas do EKS. As partes em negrito estão relacionadas ao recebimento da mensagem de commit e ao uso dela em etapas condicionais:

$ cat /.github/workflows/workflow.yaml
name: Provision EKS cluster and deploy Samples BI there
on:
  push:
    branches:
    - master

# Environment variables.
# ${{ secrets }} are taken from GitHub -> Settings -> Secrets
# ${{ github.sha }} is the commit hash
env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  AWS_REGION: ${{ secrets.AWS_REGION }}
  CLUSTER_NAME: dev-cluster
  DEPLOYMENT_NAME: samples-bi

jobs:
  eks-provisioner:
    # Inspired by:
    ## https://www.terraform.io/docs/github-actions/getting-started.html
    ## https://github.com/hashicorp/terraform-github-actions
    name: Provision EKS cluster
    runs-on: ubuntu-18.04
    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Get commit message
      run: |
        echo ::set-env name=commit_msg::$(git log --format=%B -n 1 ${{ github.event.after }})

    - name: Show commit message
      run: echo $commit_msg

    - name: Terraform init
      uses: hashicorp/terraform-github-actions@master
      with:
        tf_actions_version: 0.12.20
        tf_actions_subcommand: 'init'
        tf_actions_working_dir: 'terraform'

    - name: Terraform validate
      uses: hashicorp/terraform-github-actions@master
      with:
        tf_actions_version: 0.12.20
        tf_actions_subcommand: 'validate'
        tf_actions_working_dir: 'terraform'

    - name: Terraform plan
      if: "!contains(env.commit_msg, '[destroy eks]')"
      uses: hashicorp/terraform-github-actions@master
      with:
        tf_actions_version: 0.12.20
        tf_actions_subcommand: 'plan'
        tf_actions_working_dir: 'terraform'

    - name: Terraform plan for destroy
      if: "contains(env.commit_msg, '[destroy eks]')"
      uses: hashicorp/terraform-github-actions@master
      with:
        tf_actions_version: 0.12.20
        tf_actions_subcommand: 'plan'
        args: '-destroy -out=./destroy-plan'
        tf_actions_working_dir: 'terraform'

    - name: Terraform apply
      if: "!contains(env.commit_msg, '[destroy eks]')"
      uses: hashicorp/terraform-github-actions@master
      with:
        tf_actions_version: 0.12.20
        tf_actions_subcommand: 'apply'
        tf_actions_working_dir: 'terraform'

    - name: Terraform apply for destroy
      if: "contains(env.commit_msg, '[destroy eks]')"
      uses: hashicorp/terraform-github-actions@master
      with:
        tf_actions_version: 0.12.20
        tf_actions_subcommand: 'apply'
        args: './destroy-plan'
        tf_actions_working_dir: 'terraform'

  kubernetes-deploy:
    name: Deploy Kubernetes manifests to EKS
    needs:
    - eks-provisioner
    runs-on: ubuntu-18.04
    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Get commit message
      run: |
        echo ::set-env name=commit_msg::$(git log --format=%B -n 1 ${{ github.event.after }})

    - name: Show commit message
      run: echo $commit_msg

    - name: Configure AWS Credentials
      if: "!contains(env.commit_msg, '[destroy eks]')"
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ secrets.AWS_REGION }}

    - name: Apply Kubernetes manifests
      if: "!contains(env.commit_msg, '[destroy eks]')"
      working-directory: ./k8s/
      run: |
        aws eks update-kubeconfig --name ${CLUSTER_NAME}
        kubectl apply -f samples-bi-service.yaml
        kubectl apply -f samples-bi-deployment.yaml
        kubectl rollout status deployment/${DEPLOYMENT_NAME}

É claro que, precisamos definir as credenciais do usuário "terraform" (retirá-las do arquivo ~/.aws/credentials), permitindo que o GitHub use seus segredos:

Observe as partes destacadas do fluxo de trabalho. Elas nos permitirão destruir um cluster EKS empurrando uma mensagem de commit que contém a frase “[destroy eks]”. Observe que não executaremos "kubernetes apply" com essa mensagem de commit.
Execute um pipeline, mas primeiro crie um arquivo .gitignore:

$ cat /.gitignore
.DS_Store
terraform/.terraform/
terraform/*.plan
terraform/*.json

$ cd
$ git add .github/ k8s/ terraform/ .gitignore
$ git commit -m "GitHub on EKS"
$ git push

Monitore o processo de implantação na aba "Actions" da página do repositório GitHub. Aguarde a conclusão com sucesso.

Quando você executa um fluxo de trabalho pela primeira vez, leva cerca de 15 minutos na etapa “Terraform apply”, aproximadamente o mesmo tempo necessário para criar o cluster. Na próxima inicialização (se você não excluiu o cluster), o fluxo de trabalho será muito mais rápido. Você pode verificar isso:

$ cd
$ git commit -m "Trigger" --allow-empty
$ git push

É claro que seria bom verificar o que fizemos. Desta vez, você pode usar as credenciais do IAM “my-user” em seu computador:

$ export AWS_PROFILE=my-user
$ export AWS_REGION=eu-west-1
$ aws sts get-caller-identity
$ aws eks update-kubeconfig --region=eu-west-1 --name=dev-cluster --alias=dev-cluster
$ kubectl config current-context
dev-cluster

$ kubectl get nodes
NAME                                                                               STATUS   ROLES      AGE          VERSION
ip-10-42-1-125.eu-west-1.compute.internal   Ready          6m20s     v1.14.8-eks-b8860f

$ kubectl get po
NAME                                                       READY        STATUS      RESTARTS   AGE
samples-bi-756dddffdb-zd9nw    1/1               Running    0                      6m16s

$ kubectl get svc
NAME                   TYPE                        CLUSTER-IP        EXTERNAL-IP                                                                                                                                                         PORT(S)                    AGE
kubernetes        ClusterIP               172.20.0.1                                                                                                                                                                                443/TCP                    11m
samples-bi         LoadBalancer     172.20.33.235    a2c6f6733557511eab3c302618b2fae2-622862917.eu-west-1.elb.amazonaws.com    52773:31047/TCP  6m33s

Vá para _http://a2c6f6733557511eab3c302618b2fae2-622862917.eu-west-1.elb.amazonaws.com:52773/csp/user/_DeepSee.UserPortal.Home.zen?$NAMESPACE=USER _(substitua o link pelo seu IP externo), então, digite “_system”, “SYS” e altere a senha padrão. Você deve ver vários painéis de Inteligência Empresarial (BI):

Clique na seta de cada um para um mergulho mais profundo:

Lembre-se, se você reiniciar um pod samples-bi, todas as suas alterações serão perdidas. Este é um comportamento intencional, pois esta é uma demonstração. Se você precisar de persistência, criei um exemplo no repositório github-gke-zpm-registry/k8s/statefulset.tpl.

Quando terminar, basta remover tudo que você criou:

$ git commit -m "Mr Proper [destroy eks]" --allow-empty
$ git push

Conclusão

Neste artigo, substituímos o utilitário eksctl pelo Terraform para criar um cluster EKS. É um passo à frente para “codificar” toda a sua infraestrutura AWS.
Mostramos como você pode facilmente implantar uma aplicação de demonstração com git push usando GitHub Actions e Terraform.
Também adicionamos o kompose e um postStart hook de um pod à nossa caixa de ferramentas.
Não mostramos a ativação do TLS neste momento. Essa é uma tarefa que realizaremos em um futuro próximo.

0
0 301
Anúncio Angelo Bruno Braga · Nov. 16, 2020

Olá Desenvolvedores,

Esta semana é a semana de votação para o Concurso de Interoperabilidade InterSystems Interoperability! Então, é a hora de você dar o seu voto para a melhor solução de interoperabilidade desenvolvida com a plataforma de dados IRIS.

🔥 Você decide: VOTE AQUI 🔥

 

Como votar? É fácil: você tem direito a um voto, e seu voto vai ou para a Nominação pelos Experts ou para a Nominação pela Comundade.

0
0 80
Anúncio Jose-Tomas Salvador · Nov. 3, 2020

Desta vez, quero falar sobre algo não específico do InterSystems IRIS, mas que acho importante se você deseja trabalhar com Docker e seu servidor no trabalho é um PC ou laptop com Windows 10 Pro ou Enterprise.

Como você provavelmente sabe, a tecnologia de contêineres vem basicamente do mundo Linux e, hoje em dia, está em hosts Linux onde apresenta potencial máximo. Quem usa o Windows normalmente vê que tanto a Microsoft quanto o Docker têm feito esforços importantes nos últimos anos que nos permitem rodar contêineres baseados em imagens Linux em nosso sistema Windows de uma maneira muito fácil... mas é algo que não é suportado para sistemas em produção e, este é o grande problema, não é confiável se quisermos manter os dados persistentes fora dos contêineres, no sistema host... principalmente devido às grandes diferenças entre os sistemas de arquivos Windows e Linux. No final, o próprio _Docker para Windows usa uma pequena máquina virtual Linux (MobiLinux) para executar os contêineres... ele faz isso de forma transparente para o usuário do Windows... e funciona perfeitamente bem se, como eu disse, você não exigir que seus bancos de dados sobrevivam mais do que o contêiner...

Bem... vamos direto ao ponto... o ponto é que muitas vezes, para evitar problemas e simplificar, precisamos de um sistema Linux completo e, se nosso servidor for baseado em Windows, a única maneira de fazê-lo é por meio de uma máquina virtual. Pelo menos até o WSL2 no Windows ser lançado, mas isso será uma outra história e com certeza levará um pouco de tempo para se tornar robusto o suficiente.

Neste artigo, vou lhe dizer, passo a passo, como instalar um ambiente onde você poderá trabalhar, se precisar, com contêineres Docker em um sistema Ubuntu em seu servidor Windows. Vamos lá...

1. Habilite o Hyper-V

Se você ainda não o habilitou, vá em adicionar Recursos do Windows e habilite o Hyper-V. Você precisará reiniciar (os textos da imagem estão em espanhol pois esse é o meu espaço de trabalho atual. Espero que junto com as instruções ajudem a "descriptografá-la" se você não conhece a língua de Dom Quixote 😉) 

2. Crie uma máquina virtual Ubuntu no Hyper-V

Não acho que haja uma maneira mais fácil de criar uma máquina virtual (VM). Basta abrir a janela do Gerenciador Hyper-V,  ir para a opção  Criação Rápida...(logo acima na tela) e criar sua máquina virtual usando qualquer uma das versões do Ubuntu já oferecidas (você pode baixar um arquivo _ISO _de qualquer outro Linux e assim criar a VM com uma distro diferente). No meu caso, escolhi a última versão disponível do Ubuntu: 19.10. Enfim, tudo que você verá aqui é válido para o dia 18/04. Em 15 ou 20 minutos, dependendo do que a imagem leva para baixar, você terá sua nova VM criada e pronta.

Importante:Deixe a opção de Switch padrão como é oferecida. Isso garantirá que você tenha acesso à Internet tanto no host quanto na máquina virtual.

3. Crie uma sub-rede local

Um dos problemas no uso de máquinas virtuais que encontrei com frequência tem a ver com configuração de rede... às vezes funciona, outras não, ou funciona se eu estiver conectado com Wi-Fi, mas não por cabo ou o oposto, ou se eu estabelecer uma VPN no host Windows, perco o acesso à Internet na VM, ou a comunicação entre a VM (Linux) e o host (Windows) quebra... enfim... é uma loucura!  Faz com que eu não confie no meu ambiente quando uso meu laptop para desenvolvimento, pequenas e rápidas demonstrações ou para apresentações, onde provavelmente o acesso à Internet não é tão importante quanto ter certeza de que as comunicações entre meu host e minhas VMs funcionam em uma forma confiável.

Com uma sub-rede local ad-hoc, compartilhada entre seu host Windows e suas máquinas virtuais, você resolve. Para permitir que eles se comuniquem entre si, você usa essa sub-rede e é isso. Você só precisa atribuir IPs específicos ao seu host e às suas VMs e tudo pronto.

É muito fácil fazer isso com essas etapas. Basta ir em Gerenciador de Comutador virtual...  que você encontrará em seu  Gerenciador Hyper-V:

Uma vez lá, vá até a opção _Novo  Comutador Virtual __ _(será como uma nova placa de rede para a VM):

Certifique-se de defini-la como uma Rede Interna , escolha o nome que queremos e deixe as outras opções como padrão

Agora, se formos ao Painel de Controle do Windows > Central de Rede e Compartilhamento, veremos que já temos lá o switch que acabamos de criar:

4. Configure a sub-rede local compartilhada pelo host e as máquinas virtuais

Neste ponto, você pode concluir a configuração de sua nova rede local. Para fazer isso, coloque o cursor sobre a conexão  Meu Novo Comutador LOCAL,  clique e vá em Propriedades, e de lá para o protocolo IPv4 para atribuir um endereço IP fixo:

 

Importante: O IP que você atribuir aqui será o IP do seu host (Windows) nesta sub-rede local.

5. Conecte e configure sua nova rede local para sua máquina virtual

Agora volte ao seu  Gerenciador Hyper-V. Se sua VM estiver em execução, pare-a. Depois de parado, vá para sua configuração e adicione o novo switch virtual interno:

_(Nota – Na imagem você pode ver outro switch, o Comutador INTERNO Hyper-V. É para outra sub-rede que eu tenho. Mas não é necessário para você nesta configuração) _

Depois de clicar em Adicionar, você só terá que selecionar o switch que você criou anteriormente:

Bem, uma vez feito isso, clique em Aplicar, Aceitar... e você está pronto! Você pode iniciar e entrar novamente em sua máquina virtual para finalizar a configuração da conexão interna. Para fazer isso, assim que a VM iniciar, clique no ícone de rede (à direita) e você verá que tem 2 redes: _eth0 _e eth1. O eth1 aparece como desconectado... por agora:

Vá para a configuração da Ethernet (eht1) e atribua um IP fixo para esta sub-rede local, por exemplo: 155.100.101.1, e a máscara de sub-rede:_ 255.255.255.0_

e isso é tudo. Aqui você tem sua máquina virtual, identificada com o IP 155.100.101.1 compartilhando a mesma sub-rede com seu host.

7. Permitir acesso ao Windows 10 de sua máquina virtual

Você provavelmente descobrirá que o Windows 10 não permite por padrão a conexão de outro servidor e, para o seu sistema Windows, a VM que você acabou de criar é exatamente isso, um servidor externo e potencialmente perigoso... então você terá que adicionar uma regra no Firewall para poder se conectar ao seu host a partir dessas máquinas virtuais. Como? Muito fácil, basta procurar pelo Firewall do Windows Defender no seu Painel de Controle do Windows, ir em Configuração Avançada e  criar uma nova Regra de Entrada:

Você pode definir uma porta ou um ou vários intervalos nelas... (também pode definir a regra para todas as portas)...

A ação que queremos é Permitir Conexão...

Para todos os tipos de redes...

Dê um nome à sua regra...

importante, imediatamente depois disso, abra novamente as propriedades de sua regra recém-criada e limite o escopo da aplicação, para aplicar apenas nas conexões dentro de sua sub-rede local...

8. PRONTO. Instale o Docker e qualquer outra aplicação em sua nova máquina virtual Ubuntu

Depois de passar por todo o processo de instalação e ter sua nova VM pronta e atualizada, com acesso à internet, etc. você pode instalar as aplicações que desejar... Docker é o mínimo, essa foi a ideia para começar, você também pode instalar seu cliente VPN se precisar de uma conexão com a rede de sua empresa, VS Code, Eclipse+Atelier,...

Especificamente, para instalar o Docker, em sua VM, você pode seguir as instruções que encontrará aqui: https://docs.docker.com/install/linux/docker-ce/ubuntu/

Certifique-se de que o tempo de execução do Docker está funcionando, baixe alguma imagem de teste, etc... e é isso.

Com isso... Está tudo pronto!, agora você poderá ter contêineres rodando sem limitações (além da capacidade do seu hardware) em sua VM Ubuntu, aos quais você poderá se conectar a partir de seu host Windows 10, de um navegador ou aplicativo e vice-versa, de seu Ubuntu VM  para seu host Windows 10. Tudo isso usando  seus endereços IP configurados em sua sub-rede local compartilhada, que funcionará independente se você tem uma VPN estabelecida ou não, se você acessa à Internet através de seu adaptador Wi-Fi ou via cabo ethernet.

Ah... um último conselho. Se você deseja trocar arquivos entre o Windows 10 e suas máquinas virtuais, uma opção muito útil e simples é usar o WinSCP. É gratuito e funciona muito bem.

Bem, com certeza existem outras configurações... mas esta é a que utilizo e provou ser a mais confiável. Espero que você também ache útil. Se eu evitei qualquer dor de cabeça, este artigo terá valido a pena.

Boa codificação! 

0
0 910
Anúncio Angelo Bruno Braga · Out. 29, 2020

Olá Comunidade!

É com grande prazer que convidamos todos os desenvolvedores para o o próximo Webinar Inicial do Concurso de Interoperabilidade InterSystems! O assunto deste webinar é o Concurso de Interoperabilidade.

Neste webinar, nós iremos falar a respeito das funcionalidades de interoperabilidade de nossa plataforma de dados InterSystems IRIS, iremos fazer uma demonstração de como criar uma solução de interoperabilidade básica no IRIS e demonstrar como utilizar o PEX. Além disto iremos discutir e responder perguntas de como criar soluções de interoperabilidade utilizando as plataformas de dados InterSystems IRIS e IRIS for Health.

Dara e Horário: Segunda, 2 de Novembro — 12:00 BRT (horário de Brasília)

Palestrantes:  
🗣 @Stefan Wittmann, InterSystems Product Manager 
🗣 @Eduard Lebedyuk, InterSystems Sales Engineer
🗣 @Evgeny Shvarov, InterSystems Developer Ecosystem Manager


0
0 72
Artigo Henrique Dias · Out. 26, 2020 3m read

Fala pessoal!


Quero dividir com vocês um projeto pessoal, que iniciou como um simples pedido no meu trabalho: 

É possível saber quantas licenças Caché estamos utilizando? 

Lendo outros artigos aqui na comunidade, eu encontrei este excelente artigo de David Loveluck 


APM - Utilizando Caché History Monitor
https://community.intersystems.com/post/apm-using-cach%C3%A9-history-monitor

Então, utilizando o artigo de David como base, eu comecei a utilizar o Caché History Monitor e a exibir todas as informações.
Quando me deparei com o seguinte dilema: Qual a melhor tecnologia de frontend que eu posso usar?

0
0 218
Artigo Evgeny Shvarov · Out. 26, 2020 5m read

Olá, desenvolvedores!

"objectscript.conn" :{
      "ns": "IRISAPP",
      "active": true,
      "docker-compose": {
        "service": "iris",
        "internalPort": 52773
      }

Quero compartilhar com vocês um novo recurso bem maneiro que descobri no novo lançamento 0.8 do plugin VSCode ObjectScript de @Dmitry Maslennikov e CaretDev.

O lançamento traz uma nova configuração "docker-compose", que resolve o problema com as portas necessárias para fazer o VSCode Editor se conectar à IRIS. Não era muito conveniente se você tivesse mais de um contêiner Docker com a IRIS em execução na mesma máquina. Agora, esse problema foi resolvido!

Veja abaixo como funciona.

O conceito de usar o Docker localmente para desenvolvimento com a IRIS  pressupõe que você tem o dockerfile e o docker-compose.yml no repositório usado para compilar o ambiente do projeto e carregar todo o código ObjectScript no contêiner IRIS obtido pelo Docker Hub. Além disso, você tem o arquivo .vscode/settings.json do VSCode no repositório ao qual você aponta a porta de conexão do servidor web IRIS (junto com outras configurações de conexão, como URL, Namespace e credenciais de login).

A pergunta é: qual é a porta à qual o VSCode deve se conectar?

Você pode usar a porta 52773, que é a porta IRIS padrão para servidores web. Mas, se você tentar iniciar o segundo contêiner do Docker, haverá uma falha, pois você não pode executar dois contêineres do Docker na mesma máquina que esperam conexões pela mesma porta. Mas você pode expor uma porta externa para o contêiner do Docker, e isso pode ser configurado por um arquivo docker-compose.yml. Veja um exemplo (a porta mapeada está em negrito):

version: '3.6'
services:
  iris:
    build: .
    restart: always
    ports:
      - 52791:52773
    volumes:
      - ~/iris.key:/usr/irissys/mgr/iris.key
      - ./:/irisdev/app

No docker-compose, você deve inserir a mesma porta em .vscode/settings.json:

Mas qual é o problema?

O problema é que, quando você expõe seu projeto como uma biblioteca ou demonstração e convida pessoas a executar e editar o código com o VSCode, você não quer que elas configurem a porta manualmente e quer que elas clonem o repositório, executem o Docker e tenham a opção de colaborar imediatamente. Eis a pergunta: no docker-compose, a que você deve mapear seu projeto para que não haja conflito com o ambiente de outra pessoa?

Mesmo se você não o expuser a ninguém exceto você mesmo, que porta deve colocar nas configurações de conexão do .vscode/settings.json?

A resposta é: quando você inicia um novo Docker com a IRIS, é exibida a mensagem de erro dizendo que a porta já está sendo usada e que você deve interromper os outros contêineres ou inventar uma nova porta que provavelmente não esteja em uso e tentar usá-la no docker-compose e settings.json.

Que chatice! É uma operação inútil que gasta tempo demais. Ninguém gosta de fazer isso.

O mesmo ocorre se você expuser a biblioteca.

O alívio chegou com o novo lançamento 0.8 do VSCode ObjectScript, em que você pode incluir uma seção docker-compose, que resolve o problema para sempre:

"objectscript.conn" :{
      "ns": "IRISAPP",
      "active": true,
      "docker-compose": {
        "service": "iris",
        "internalPort": 52773
      }

A seção contém os parâmetros "service" e "internalPort", que informam ao VSCode que, para encontrar a porta de conexão, deve-se verificar o arquivo docker-compose.yml que temos no mesmo repositório, encontrar "iris" na seção "service" e obter a porta, mapeada para a porta interna 52773.

Viva!

O mais maneiro é que agora o Docker tem o modo para docker-compose.yml em que você pode não configurar nenhuma porta no Docker. Você pode deixar o símbolo "-" na porta mapeada, e o Docker usará uma porta disponível aleatoriamente. 

iris:
    build: 
      context: .
      dockerfile: Dockerfile-zpm
    restart: always
    ports: 
      - 51773
      - 52773
      - 53773
    volumes:
      - ~/iris.key:/usr/irissys/mgr/iris.key
      - ./:/irisdev/app

Viva de novo! Agora, você tem uma opção para não se preocupar mais com as portas do servidor web da IRIS às quais o VSCode se conecta.

Como funciona nesse caso: executamos o docker-compose.yml, o Docker escolhe uma porta aleatória do servidor web e executa a IRIS com ela, o VSCode obtém essa porta pelo Docker e conecta-se à IRIS por ela, e você pode editar e compilar o código imediatamente. Sem nenhuma configuração adicional.

Não tem nada melhor que isso!

E você pode fazer o mesmo com o seguinte modelo que enviei recentemente de acordo com o novo recurso do VSCode ObjectScript 0.8, que atualizou o settings.json e o docker-compose.yml. Para testar o modelo, execute os comandos abaixo no terminal (testados no Mac). Você também precisa do git e do Docker Desktop instalados. 

$ git clone https://github.com/intersystems-community/objectscript-docker-template.git

$ cd objectscript-docker-template

$ docker-compose up -d

Abra essa pasta no VSCode (é preciso ter o plugin VScode ObjectScript instalado):

Verifique se o VSCode está conectado – clique na linha de status do VSCode:

Reconecte o VSCode, se necessário.

Você pode abrir o IRIS Terminal no VSCode, se necessário, com o menu ObjectScript.

Concluído! Agora, você pode executar, compilar e depurar o código!

Viva a programação!

0
0 171
Artigo Evgeny Shvarov · Out. 6, 2020 13m read

Olá, desenvolvedores!

Muitos de vocês publicam suas bibliotecas InterSystems ObjectScript no Open Exchange e GitHub.

Mas o que você faz para facilitar o uso e a colaboração do seu projeto por desenvolvedores?

Neste artigo, quero apresentar uma maneira fácil de iniciar e contribuir com qualquer projeto ObjectScript apenas copiando um conjunto padrão de arquivos para o seu repositório.

Vamos lá!

Copie esses arquivos deste repositório para o seu repositório:

Dockerfile

docker-compose.yml

Installer.cls

iris.script

settings.json{#9f423fcac90bf80939d78b509e9c2dd2-d165a4a3719c56158cd42a4899e791c99338ce73}

.dockerignore{#f7c5b4068637e2def526f9bbc7200c4e-c292b730421792d809e51f096c25eb859f53b637}
.gitattributes{#fc723d30b02a4cca7a534518111c1a66-051218936162e5338d54836895e0b651e57973e1}
.gitignore{#a084b794bc0759e7a6b77810e01874f2-e6aff5167df2097c253736b40468e7b21e577eeb}

E você agora possui uma maneira padrão de lançar e colaborar com seu projeto. Abaixo está o longo artigo sobre como e por que isso funciona.

OBS.: Neste artigo, consideraremos projetos que podem ser executados no InterSystems IRIS 2019.1 e versões mais recentes.

Escolhendo o ambiente de lançamento para projetos do InterSystems IRIS

Normalmente, queremos que um desenvolvedor teste o projeto/biblioteca e tenha certeza de que será um exercício rápido e seguro.

Na minha humilde opinião, a abordagem ideal para lançar qualquer coisa nova de forma rápida e segura é através da utilização do contêiner Docker, que dá ao desenvolvedor uma garantia de que tudo o que ele/ela inicia, importa, compila e calcula é seguro para a máquina host e de que nenhum sistema ou código será destruído ou deteriorado. Se algo der errado, basta parar e remover o contêiner. Se a aplicação ocupa uma quantidade enorme de espaço em disco, você a limpa com o contêiner e seu espaço estará de volta. Se uma aplicação deteriora a configuração do banco de dados, você exclui apenas o contêiner com configuração deteriorada. É assim, simples e seguro.

O contêiner Docker oferece segurança e padronização.

A maneira mais simples de executar o contêiner Docker do InterSystems IRIS é executar uma imagem do IRIS Community Edition:

  1. Instale o Docker desktop 

  2. Execute no terminal do sistema operacional o seguinte:

docker run --rm -p 52773:52773 --init --name my-iris store/intersystems/iris-community:2020.1.0.199.0
  1. Em seguida, abra o Portal de Administração do IRIS em seu navegador host em:

http://localhost:52773/csp/sys/UtilHome.csp

  1. Ou abra uma sessão no terminal:

    docker exec -it my-iris iris session IRIS

  2. Pare o contêiner IRIS quando não precisar mais dele:

    docker stop my-iris

OK! Executamos o IRIS em um contêiner docker. Mas você deseja que um desenvolvedor instale seu código no IRIS e talvez faça algumas configurações. Isso é o que discutiremos a seguir.

Importando arquivos ObjectScript

O projeto InterSystems ObjectScript mais simples pode conter um conjunto de arquivos ObjectScript como classes, rotinas, macro e globais. Verifique o artigo sobre nomenclatura e estrutura de pastas proposta.

A questão é: como importar todo esse código para um contêiner IRIS?

Aqui é o momento em que o Dockerfile nos ajuda pois podemos usá-lo para pegar o contêiner IRIS padrão, importar todo o código de um repositório para o IRIS e fazer algumas configurações com o IRIS, se necessário. Precisamos adicionar um Dockerfile no repositório.

Vamos examinar o Dockerfile do repositório de modelos ObjectScript:

ARG IMAGE=store/intersystems/irishealth:2019.3.0.308.0-community
ARG IMAGE=store/intersystems/iris-community:2019.3.0.309.0
ARG IMAGE=store/intersystems/iris-community:2019.4.0.379.0
ARG IMAGE=store/intersystems/iris-community:2020.1.0.199.0
FROM $IMAGE

USER root

WORKDIR /opt/irisapp
RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp

USER irisowner

COPY  Installer.cls .
COPY  src src
COPY iris.script /tmp/iris.script # run iris and initial 

RUN iris start IRIS \
    && iris session IRIS < /tmp/iris.script

 

As primeiras linhas ARG definem a variável $IMAGE - que usaremos então em FROM. Isso é adequado para testar/executar o código em diferentes versões do IRIS, trocando-os apenas pelo que é a última linha antes do FROM para alterar a variável $IMAGE. 

Aqui temos: 

ARG IMAGE=store/intersystems/iris-community:2020.1.0.199.0

FROM $IMAGE

Isso significa que estamos pegando o IRIS 2020 Community Edition versão 199.

Queremos importar o código do repositório - isso significa que precisamos copiar os arquivos de um repositório para um contêiner do docker. As linhas abaixo ajudam a fazer isso:

USER root

WORKDIR /opt/irisapp
RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp

USER irisowner

COPY  Installer.cls .
COPY  src src

USER root - aqui, mudamos o usuário para root para criar uma pasta e copiar arquivos no docker.

WORKDIR  /opt/irisapp - nesta linha configuramos o diretório de trabalho no qual copiaremos os arquivos.

RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp   -  aqui, damos os direitos ao usuário e grupo irisowner que executam o IRIS.

USER irisowner - trocando usuário de root para irisowner

COPY Installer.cls .  - copiando o Installer.cls para a raiz do workdir. Não esqueça aqui do ponto.

COPY src src - copia os arquivos de origem da pasta src no repo para a pasta src no workdir no docker.

No próximo bloco, executamos o script inicial, onde chamamos o instalador e o código ObjectScript:

COPY iris.script /tmp/iris.script # executar o iris e iniciar 
RUN iris start IRIS \
    && iris session IRIS < /tmp/iris.script

COPY iris.script / - copiamos iris.script para o diretório raiz. Ele contém o ObjectScript que desejamos chamar para configurar o contêiner.

RUN iris start IRIS</span>  - inicia o IRIS

&& iris session IRIS < /tmp/iris.script - inicia o terminal IRIS e insere o ObjectScript inicial nele.

Ótimo! Temos o Dockerfile, que importa arquivos no docker. Mas nos deparamos com outros dois arquivos: installer.cls e iris.script. Vamos examiná-los.

Installer.cls

Class App.Installer
{

XData setup
{
<Manifest>
  <Default Name="SourceDir" Value="#{$system.Process.CurrentDirectory()}src"/>
  <Default Name="Namespace" Value="IRISAPP"/>
  <Default Name="app" Value="irisapp" />

  <Namespace Name="${Namespace}" Code="${Namespace}" Data="${Namespace}" Create="yes" Ensemble="no">

    <Configuration>
      <Database Name="${Namespace}" Dir="/opt/${app}/data" Create="yes" Resource="%DB_${Namespace}"/>

      <Import File="${SourceDir}" Flags="ck" Recurse="1"/>
    </Configuration>
    <CSPApplication Url="/csp/${app}" Directory="${cspdir}${app}"  ServeFiles="1" Recurse="1" MatchRoles=":%DB_${Namespace}" AuthenticationMethods="32"
       
    />
  </Namespace>

</Manifest>
}

ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]
{
  #; Deixe o documento XGL gerar código para este método. 
  Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "setup")
}

}

Francamente, não precisamos do Installer.cls para importar arquivos. Isso pode ser feito com uma linha. Mas frequentemente, além de importar o código, precisamos configurar a aplicação CSP, introduzir configurações de segurança, criar bancos de dados e namespaces.

Neste Installer.cls, criamos um novo banco de dados, namespace com o nome IRISAPP e criamos a aplicação /csp/irisapp padrão para este namespace.

Tudo isso realizamos no elemento <Namespace>:

<Namespace Name="${Namespace}" Code="${Namespace}" Data="${Namespace}" Create="yes" Ensemble="no">

    <Configuration>
      <Database Name="${Namespace}" Dir="/opt/${app}/data" Create="yes" Resource="%DB_${Namespace}"/>

      <Import File="${SourceDir}" Flags="ck" Recurse="1"/>
    </Configuration>
    <CSPApplication Url="/csp/${app}" Directory="${cspdir}${app}"  ServeFiles="1" Recurse="1" MatchRoles=":%DB_${Namespace}" AuthenticationMethods="32"
       
    />
  </Namespace>

E importamos todos os arquivos do SourceDir com a tag Import:

<Import File="${SourceDir}" Flags="ck" Recurse="1"/>

SourceDir aqui é uma variável, que é definida para o diretório/pasta src atual:

<Default Name="SourceDir" Value="#{$system.Process.CurrentDirectory()}src"/>

Uma classe Installer.cls com essas configurações nos dá a confiança de que criamos um novo banco de dados IRISAPP limpo, no qual importamos código ObjectScript arbitrário da pasta src.

iris.script

Aqui, você é bem-vindo para fornecer qualquer código de configuração ObjectScript inicial que deseja para iniciar seu contêiner IRIS.

Ex. Aqui carregamos e executamos o installer.cls e então criamos o UserPasswords sem expiração, apenas para evitar a primeira solicitação de alteração da senha, pois não precisamos desse prompt para o desenvolvimento.

; run installer to create namespace
do $SYSTEM.OBJ.Load("/opt/irisapp/Installer.cls", "ck")
set sc = ##class(App.Installer).setup()  zn "%SYS"
Do ##class(Security.Users).UnExpireUserPasswords("*") ; call your initial methods here
halt

docker-compose.yml

Por que precisamos de docker-compose.yml ? Não poderíamos simplesmente construir e executar a imagem apenas com Dockerfile? Sim, poderíamos. Mas docker-compose.yml simplifica a vida.

Normalmente, docker-compose.yml é usado para iniciar várias imagens docker conectadas a uma rede.

docker-compose.yml também pode ser usado para tornar a inicialização de uma imagem docker mais fácil quando lidamos com muitos parâmetros. Você pode usá-lo para passar parâmetros para o docker, como mapeamento de portas, volumes, parâmetros de conexão VSCode.

version: '3.6' 
services:
  iris:
    build: 
      context: .
      dockerfile: Dockerfile
    restart: always
    ports: 
      - 51773
      - 52773
      - 53773
    volumes:
      - ~/iris.key:/usr/irissys/mgr/iris.key
      - ./:/irisdev/app

Aqui, declaramos o serviço iris, que usa o arquivo docker Dockerfile e expõe as seguintes portas do IRIS: 51773, 52773, 53773. Além disso, este serviço mapeia dois volumes: iris.key do diretório inicial da máquina host para a pasta IRIS onde é esperado, e ele mapeia a pasta raiz do código-fonte para a pasta /irisdev/app.

Docker-compose nos oferece o comando mais curto e unificado para construir e executar a imagem, quaisquer que sejam os parâmetros que você configurar no docker compose.

em qualquer caso, o comando para construir e lançar a imagem é:

$ docker-compose up -d

 e para abrir o terminal IRIS:

$ docker-compose exec iris iris session iris

Node: 05a09e256d6b, Instance: IRIS

USER>

Além disso, docker-compose.yml ajuda a configurar a conexão para o plugin VSCode ObjectScript.

.vscode/settings.json

A parte relacionada às configurações de conexão da extensão ObjectScript é esta:

{
    "objectscript.conn" :{
      "ns": "IRISAPP",
      "active": true,
      "docker-compose": {
        "service": "iris",
        "internalPort": 52773
      }
    }     

}

Aqui vemos as configurações, que são diferentes das configurações padrão do plugin VSCode ObjectScript.

Aqui, dizemos que queremos nos conectar ao namespace IRISAPP (que criamos com Installer.cls):

"ns": "IRISAPP",

e há uma configuração docker-compose, que informa que, no arquivo docker-compose dentro do serviço "iris", o VSCode se conectará à porta, para a qual 52773 está mapeado:

"docker-compose": {
        "service": "iris",
        "internalPort": 52773
      }

Se verificarmos o que temos para 52773, veremos que esta é a porta mapeada não definida para 52773:

ports: 
      - 51773
      - 52773
      - 53773

Isso significa que uma porta aleatória disponível em uma máquina host será obtida e o VSCode se conectará a este IRIS no docker via porta aleatória automaticamente.

Este é um recurso muito útil, pois oferece a opção de executar qualquer quantidade de imagens do docker com IRIS em portas aleatórias e ter VSCode conectado a elas automaticamente.

E quanto a outros arquivos?

Nos também temos:

.dockerignore  - arquivo que você pode usar para filtrar os arquivos da máquina host que você não deseja que sejam copiados para a imagem docker que você construir. Normalmente .git e .DS_Store são linhas obrigatórias.

.gitattributes - atributos para git, que unificam terminações de linha para arquivos ObjectScript em fontes. Isso é muito útil se o repositório for colaborado por proprietários de Windows e Mac/Ubuntu.

.gitignore - arquivos, os quais você não deseja que o git rastreie o histórico de alterações. Normalmente, alguns arquivos ocultos no nível do sistema operacional, como .DS_Store.

Ótimo!

Como tornar seu repositório executável em docker e amigável para colaboração?

  1. Clone este repositório.

  2. Copie todos esses arquivos:

Dockerfile

docker-compose.yml

Installer.cls

iris.script

settings.json{#9f423fcac90bf80939d78b509e9c2dd2-d165a4a3719c56158cd42a4899e791c99338ce73}

.dockerignore{#f7c5b4068637e2def526f9bbc7200c4e-c292b730421792d809e51f096c25eb859f53b637}
.gitattributes{#fc723d30b02a4cca7a534518111c1a66-051218936162e5338d54836895e0b651e57973e1}
.gitignore{#a084b794bc0759e7a6b77810e01874f2-e6aff5167df2097c253736b40468e7b21e577eeb}

para o seu repositório.

Altere esta linha no Dockerfile para corresponder ao diretório com ObjectScript no repositório que você deseja importar para o IRIS (ou não altere se estiver na pasta /src).

É isso. E todos (e você também) terão seu código importado para o IRIS em um novo namespace IRISAPP.

Como as pessoas irão iniciar o seu projeto

o algoritmo para executar qualquer projeto ObjectScript no IRIS pode ser:

  1. Clone o projeto Git localmente

  2. Execute o projeto:

$ docker-compose up -d
$ docker-compose exec iris iris session iris

Node: 05a09e256d6b, Instance: IRIS

USER>zn "IRISAPP"

**Como qualquer desenvolvedor pode contribuir para o seu projeto **

  1. Bifurque o repositório e clone o repositório git bifurcado localmente

  2. Abra a pasta no VSCode (eles também precisam que as extensões Docker e ObjectScript estejam instaladas no VSCode)

  3. Clique com o botão direito em docker-compose.yml->Reiniciar - VSCode ObjectScript irá conectar-se automaticamente e estará pronto para editar/compilar/depurar

  4. Commit, Push e Pull as mudanças solicitadas em seu repositório

Aqui está um pequeno gif sobre como isso funciona:

É isso! Viva a programação!

0
0 490