URL da caixa do Vagrant para arquivo de metadados JSON

18

No meu arquivo Vagrant, posso especificar o URL de uma caixa:

config.vm.box_url = "http://example.com/my-box.pkg"

De acordo com a documentação mais recente , devo poder criar um arquivo JSON que contenha os URLs para diferentes versões da caixa. A documentação também diz que eu posso usar a URL desse arquivo JSON ao executar vagrant box add. Eu esperava poder usar a URL desse arquivo JSON config.vm.box_url. No entanto, isso não parece funcionar. Quando eu tento, ele trata como um arquivo de caixa:

Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'my-box' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Adding box 'my-box' (v0) for provider: virtualbox
    default: Downloading: http://example.com/my-box.pkg.json
    default: Progress: 100% (Rate: 876k/s, Estimated time remaining: 0:00:01)
The box failed to unpackage properly. Please verify that the box
file you're trying to add is not corrupted and try again. The
output from attempting to unpackage (if any):

bsdtar.EXE: Unrecognized archive format: Illegal byte sequence
bsdtar.EXE: Error exit delayed from previous errors.

É possível dizer ao Vagrant para usar um arquivo JSON de metadados da caixa no meu arquivo Vagrant? Prefiro não ter que usar o Vagrant Cloud.

Brad
fonte
Você já encontrou uma solução para isso?
21310 Jim Rubenstein1 de
@JimRubenstein Infelizmente, não. A sugestão de Nicholas pode funcionar, mas tenho certeza de que meu servidor já está enviando os cabeçalhos de tipo de conteúdo corretos para JSON. A resposta do Chux pode ser precisa, mas ainda não estou convencido, pois a documentação implica o contrário. Infelizmente, a documentação do Vagrant é bastante terrível e não dá muito contexto entre os níveis de tutorial básico e contribuição para o projeto e saída do IRC ... pelo menos para mim de qualquer maneira.
Brad
Estou testando algo enquanto falamos sobre a publicação de uma caixa + metadados para ver se consigo imitar o comportamento da nuvem vagante localmente. Eu vou deixar você saber como isso acaba.
21311 Jim Rubenstein

Respostas:

8

