Questão Clone manual / recriar disco virtual


Eu estou tentando clonar uma imagem de disco virtual de forma bastante manual. A visão geral da minha metodologia até agora é a seguinte:

  1. Crie uma máquina virtual no VirtualBox com HD de 120 GB (o tamanho do hipervisor e do HDD não importa, incluído principalmente para integridade e consistência com o resto da minha pergunta, por exemplo, tamanhos de partições)
  2. Instale o Ubuntu 12.04.3 na máquina virtual
  3. Feche a máquina virtual
  4. Monte o disco rígido virtual associado à máquina virtual
  5. Extrair arquivos e dados do sistema operacional para armazenar em um diretório
  6. Salve os metadados do disco rígido virtual
  7. Criar disco virtual novo e restaurar partições e inicializar informações de (6)
  8. Restaurar dados de (5) para a partição correta

O problema

Minha VM duplicada não inicializa. O Grub parece copiar e aparece para reconhecer minha partição raiz (com o Ubuntu instalado). Eu posso dar um boot pelo Grub uma vez e pegar uma tela roxa, como se o Ubuntu estivesse prestes a carregar. Então isso pára. Depois disso, eu posso inicializar no Grub, selecione meu sistema operacional, então eu recebo um cursor de linha de comando piscando. Nenhuma entrada é possível. Eu suspeito que há algo que estou perdendo no processo de clonagem (veja abaixo para mais detalhes). Nota: Eu estou usando o grub2, não o legado.

Por que você está fazendo isso?

Como parte de um requisito contratual, preciso armazenar o disco virtual no controle de versão. Ter um enorme binário binário (disco virtual) no controle de versão é uma dor, principalmente para clone (git) / checkout (svn), mas também para diffs. Considerei a compactação para vários arquivos, mas preciso manipular o sistema operacional / dados extraídos em (5) acima. Observe que meu repositório VCS ainda precisa de todas as informações necessárias para construir uma VM completa.

Detalhe

Instruções detalhadas para reproduzir o que descrevi:

  1. Crie uma VM e inicialize o Live CD do Ubuntu
  2. Escolha "Experimente o Ubuntu"
  3. Abra um terminal
  4. Crie uma partição msdos: sudo parted / dev / sda mklabel msdos
  5. Crie um arquivo de troca de 2 GB: sudo parted / dev / sda mkpart primário linux-swap 2048s 4198399s
  6. Use o restante da unidade para a partição raiz: sudo repartido / dev / sda mkpart primário ext4 4198400s 100%
  7. Reinicie a máquina, escolha "Instalar o Ubuntu"
  8. Escolha a opção avançada de particionamento
  9. Clique duas vezes na partição swap, escolha usá-la como swap
  10. Clique duas vezes na partição raiz, escolha formatá-la e use-a para raiz (/) ponto de montagem

Agora, execute o seguinte para clonar o disco:

# Set up some parameters
ORIG_DEV="/dev/nbd0"
ORIG_MNT=$(mktemp -d)
ORIG_IMG="orig.vdi" 
CLONE_DEV="/dev/nbd1"
CLONE_MNT=$(mktemp -d)
CLONE_IMG="clone.vdi"
qemu-img info $ORIG_IMG # save the "virtual size" output (in bytes) in the
                        # VIRT_SIZE variable in the next command
VIRT_SIZE="128849018880"

# Create the clone disk
qemu-img create -f vdi $CLONE_IMG $VIRT_SIZE

# Use qemu to make both disks accessible
modprobe nbd
qemu-nbd -c $ORIG_DEV $ORIG_IMG
qemu-nbd -c $CLONE_DEV $CLONE_IMG

# Set up the clone disk partition table and partitions
parted $CLONE_DEV mklabel msdos
parted $CLONE_DEV mkpart primary linux-swap 2048s 4198399s
parted $CLONE_DEV mkpart primary ext4 4198400s 100%

# Format the clone disk partitions and clone the UUIDs
mkswap $CLONE_DEVp1 -U $(blkid $ORIG_DEVp1 -s UUID -o value)
mkfs.ext4 $CLONE_DEVp2 -U $(blkid $ORIG_DEVp2 -s UUID -o value)

# Mount both disks and copy root from the original to the clone
mount $CLONE_DEVp2 $CLONE_MNT
mount $ORIG_DEVp2 $ORIG_MNT
find $ORIG_MNT -maxdepth 1 -mindepth 1 | xargs -I{} cp -ar {} $CLONE_MNT
umount $ORIG_MNT
umount $CLONE_MNT

