software‎ > ‎módulos‎ > ‎engine‎ > ‎manuais‎ > ‎

Union File System

Introdução

A Union File System (UnionFS) é um sistema de arquivos alternativo à Virtual File System (VirtualFS) que permite que os arquivos estejam contidos em múltiplas origens, entre elas, no disco do sistema operacional. Essa é uma característica importante para que possam ser utilizadas IDEs de mercado para editar códigos fontes do sistema.

Ao contrário da VirtualFS, que está completamente no banco de dados e é replicada para todos os Engines por meio do cache local, a UnionFS pode ser configurada localmente no Engine, possibilitando que duas instâncias de Engine tenham arquivos distintos, apesar de estarem usando a mesma base de dados.

A UnionFS atualmente permite a utilização de arquivos a partir de duas fontes: diretórios do sistema operacional e arquivos JAZ.

Configuração da Union File System


O UnionFS é configurado através do arquivo de configuração do Engine iengine.conf, podendo ser editado diretamente no disco, ou pela interface Manager do Engine, em configuration/others. Exemplo de configuração:

<UnionFS>
  # Se habilitado, os arquivos JAZ que estiverem na VFS serão copiados para o disco e incluídos
  IncludeVFSJazArchives on
  # Pastas e arquivos jaz que são incluídos no UnionFS
  Directory c:\myrepository
</UnionFS>


A seção UnionFS do arquivo de configuração define a pasta no disco raiz da UFS.É permitida a utilização de mais de um diretório raiz, realizando uma mescla do conteúdo dos diretórios, criando a visão de um único sistema de arquivos. Suponhamos que temos dois repositórios, o repositório usado para o desenvolvimento de uma biblioteca libX, e o repositório usado para o desenvolvimento de uma outra biblioteca libY.

c:\projetoX\engine\libx\scriptx.js
c:\projetoY\engine\libY\scripty.js


Caso queiramos trabalhar com esses dois repositórios ao mesmo tempo, devemos incluí-los no arquivo de configuração da seguinte forma:


<UnionFS>
  # Se habilitado, os arquivos JAZ que estiverem na VFS serão copiados para o disco e incluídos
  IncludeVFSJazArchives on
  # Pastas e arquivos jaz que são incluídos no UnionFS
  Directory c:\projetoX
  Directory c:\projetoY
<UnionFS>


Com essa configuração, a UnionFS terá a seguinte hierarquia de arquivos:
  • /engine
    • /libx
      • scriptx.js
    • liby
      • scripty.js

Arquivo de manifesto

Algumas configurações da UnionFS podem ser definidas em um arquivo json nomeado jazmanifest.json contido na raiz do repositório. Atualmente, a única propriedade aceita é a encoding. Ela indica a codificação dos arquivos contidos em um arquivo JAZ ou diretório do sistema operacional. Caso ele não seja informado, será considerado UTF8. Os valores atualmente suportados são ISO-8859-1 e UTF-8.

{
    "encoding": "UTF-8"
}

Em versões do Engine anteriores a 13.10 era possível definir esta configuração com a criação de um arquivo com o nome .ufs#utf8 na raiz do diretório. Apesar de ainda suportada, está configuração não deve ser mais utilizada e seu comportamento é sobrescrito pela configuração presente no manifesto, se este existir.

Habilitando Configurações da UnionFS

Todas as opções de configuração da UnionFS presentes no arquivos iengine.conf somente tem efeito se forem executadas num script de inicialização do Engine localizado em /Configuração/Inicialização do Engine. Por motivos de segurança, recomenda-se a criação de um script positivo de configuração apenas na base de desenvolvimento. O conteúdo desse script deve ser:

ngin.ufs.configureWithLocalSettings(engine.unionFS);

Importante: criar a configuração acima em ambiente de produção pode comprometer a segurança do sistema, pois permitirá que um usuário consiga injetar comportamentos em um determinado Engine que tenha acesso. Reforçamos que essa é uma configuração que deve ser ativada apenas em ambientes de desenvolvimento.

Arquivos JAZ

Um arquivo JAZ é um arquivo no formato zip contendo um conjunto de diretórios e arquivos. Quando o Engine encontra arquivos com a extensão .jaz na Virtual File System, ele descomprime esse arquivo e inclui os arquivos extraídos na Union File System. Eles também podem ser informados na configuração da UnionFS conforme exemplo abaixo:

<UnionFS>
  # Se habilitado, os arquivos JAZ que estiverem na VFS serão copiados para o disco e incluídos
  IncludeVFSJazArchives on
  # Pastas e arquivos jaz que são incluídos no UnionFS
  Directory c:\projetoX
  JazArchive c:\projetoY.jaz
</UnionFS>

Assim como diretórios, você também pode informar vários arquivos Jaz no arquivo de configuração.

O conteúdo de um arquivo JAZ por padrão é extraído na raiz da Union File System, exceto se ele contiver o arquivo package.json quando será tratado como um pacote JAZ.

Pacotes JAZ

Um arquivo JAZ que contiver o arquivo package.json na sua raiz será tratado como um pacote pelo Engine. Ao carregar um pacote JAZ o Engine importará os diretórios e arquivos do pacote no diretório engine_modules em vez da raiz da Union File System.

O uso de pacotes JAZ simplifica a importação das dependências, pois permite que os módulos possam ser carregados via require utilizando a identificação do pacote. O Engine trata o diretório engine_modules de forma similar ao tratamento dado pelo Node.js ao diretório node_modules. Essa similaridade de uso permite que as IDEs reconheçam os módulos importados corretamente e possam fazer sugestões ou validações de uso. Exemplo: dado o pacote my-package contendo o arquivo /lib/myFunc.js, o arquivo será acessível no caminho /engine_modules/my-package/lib/myFunc.js da Union File System. Dessa forma, o módulo poderá ser importado utilizando