A partir de hoje (12/07/2016, vagrant 1.8.4), se você deseja executar seu próprio catálogo de maneira manual (ou seja, atualizando manualmente as caixas e editando o arquivo metadata.json), mas ainda assim ele se comporta como um catálogo real, lembre-se do seguinte:

  • Não há necessidade de o nome do arquivo "metadata.json". Pode ter qualquer nome, desde que contenha os valores esperados. Estou usando "metadata.json" aqui para esclarecer as etapas abaixo.

  • cada arquivo metadata.json pode conter apenas uma única caixa. Pode ter várias versões, e cada versão pode ter vários provedores (virtualbox, vmware, libvirt). Se você precisar ter mais de uma caixa (por exemplo, "fedora" e "ubuntu"), precisará de dois arquivos de metadados diferentes.

  • O Vagrant espera que o arquivo metadata.json tenha um tipo de "application / json" (como Nicholas Hinds mencionou acima. Se o seu servidor da Web não o devolver (ou retornar "text / plain"), o vagrant assumirá que é um arquivo de caixa real e tente analisá-lo (e falhar miseravelmente).

  • O Atlas da Hashicorp (que costumava ser o Vagrant Cloud) é a exceção, pois os redirecionamentos levam você ao conteúdo exibido como "text / html". Meu melhor palpite para isso é que tem algo a ver com os redirecionamentos (mais sobre isso abaixo).

  • O arquivo da caixa não precisa estar no mesmo local que o arquivo de metadados. Você pode ter seu arquivo de metadados em um servidor da web local e a caixa no Amazon S3, sem problemas.

Portanto, até onde cheguei, achei a maneira mais fácil de fazer isso funcionar em um servidor da web e ainda ter uma funcionalidade bastante normal:

No seu host da web, crie uma estrutura de arquivos e diretórios semelhante a esta:

d wwwroot/
d wwwroot/boxes
d wwwroot/boxes/yourname
f wwwroot/boxes/yourname/.htaccess
d wwwroot/boxes/yourname/box1
f wwwroot/boxes/yourname/box1/metadata.json
f wwwroot/boxes/yourname/box1/box1-$version1-$provider.box
f wwwroot/boxes/yourname/box1/box1-$version2-$provider.box
f wwwroot/boxes/yourname/box1/box1-$version2-$otherprovider.box
d wwwroot/boxes/yourname/box2
f wwwroot/boxes/yourname/box2/metadata.json
f wwwroot/boxes/yourname/box2/box2-$version1-$provider.box
(... etc)

(esse layout significa que seus "metadados.json" para a caixa1 terão que ter seus URLs apontando para algo como " http: // yourhost / boxes / seunome / box1 / box1- $ version1- $ provider.box")

No seu .htaccess, verifique se "metadata.json" está definido para o índice do Diretório. O restante é opcional, para cache negativo e ocultar o conteúdo real:

Header unset Pragma
FileETag None
Header unset ETag
DirectoryIndex metadata.json
IndexIgnore *
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate, private"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"

No seu ambiente, exporte o VAGRANT_SERVER_URL apontando para o seu host. Observe nenhuma barra à direita!

export VAGRANT_SERVER_URL="http://yourhost/boxes"

Com isso no lugar (e todos os arquivos com o conteúdo correto), você pode adicionar sua caixa diretamente:

vagrant box add yourname/box1

Como "metadata.json" é o arquivo de índice do diretório box1, ele deve redirecionar o conteúdo diretamente para ele, o vagrant o buscará, interpretará os metadados e fará o download da caixa apropriada.

Guto Andreollo
fonte
19

Depois de ler sua pergunta novamente, parece que você está tentando fazer algo um pouco diferente do que eu sou - mas acho que nosso objetivo final é o mesmo.

Não quero utilizar o serviço Vagrant Cloud para hospedar minhas caixas de base, mas quero poder distribuir um ambiente de desenvolvimento para minha equipe de desenvolvedores e utilizar os recursos do metadata.jsonarquivo para manter um sistema de versão para o ambiente de desenvolvimento, que estará disponível para minha equipe de desenvolvimento simplesmente usando os recursos incorporados ao vagrant.

A documentação vaga é realmente escassa nesta área no momento da redação deste artigo (8/5/2014), presumivelmente porque é um recurso relativamente novo, mas tenho certeza de que o VagrantCloud tem uma camada paga também tem algo a ver com isso. .

Para descobrir como utilizar o metadata.jsonarquivo para versão e distribuir caixas, dei uma olhada em algumas das VMs disponíveis no VagrantCloud. Depois de examinar essas informações e ler alguns dos códigos vagantes - tornou-se muito fácil descobrir como realizar meu objetivo.

  • Empacote sua caixa como faria normalmente. No meu caso, estou empacotando apenas para caixa virtual, porque é isso que nossos desenvolvedores usarão para executar o Vm. Também empacotei um Vagrantfile com minha caixa de base, que faz alguns provisionamentos para o ambiente de desenvolvimento (configurando compartilhamentos para pastas apropriadas, algumas configurações básicas do apache, registro de erros, etc.)
  • Crie um metadata.jsonarquivo para descrever sua caixa base, a minha é semelhante a esta:

    {
        "description": "long box description",
        "short_description": "short box description",
        "name": "company/developer-environment",
        "versions": [{
            "version": "1",
            "status": "active",
            "description_html": "<p>Dev Environment</p>",
            "description_markdown": "Dev Environment",
            "providers": [{
                "name": "virtualbox",
                "url": "http:\/\/vagrant.domain.local/dev/company-developer-environment-1.box"
            }]
        }]
    }
    

Depois de criar meu metadata.jsonarquivo, enviei-o para um servidor local em execução em nossa rede interna ( vagrant.domain.local/metadata.json). Depois que fiz isso, tudo o que restou foi testá-lo com vagrant:

# add the box to vagrant using the definition from metadata.json
# (the box is actually downloaded here, so it can take a minute...or 10)
$ vagrant box add http://vagrant.domain.local/dev/metadata.json

# init the box (this creates a .vagrant folder and a Vagrantfile in the cwd with the appropriate box name)
$ vagrant init company/developer-environment

# boot the box
$ vagrant up

Voila, uma caixa particular hospedada, compartilhada e com versão remota que não requer o uso da Nuvem Vagrant.

À medida que você cria novas versões da sua caixa, empacota e edita o metadata.jsonarquivo. Pelo que posso dizer, você pode usar qualquer esquema de versão que desejar, seja versão semântica (1.0.0, 1.0.1, etc) ou apenas números inteiros simples para versões (1, 2, 3, etc.). Quando o vagrant upvagrant dos usuários da sua caixa verifica automaticamente o arquivo metadata.json em busca de uma nova versão, e solicita que eles façam vagrant box updatea atualização da caixa.

Você também pode pular os bits vagrant box add <metadata.json url>e vagrant init, definindo um Vagrantfile base com o nome da caixa e o URL da caixa, da seguinte maneira:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "company/developer-environment"
  config.vm.box_url = "https://vagrant.domain.local/dev/metadata.json"
end

Você poderia distribuir um arquivo Vagrant com esse conteúdo, e todos os usuários apenas poderiam vagrant up. No entanto, não tenho certeza de como isso funciona quando as versões são atualizadas.

Jim Rubenstein
fonte
Perfeito, obrigado! No entanto ... como adiciono esse URL JSON ao Vagrantfile?
Brad
Você não precisa. Quando você adiciona a caixa, o Vagrant baixa a imagem atual da caixa e armazena as informações ~/.vagrant.d/boxes/<your box name>. Dentro dessa pasta, há o metadata_urlarquivo que é mencionado na documentação, que contém a URL do seu arquivo JSON que define suas versões. Alças Vagrant tudo o que automaticamente, então tudo que você tem a fazer é vagrant box add <your metadata.json url>, em seguida, apenas vagrant init <boxname> && vagrant up, vagabundo faz o resto
Jim Rubenstein
Entendo isso, mas estou tentando facilitar o máximo possível para que os desenvolvedores entrem em funcionamento. Adicionando um URL da caixa no Vagrantfile, não vagrant box addé necessário. Se eu pudesse definir o URL desse arquivo JSON no Vagrantfile, isso é menos uma etapa para um novo desenvolvedor que acabou de se juntar à equipe para começar a trabalhar. Funciona para caixas, mas não consigo entender por que não funciona no arquivo JSON.
Brad
11
ah, entendi - na verdade, acabei de encontrar uma solução para isso, apenas peidando. você precisa definir config.vm.boxAND config.vm.box_urlonde boxestá o nome da sua caixa e box_urlé a URL do seu arquivo json.
21419 Jim Rubenstein
11
Resposta @JimRubenstein Fantástico - assim como Goldilocks, não muito curto, não muito tempo :)
Steve Jansen
9