# Copy the boot sector and partition table from the original
dd if=$ORIG_DEV of=$CLONE_DEV bs=$((2048*512)) count=1

# Disconnect the disks
qemu-nbd -d $CLONE_DEV
qemu-nbd -d $ORIG_DEV

O que mais você tentou?

  1. grub-install --root-directory = / caminho / para / clone / device / boot / / dev / clone_device. Isso instalou o Grub no dispositivo correto, mas com os detalhes do dispositivo do meu host. A VM não inicializaria.
  2. chroot no disco clone, em seguida, instalar o grub. Encontrei problemas porque devo usar hosts de 64 bits para clonar convidados de 32 bits. Isso parece uma avenida esperançosa para investigar, mas estou preso a como conseguir isso.
  3. Monte o disco virtual, mova todos os arquivos da partição de dados usando mv, zero as partições de dados e swap (dd if=/dev/zero of=/dev/nbd0p2) e comprima o disco virtual (usando VBoxManage modifyhd clone.vdi --compress). O disco começou a se expandir em meu sistema de arquivos host, já que isso estava preenchendo-o com espaço vazio (hah!). eu parei dd quando percebi que isso estava acontecendo, então comprimi a imagem do disco. Ainda estava com mais de 3GB. (Eu não tentei usar o gzip / bzip, vou começar a tentar isso esta noite. Também vou tentar deixar o dd limpar até a conclusão, mas eu prefiro uma solução menos demorada, mesmo que isso funcione) .
  4. e2image. Veja minha outra pergunta: e2image restaurar metadados do sistema de arquivos. Eu não resolvi isso. Note que os passos que eu forneço no Detalhe seção, incluindo criação de partição, formatação e cópia do setor de inicialização, mas antes Eu copio a partição raiz, produzo um arquivo de imagem de tamanho muito semelhante ao criado pela e2image.
  5. Inicializando em outra VM para chorar neste para executar o grub-install. Eu realmente não fiz isso, mas incluí-lo aqui no caso de alguém sugerir isso. Para meus usuários, preciso que a recombinação da máquina virtual seja roteirizável; que impede um processo de configuração envolvido.
  6. Instale o extlinux em vez do Grub. Embora malsucedido, este exercício indica que (eu acho!) O bootloader está carregando com sucesso o disco da minha partição, mas fica preso neste ponto.

Se você chegou até aqui, obrigado já! Quaisquer sugestões para avenidas de investigação, no entanto não detalhadas, serão muito apreciadas. Desde já, obrigado.


7


origem


+1 para a integridade; Eu gostaria de poder ajudar ainda mais - Canadian Luke
e2image man menciona o -r parâmetro em vez de -Q. Você poderia tentar entrar em contato com o criador Theodore Ts'o, que certamente poderia ajudá-lo. - harrymc
Obrigado @CanadianLuke, eu também! @harrymc, eu não tinha pensado em usar e2image -r porque na minha experiência o Windows não faz um trabalho muito bom de armazenar arquivos esparsos, o que significa que um check-out do repositório precisaria de muito espaço se um desenvolvedor quiser usar o Windows. No entanto, minha "experiência" acima mencionada com arquivos esparsos no Windows é muito limitada, eu mal tenho feito isso e certamente parece justificar uma investigação adicional; Muito obrigado pela sugestão, vou dar uma olhada e deixar você saber como é. - mkingston


Respostas:


Eu tenho uma proposta alternativa que omite a necessidade de extrair e recriar o conteúdo do seu disco virtual.

Se você estiver usando o git, você pode trabalhar diretamente no disco virtual montado e ter seu diretório .git em outro lugar. A única coisa é que você provavelmente precisa ter o seu .gitignore (se houver) no diretório raiz da partição raiz no seu disco virtual.

EDITAR:
Para clonagem, você pode usar o mecanismo normal do VirtualBox após a instalação inicial. Sempre que você precisar restaurar uma versão específica, crie outro clone a partir do original, monte-o e faça um checkout do git.
Desde que a versão do grub não seja diferente, é tudo o que você precisa fazer. Se a versão do grub for diferente, você precisará inicializar a VM a partir do seu 12.04.3.iso e fazer uma instalação do grub.