var myFunc = require('my-package/lib/myFunc');

Importante:
pacotes JAZ, módulos CommonJS e a função require são funcionalidades experimentais que ainda não devem ser utilizados por parceiros ou clientes em customizações. Elas estão aqui documentadas apenas porque são funcionalidades que podem ser observadas durante a inspeção dos códigos do sistema. Será enviada uma notificação para os clientes e parceiros quando esses recursos estiverem estáveis e devidamente homologados.

Distribuindo arquivos JAZ

A distribuição dos arquivos JAZ é realizada de forma similar aos outros arquivos da VirtualFS. Eles devem ser gravados com chaves negativas e dessa forma serão enviados via processos de atualização do sistema.

Utilizando arquivos da UnionFS

A partir da versão 11 do Engine, foram criadas as funções__includeOnce() e __include() para importar arquivos da VirtualFS ou da UnionFS. A sintaxe é:

__includeOnce(uri);
__include(uri);
// onde uri é uma string com o path do arquivo, ou

__includeOnce(key);
__include(key);
// onde key é o número da chave de um script na Virtual File System.

A sintaxe antiga de incluir scripts, usando as palavras reservadas includeOnce e include ainda é suportada.

Esquemas dos sistemas de arquivos

Quando estamos em um script da VirtualFS e desejamos incluir um script da UnionFS, devemos informar o esquema na uri passado à função includeOnce. Por exemplo, caso um script nossa na VFS dependa de um script localizado na raiz da UFS, usamos esse método da seguinte forma:

__includeOnce("ufs:script.js");

Não é necessário informar o esquema, caso ele seja o mesmo do script que o inclui. Por exemplo, se o script do nosso exemplo anterior, script.js, necessita incluir um outro script da raiz da UFS, ele pode invocar a função diretamente:

__includeOnce("aux.js");

URIs relativas e top-level

Para carregarmos um script localizado na mesma pasta de outro, podemos usar uma URI relativa. URIs relativas são iniciadas por "./" para scripts na mesma pasta, ou "../" para scripts na pasta de nível imediatamente acima.

__includeOnce("./aux.js"); // inclui o script aux.js, na mesma pasta
__includeOnce("../master.js"); // include o script master.js, localizado na pasta superior

Quando desejamos definir completamente o caminho de um script, usamos URIs top-level. Elas iniciam com o nome da pasta raiz, sem a "/". Por exemplo:

__includeOnce("pasta/script.js");

Arquivos encriptados E2C

A partir da versão 2017-12, o Engine passou a suportar a encriptação do conteúdo dos arquivos contidos em um arquivo JAZ. Para isso, deve ser utilizado o formato E2C definido pelo Engine. Este recurso é opcional e deve ser utilizado de forma seletiva, pois é menos eficiente que o formato padrão do JAZ ao exigir o uso de funções de criptografia forte.

A criptografia adotada nos arquivos E2C busca criar um nível de proteção do conteúdo dos arquivos contidos em um arquivo JAZ, no entanto esse formato não deve ser considerado inviolável. A natureza de execução dinâmica e aberta do JavaScript e as características offline do Engine não permitem criar um sistema de criptografia totalmente seguro. Conteúdos que dependam de sigilo forte não devem adotar o formato E2C como forma de proteção e devem buscar tecnologias de criptografia existentes no sistema operacional e em sistemas de terceiros.

O arquivo E2C tem o seguinte formato binário:

-- file header - plain text
[4] file format Id
[2] file version (little endian)
[2] metadada size (little endian)
[n] metadata (size <= 64 Kb)
-- file header ext - plain binary
[32] header hash (sha256)
[16] authentication tag
[12] AES iv
[2] file prologue size + padding size (little endian)
-- end file header

----- start file prologue - RSA encrypted data using Engine public key
[4] payload size(little endian)
[16] AES 128 key
[n] padding
------ end file prologue

------ start file payload - AES GCM
[4] content size - (little endian)
[n] content
[] padding
-------end file payload

A chave pública RSA do Engine pode ser obtida no cadastro Admin > Licenciamento > Produtos licenciados, no campo "Chave RSA pública" do registro Engine exibido no modo formulário.

O formato E2C permite associar metadados ao arquivo encriptado. A versão atual do E2C adota o formato JSON nos metadados e permite indicar requerimentos de licenciamento para utilização do arquivo. O formato atual de metadados é:

{
  "license": {
    "product": <chave_do_produto/licença>,
    "extension": <chave da extensão do produto>
  }
}

A indicação de requerimentos de licenciamento é opcional. Quando não são informados não haverá verificação do licenciamento do sistema e os arquivos poderão ser utilizados sem restrição de uso.

Os arquivos E2C somente podem ser carregados por meio da função require do API do Module Loader. A tentativa de incluir um arquivo E2C por meio das funções __includeOnce e __include produzirá um erro.

Importante: de forma similar aos pacotes JAZ e API de Module Loader, o arquivo E2C é uma funcionalidade experimental que ainda não deve ser utilizada por parceiros ou clientes em customizações. O formato está aqui documentado apenas porque é uma funcionalidade que pode ser observada durante a inspeção dos códigos do sistema. Será enviada uma notificação para os clientes e parceiros quando este recurso estiver estável e devidamente homologado.