O Vagrant exige que os URLs de metadados da caixa sejam veiculados com o application/jsontipo de conteúdo. O erro que você está recebendo indica que o vagrant interpretou seu URL como uma caixa comum.

Verifique se o servidor HTTP está configurando o Content-Typecabeçalho adequadamente. A maioria dos servidores HTTP definirá automaticamente o Content-Type cabeçalho para application/jsonse o seu arquivo tiver a extensão.json

Nicholas Hinds
fonte
11
Não sei por que sua resposta não é a resposta, porque é exatamente isso que eu precisava fazer para fazer o provisionamento local funcionar com o Vagrant.
quer
4

Eu acho que você tem suas diretrizes misturadas ..

O seguinte é retirado do site vagrant:


ARQUIVO DE CAIXA

O arquivo da caixa real é a parte necessária para o Vagrant. É recomendável que você sempre use um arquivo de metadados ao lado de um arquivo de caixa, mas os arquivos de caixa direta são suportados por motivos herdados no Vagrant.

Box files are compressed using tar, tar.gz, or zip. The contents of the archive can be anything, and is specific to each provider. O próprio núcleo do Vagrant descompacta as caixas para uso posterior.

Within the archive, Vagrant does expect a single file: "metadata.json".Este é um arquivo JSON que não tem nenhuma relação com o componente "metadados da caixa" acima. This file must contain at least the "provider" key with the provider the box is for. Por exemplo, se sua caixa fosse para o VirtualBox, o metadata.json ficaria assim:

{
  "provider": "virtualbox"
}

If there is no metadata.json file or the file does not contain valid JSON with at least a "provider" key, then Vagrant will error when adding the box.


Então, acho que o formato do seu arquivo de caixa provavelmente está errado. Ou ele não está compactado com o formato recomendado ou você não incluiu um arquivo metadata.json no archive

Chux Uzoeto
fonte
Para outras pessoas com o mesmo problema, o caminho metadata.json (no Windows) é ..Users \ username \ vagrant.d \ caixas \ boxname \ 0 \ VirtualBox \ metadata.json
Nebojsac
1

Você pode tentar https://github.com/sparkoo/boxitory . É um servidor jar simples. Você o aponta para o diretório em que você possui suas caixas vagrantes e cria uma interface http compatível para vagrantes. Então você simplesmente aponta o seu arquivo vagrant e pronto. Você não precisa manipular manualmente os arquivos json que descrevem suas caixas, adicionando novas versões, provedores etc. Tudo é feito gratuitamente. Basta adicionar um novo arquivo de caixa e o Boxitory o devolve instantaneamente quando solicitado.

Michal Vala
fonte