Desta forma, o fluxo de trabalho alternativo é (adicionado novo passo 4, etapa modificada 5):

  1. Crie uma máquina virtual no VirtualBox com HD de 120 GB
  2. Instale o Ubuntu 12.04.3 na máquina virtual
  3. Feche a máquina virtual
  4. Clone máquina virtual, coloque original de lado
  5. Montar disco rígido virtual de oringinal ou primeiro clone (por exemplo, em / media / virtual)
  6. cd / media / virtual
  7. git --git-dir = / algum lugar / outro / virtual.git --work-tree =. nisso
  8. git --git-dir = / algum lugar / outro / virtual.git --work-tree =. adicionar .
  9. git --git-dir = / algum lugar / outro / virtual.git --work-tree =. commit -m "Importação inicial"
  10. ... quaisquer outras tarefas do git ...

Se você não quiser sempre adicionar --git-dir = / algum lugar / outro / virtual.git --work-tree =., há uma pergunta no Stackoverflow que explica como se livrar dela: Posso armazenar a pasta .git fora dos arquivos que eu quero rastrear?

Não exatamente o que você pediu, mas a descrição do seu problema me dá a impressão de que você está mais interessado em fazer o seu trabalho do que na maneira exata de fazê-lo.


4



Ao escrever esta resposta, esqueci de mencionar a clonagem. Eu adicionei isso agora. - Markus N.
Obrigado pela sua resposta. Peço desculpas pelo atraso na resposta. Eu posso estar enganado, mas eu não acho que isso resolve o meu problema. Ele armazenará apenas arquivos OS / data no controle de versão, não no próprio VHD (corrija-me se estiver enganado). Eu estava tentando reconstruir o VHD porque deve estar no controle de versão bem como o sistema operacional e dados. Como um "shell" contendo informações básicas de partição e o setor de inicialização, é um tamanho gerenciável, mas uma vez que os metadados ext4 e (/ ou) arquivos OS estejam nele, é muito grande. +1 para uma ideia inteligente em qualquer caso, obrigado novamente. - mkingston
Sim, isso mesmo ... só armazena arquivos. Talvez eu tenha entendido mal, mas eu pensei que é isso que você quer, a fim de evitar manipular todo o disco virtual como blob. - Markus N.
O erro de comunicação é meu. Dentro do repositório VCS, eu preciso de todas as informações disponíveis para criar um OVA funcional. Idealmente, isso incluirá uma cópia do OS / data (como arquivos individuais), um VHD "shell" muito pequeno e um script para recombinar o VHD e os dados do SO / em uma VM funcional. Eu acho que a minha pergunta tem a informação relevante para deduzir este requisito, no entanto, é menos explícito do que poderia ser. Vou atualizar a pergunta para refletir isso. Obrigado novamente por uma idéia inteligente e pelo esforço que você dedicou a responder à pergunta, eu realmente agradeço. - mkingston
Eu lhe concedi a recompensa, não explicitamente porque sua resposta resolve o meu problema (eu não lhe dei a resposta!), Mas porque você recebeu metade dela de qualquer maneira, e apenas como um agradecimento pelo seu pensamento inteligente e sua sugestão. . - mkingston


Talvez você já tenha tentado isso, talvez você não tenha feito isso. Mas você já tentou reinstalar o Grub2 de um Live CD dentro da "VM duplicada"? Tudo o que li parecia que você estava instalando o Grub2 da máquina host.

  • Quando chegar ao ponto em que você tem uma VM duplicada que não inicializa
  • Montar um CD ao vivo, como o disco de instalação do Ubuntu para a VM
  • Inicialize a VM e pressione F12 para inicializar a partir do Live CD
  • Reinstale o grub na linha de comando (dentro da VM)

Se você quiser automatizar o processo, você pode usar VBoxManage para montar um Ubuntu Live CD personalizado que execute um script para reinstalar o Grub2 na inicialização.

VBoxManage storageattach "io" --storagectl "IDE Controller" \
--port 1 --device 0 --type dvddrive --medium debian-6.0.2.1-i386-CD-1.iso

Exemplo de fonte

Esperemos que não muito desatualizado, há uma guia em help.ubuntu.com para personalizar o Live CDe um Stack Exchange pergunta / resposta em askubuntu.com envolvendo a adição de um script de inicialização a um Live CD personalizado


3



