Se você deseja possibilitar que os usuários do Firefox OS facilmente atualize a versão do sistema em seus dispositivos, você precisa criar um pacote de atualização para eles usarem. Este artigo apresenta os diferentes tipos de pacote de atualização disponível e abrange a compilação do pacote, hospedagem das atualizações (e como o sistema faz o polling das atualizações disponíveis), aplicação e verificação das atualizações.
Essa atividade é dividida em quatro tarefas:
- Compilar um pacote de atualização incremental da versão(ões) anteriores para uma nova versão em uma máquina de compilacão.
- Encontrar o pacote de atualização correto.
- Baixar a atualização.
- Aplicar a atualização dos arquivos existentes no dispositivo.
Cada uma das etapas está descrita abaixo.
Tipos de atualização
São dois tipos de atualização a saber: FOTA e Gecko/Gaia OTA. Vamos verificar a diferença entre elas
Atualização FOTA
É possível atualizar o Firefox OS inteiro através da atualização FOTA, a tecnologia usada é compartilhada do projeto Android. Os locais no disco rígido do telefone podem ser alterados usando a alteração incluindo a partição do sistema, kernel, modem, imagem de recuperação usada para atualização, ou qualquer outro arquivo no dispositivo.
Firefox OS não depende de um cliente FOTA em particular, a interface é abstraída através de uma API que chamamos librecovery. Portanto nós recomendamos usar o cliente de recuperação GOTA (veja abaixo para mais detalhes), e assumiremos a utilização do FOTA a partir de agora.
O pacote de atualização FOTA consiste-se principalmente de um arquivo chamado update.zip
. Esse pacote possui:
- Um conjunto de "diffs" binários e novos arquivos necessários para a atualizção do cliente para a nova versão do software
- Um script de atualização que controla como os "diffs" e novos arquivos serão carregados no cliente
- Uma assinatura interna usada para verificar o pacote de atualização
O formato e o conjunto de arquivo são os mesmos que os usados em uma atualização normal do Android, exceto pelo fato de que o Firefox OS adicionamente envolve o pacote update.zip
em um invólucro mar
(MAR é o acrônimo de Mozilla ARchive). Esse invólucro mar
possibilita um nível adicional de verificação que será explicado abaixo.
Atualização Gecko/Gaia OTA
A outra opção é atualizar apenas os arquivos do Gecko e o Gaia em um dispositivo Firefox OS através de um mecanismo que nós chamamos atualizações Gecko/Gaia OTA. Todos os arquivos Gecko e Gaia — compreendendo o Gecko runtime core e as interfaces de usuário do dispositivo — estão no diretório do dispositivo /system/b2g
. Esse é o único diretório que o OTA pode fazer alterações.
As atualizações Gecko/Gaia OTA utilizam a mesma tecnologia utilizada pela atualização do navegador Firefox para desktop. Muito parecido com os pacotes FOTA update.zip
discutidos acima, as atualizações OTA consiste-se de um arquivo MAR contendo um conjunto de diffs binários e novos arquivos necessários para atualizar o cliente com uma nova versão.
O cliente Gecko verifica a integridade dos arquvios MARs
que foram baixados e os MARs
podem ser assinados por múltiplas partes.
Por que ter duas tecnologias de atualizações?
Atualizações OTA não são tão abrangentes as atualizações FOTA, mas são muito mais amigáveis e fáceis de usar, e geralmente o processo de atualização funciona bem.
- Atualizações Gecko/Gaia OTA podem ser aplicadas "em segundo plano", enquanto o Firefox OS continua a funcionar normalmente. Isso proporciona um experiência do usuário muito melhor uma vez que não é necessário reiniciar o telefone e esperar enquanto a atualização é aplicada. Quando o processo termina a única coisa que o usuário precisa fazer é concordar em reiniciar o processo principal
b2g
. Isso leva apenas alguns segundos, em vez dos minutos normalmente necessários para aplicar as atualizações FOTA. - Normalmente, mas nem sempre, os pacotes de atualização Gecko/Gaia OTA são menores que os pacotes FOTA. Isso significa que os usuários podem ter menos dados para baixar.
É claro que se você precisar atualizar arquivos fora do Gecko/Gaia, você terá que usar o roteiro do pacote completo FOTA.
Seguindo, vamos verificar o processo de compilação do pacote.
Compilando os pacotes de atualização
A compilação das atualizações é o processo de gerar os arquivos necessários para atualizar os clientes Firefox OS da versão X do software para a nova versão Y. O pacote de atualização necessário depende de quais arquivos foram alterados entre a versão X e a versão Y.
- se somente arquivos do diretório
/system/b2g
foram alterados, vamos gerar uma atualização Gecko/Gaia OTA - Se algum arquivo que não seja do diretório
/system/b2g
é alterado, nós vamos gerar uma atualização FOTA
Para gerar um pacote de atualização incremental (seja para atualização FOTA ou Gecko/Gaia OTA), nossas ferramentas necessitam compilações completas de ambas as versões X e Y (nova e a anterior). Compilação completa significa que o pacote inclui todos os arquivos necessários para fazer o flash no cliente. Quando nós produzimos uma compilação completa da versão X, nós não sabemos quais as futuras versões nós atualizaremos a partir da versão X. Por isso, nós compilamos ambos os pacotes para cada versão. Isso possibilita criar pacotes incrementais.
Numa visão geral, o processo de compilação é semalhante a isso:
- Com o software versão X
- Gerar um arquivo completo
MAR
do Gecko/Gaia OTA para o conteúdo do diretório/system/b2g
. - Gerar arquivo completo
update.zip
do FOTA e arquivos zip específicos para as partições do dispositivo.
- Gerar um arquivo completo
- Com o software versão Y
- Gerar um arquivo completo
MAR
do Gecko/Gaia OTA do diretório/system/b2g
. - Gerar um arquivo completo
update.zip
do FOTA e arquivos zip específicos para as partições do dispositivo.
- Gerar um arquivo completo
- Se apenas os arquivos do diretório
/system/b2g
foram alterados, gerar uma atualização incremental Gecko/Gaia OTAMAR
da versão X para a versão Y. - Caso contrário, gerar um arquivo
update.zip
da atualização incremental FOTA da versão X para a versão Y. Empacote a atualização incremental FOTAupdate.zip
em umMAR
para entrega ao cliente B2G. - Assine os pacotes como exigido pelos acordos de entrega.
A sub-sessão abaixo descreve como usar as ferramentas do B2G para implementar cada uma dessas etapas.
Nota: para executar as etapas a seguir assumimos que você já configurou um ambiente de compilação b2g na localização $b2g
. Os comandos abaixo fazem referência ao script de ajuda $b2g/build.sh
, mas o make
também pode ser usado.
Gerando uma atualização Gecko/Gaia OTA
completa em MAR
Execute gecko-update-full
para gerar um MAR
completo da última compilação bem sucedida do b2g
. Para colocar o MAR em $b2g/objdir-gecko/dist/b2g-update/b2g-gecko-update.mar
, use os seguintes comandos:
$ cd $b2g $ ./build.sh gecko-update-full $ cp objdir-gecko/dist/b2g-update/b2g-gecko-update.mar <destination>
Gerando uma atualização FOTA zip completa e arquivos de destino
O alvo padrão no sistema de compilação b2g
irá gerar um FOTA update.zip
/ arquivos de destino zip quando o kernel binário tiver sido copiado para a localização apropriada embaixo do diretório vendor/
. Isso habilita a imagem de boot, imagem de recuperação e a geração do update.zip.
- O arquivo completo do FOTA
update.zip
é gerado emout/target/product/$DEVICE/$DEVICE-ota-$VARIANT.$USER.zip
- O arquivo zip de destino é gerado em
out/target/product/$DEVICE/obj/PACKAGING/target_files_intermediates/$DEVICE-target_files-$VARIANT.$USER.zip
Os comandos a seguir realizam essa etapa:
$ cd $b2g $ ./build.sh target-files-package $ cp out/target/product/$DEVICE/obj/PACKAGING/target_files_intermediates/$DEVICE-target_files-$VARIANT.$USER.zip <destination>
Os valores das variáveis nos comandos listados acima devem ser preenchidos dessa forma:
Variable | Meaning |
---|---|
$DEVICE |
O nome do dispositvo para o produto AOSP |
$VARIANT |
eng , user , ou userdebug |
$USER |
O nome do usuário de compilaçãoThe build username |
Gerando um MAR da atualização incremental OTA
Nesse exemplo, nós assumimos que estamos gerando uma atualização do software versão X para versão Y. A localização do MAR completo da compilação Gecko/Gaia OTA da versão X usando as instruções acima será chamado de $MAR_X
. Isso deve ser um caminho no servidor de compilacão como por exemplo /home/build/b2g/versions/X/update.mar
. De forma similiar, a localização do MAR
completo da versão Y será chamado de $MAR_Y
.
A ferramenta build-gecko-mar.py
vair gerar uma MAR da atualização incremental usando $MAR_X
e $MAR_Y
. Nós chamaremos o destino do arquivo gerado de $GENERATED_INCREMENTAL_MAR_X_Y
. Use os seguintes comandos para essa etapa:
$ cd $b2g $ ./tools/update-tools/build-gecko-mar.py --from $MAR_X --to $MAR_Y $GENERATED_INCREMENTAL_MAR_X_Y
Gerando um update.zip da atualização incremental FOTA
Nesse exemplo, nós assumimos que estamos gerando uma atualização do software versão X para versão Y. A localização do arquivo zip completo do FOTA compilado do software vesrão X usando as instruções acima será chamado $TARGET_FILES_X
. Esse deve ser o caminho no servidor de compilação como /home/build/b2g/versions/X/target_files.zip
. De forma semelhante, a localização do zip destino do FOTA completo construido da versão Y será chamado $TARGET_FILES_Y
.
A ferramenta build/tools/releasetools/ota_from_target_files
irá gerar um FOTA incremental no arquivo update.zip usando $TARGET_FILES_X
e $TARGET_FILES_Y
. Nós chamamos o arquivo intermediário de $INTERMEDIATE_FOTA_UPDATE_FOTA_X_Y
.
Depois do arquivo update.zip
ter sido gerado, a última etapa é empacotá-lo em um arquvio MAR
para entrega ao cliente b2g. A ferramenta tools/update-tools/build-fota-mar.p
executa essa etapa. Nós chamaremos o destino desse arquivo gerado de $GENERATED_INCREMENTAL_FOTA_X_Y
. Use os seguintes comandos para completar essa etapa:
$ cd $b2g $ ./build/tools/releasetools/ota_from_target_files -v \ -i $TARGET_FILES_X \ -p out/host/$HOST_ARCH \ -k $FOTA_SIGNING_KEY \ $TARGET_FILES_Y \ $INTERMEDIATE_FOTA_UPDATE_FOTA_X_Y $ ./tools/update-tools/build-fota-mar.py $INTERMEDIATE_FOTA_UPDATE_FOTA_X_Y --output=$GENERATED_INCREMENTAL_FOTA_X_Y
Os valores das variáveis nos comandos listados acima devem ser preenchidos dessa forma:
Variable | Meaning |
---|---|
$TARGET_FILES_X |
Os arquivos zip destino do para a versão X |
$TARGET_FILES_Y |
Os arquivos zip destino do para a versão Y |
$GENERATED_INCREMENTAL_FOTA_X_Y |
O destino da atualização incremental em zip empacotado num |
$HOST_ARCH |
A combinação do host e arquitetura (i.e. linux-x86 ou darwin-x86 ) |
$FOTA_SIGNING_KEY |
Caminho para o prefixo para uma chave privada e o certificado público para assinatura do arquivo update zip. Ambos os arquivo $FOTA_SIGNING_ZIP.pk8 e $FOTA_SIGNING_ZIP.x509.pem devem existir no sistema |
Hospedagem e polling de atualizações no lado do cliente
Clientes Firefox OS fazem polling das atualizações através de um parsing do manifesto de atualização: update.xml
. Os clientes Firefox OS são configurados para fazer o polling de atualizações em servidores específicos — eles consultam um caminho especialmente construído no servidor. HTTPS é o protocolo recomendado para consultar o servidor, embora HTTP também é suportado. O servidor e o caminho utilizado pelos clientes podem ser alterados entregando uma atualização para clientes existentes que altera o código do polling.
Nos exemplos abaixo, assumimos que as atualizações estão hospedadas no servidor updates.b2g.com
.
A URL pesquisada pelo cliente comumente contém os seguintes parâmetros:
Parameter | Explanation |
---|---|
PRODUCT_MODEL |
O nome do modelo do dispositivo. É o valor da propriedade ro.product.model no banco de dados do B2G. |
CHANNEL |
O "canal" da atualização. Isso é útil para teste: servidores podem ser configurados para hospedar, por exemplo, os canais "nightly", "beta" e "release". |
VERSION |
A versão do software do cliente. Por exemplo, "18.0.2". |
BUILD_ID |
O ID unívoco como um timestamp, configurado para uma compilação em particular |
Entretando, existem mais valores que podem ser consultados para construir a consulta de URL de atualização.
O cliente Firefox usa os valores de onde as atualizações estão hospedadas para construir a URL para o polling em tempo de execução. Um exemplo dessa URL é:
https://updates.b2g.com/release/unagi1/18.0/20121203123456/update.xml
Se o servidor retornar um erro "404 Not Found" em resposta à requisição do cliente, então não há atulização disponível. Se o servidor retornar "200" e o arquivo manifesto, então há uma atualizacão disponível. O manifesto descreve a compilação recem-disponível, ou seja, a atualização que o cliente deve usar. Um exemplo de manifesto:
<?xml version="1.0"?> <updates> <update type="major" appVersion="19.0" version="19.0" extensionVersion="19.0" buildID="20121210123456" licenseURL="https://www.mozilla.com/test/sample-eula.html" detailsURL="https://www.mozilla.com/test/sample-details.html"> <patch type="partial" URL="https://updates.b2g.com/release/unagi1/18.0/20121203123456/update.mar" hashFunction="SHA512" hashValue="5111e033875752b7d9b32b4795152dea5ef954cb8a9d4a602dd19a923b464c43521287dcb5781faf3af76e6dc5e8a3dd9c13edea18c1f2c8f3bd89e17d103d6f" size="41901319"/> </update> </updates>
Os campos no manifesto descrevem:
- metadata usado para mostrar a interface no cliente
- metadata sobre a versão recém-disponível
- a localização do pacote de atualização
- metadata usado para verificar o download do pacote de atualização
Nota: O dispositivo do cliente ou o próprio usuário pode recusar a atualização.
Usando os mecanismos acima descritos, os servidores podem hospedar pacotes de atualização para atualizar qualquer versão antiga cliente para a versão mais recente. Ou podem hospedar somente uma "atualização linear" na qual os clientes devem atualizar através de um caminho simples.
Os detalhes da interação entre os servidores de compilação e de atualização estão fora do escopo desse documento. E são altamente dependentes no ambiente produtivo.
Verificando e aplicando as atualizações
Após o cliente Firefox OS ter baixado a atualização e verificado a integridade do pacote, a etapa final é aplicar a atualização.
A primeira etapa consiste-se em verificar as assinaturas embutidas nos pacotes MAR
. Isso é feito pelo próprio cliente Firefox OS após checar a integridade do pacote. O código usado para isso é o mesmo para atualizações FOTA ou Gecko/Gaia OTA.
Após as assinaturas terem sido verificadas, o processo de aplicar uma atualização diverge entre os tipos de pacotes. Vamos ver as diferenças entre os dois a partir de agora.
Aplicando atualizações Gecko/Gaia OTA
O cliente Firefox OS usa o executável updater
para aplicar as atualizações. É parte da distribuição Gecko e é o mesmo código usado para aplicar as atualizações do Firefox Desktop. Como descrito acima, a atualização é aplicada enquanto o Firefox OS continua a rodar normalmente. Usuários podem fazer e receber ligações, executar aplicativos, navegar na internet, etc durante o processo de atualização.
Os detalhes específicos do updater
estão além do escopo desse documento, mas seu funcionamento é aproximadamente descrito abaixo:
- Faz uma cópia do diretório
/system/b2g
. - Aplica os patches binários, removendo arquivos antigos, e incluindo os novos como especificado no arquivo
MAR
. - Reinicia o processo principal
b2g
para que utilize os novos arquivos.
Após reiniciar o processo b2g
o usuário já está executando a nova versão do software cliente B2G.
Aplicando atualizações FOTA
O cliente FOTA é o responsável por aplicar a atualização. O cliente Gecko não interefer no processo que será aplicado chamando a API librecovery. O que acontece após essa etapa é específico de cada cliente FOTA.
Na implementação do librecovery
usado pelo cliente FOTA, o pacote de atualização baixado é armazenado para ser aplicado e comandos especiais são enfileirados para recuperar o cliente. librecovery
então inicializa o dispositivo no modo recovery no qual é executado o script que está dentro do arquivo update.zip
que atualiza os arquivos e as partições necessárias. O cliente recovery pode necessitar reinicar o dispositivo diversas vezes para atualizar todos os arquivos.
Na inicialização final, o dispositivo estará com a nova versão do Firefox OS instalado.