Eu absolutamente espero que funcione; mas eu preciso ser capaz de executar a solução com um script (ver ponto 5 em What else have you tried?), de modo que quando um usuário transfere o repositório para sua máquina (git clone ou svn checkout) eles podem facilmente construir a vm a partir dos arquivos constituintes. Eu suspeito que seria possível escrever isso, mas provavelmente exigiria mais trabalho do que prosseguir com alguns dos meus esforços atuais. Se você acha que está incorreto, eu adoraria saber. Muito obrigado pela sua contribuição em qualquer caso. - mkingston
Eu devo ter entendido mal o que você quis dizer com "outra VM". Algo que vem à mente, porém, é usar o VBoxManage comando para montar o Live CD e criar um live CD personalizado que execute um script na inicialização para reinstalar o Grub2. O desafio óbvio aqui é o Live CD personalizado, mas eu tenho vários tutoriais e ferramentas on-line que permitem que você crie CDs personalizados ao vivo com muita facilidade. Costumava haver uma ferramenta on-line que permitia criar um CD do OpenSUSE Live, permitindo que você selecionasse os pacotes desejados e carregasse um script de inicialização. - Drew Chapin
Se eu tiver tempo, vou dar uma olhada mais tarde hoje e fazer uma sugestão sobre como fazer o Live CD personalizado. - Drew Chapin
Só queria mencionar que vi sua atualização e seus comentários e ainda não tive tempo de tomar nenhuma providência. Eu farei alguma leitura / experimentação assim que puder. Obrigado por isso. - mkingston
Infelizmente, eu não consegui me aproximar disso até hoje. Acontece que, na verdade, não consigo instalar o grub com sucesso a partir do live CD. Eu acho que é um problema com alguns dos metadados do sistema de arquivos. Obrigado pela sua sugestão de qualquer maneira. - mkingston


Parece que você não teve muita ideia sobre o ponto de montagem do Ubuntu? Você considerou separar a VM em várias partições?

no link abaixo:

http://www.easy-ubuntu-linux.com/ubuntu-installation-606-12.html

uma instalação básica é apenas 4G, + 1G para SWAP, + 2G para / tmp, então você pode criar uma partição separada para / usr, / var, / home, / opt

basta fazer 1G para cada um deles no começo, você pode crescer dinamicamente com caixa virtual quando necessário

referência:

http://www.ubuntugeek.com/linux-or-ubuntu-directory-structure.html

Depois, você pode determinar o seu escopo SVC, apenas os arquivos de usuário ou registros ou o sistema operacional? para o qual você pode ter muito menos dor na versão.

na maioria dos casos, você pode simplesmente tornar o /, / usr e / opt read-only e unchangeble após a configuração e, assim, reduzir a dor de cabeça da versão geral.

mas uma coisa é lembrar, como seu contrato diz que você precisa armazenar seu disco virtual, eu acho que armazenar dados extraídos do disco virtual não corresponde ao seu contrato. Mas armazenar várias correspondências de disco virtual. É por isso que eu sugiro que você crie um ponto de montagem e faça parte deles apenas para leitura (então, há apenas uma versão deles).

Só mais uma nota, lembre-se de verificar se você pode desligar a data de acesso ao arquivo do ponto de montagem? (algumas configurações de segurança muito altas não permitem que isso seja desativado, computação forense)

Desde que a data de acesso é realmente gravada no disco se a data de acesso estiver ativada. Portanto, um disco virtual / ponto de montagem que é acessado no dia 2 é, na verdade, uma versão diferente com o disco virtual / ponto de montagem no dia 1, mesmo que nada seja gravado.

referência (sem tempo de acesso):

https://askubuntu.com/questions/59179/how-do-i-make-noatime-mounts-default


3



Nesse cenário, eu preferiria sugerir vários discos virtuais em vez de um disco virtual com várias partições. Caso contrário, você não poderá separá-los da exibição de um VCS. - Markus N.
Isso por si só não resolve o problema da transferência de arquivos grandes durante o checkout. No entanto, usar vários VHDs contendo diferentes partições pode ser. Isso pode ser um pouco dependente dos meus requisitos de lançamento (que eu ainda não estou claro). Obrigado e +1 pela sua sugestão. - mkingston


Mais um pensamento sobre isso, vou realmente olhar para /etc/fstab. Como suas partições são definidas lá? Se eles são definidos por seus UUID, então talvez haja uma chance de que essa informação não seja replicada com o processo de clonagem. Você pode querer torná-los definidos por nomes de dispositivos, como /dev/sda0 por exemplo.

Um outro ponto, porque não correr git de dentro a máquina virtual em si? Eu posso pensar em ter um diretório no host tendo seu repositório. A máquina virtual pode então montar esse diretório e executar git na própria máquina virtual.


0



Obrigado pela sua sugestão. Eu de fato clonei os UUIDs e confirmei que fstab faz referência a eles em vez de nomes de dispositivos. Infelizmente, o próprio VHD precisa estar no repositório VCS, a menos que eu tenha entendido mal sua resposta, executar o git de dentro da VM não atenua o problema que surge do clone / checkout / diff de arquivos binários grandes no repositório. - mkingston