为什么在Ubuntu中使用`vagrant box add`导入`.box`时会出现`bsdtar`错误?

5

我在Ubuntu 12.04.2 LTS中安装了Vagrant和VirtualBox(版本1.2.1)。我已经下载了vagrant box并执行了vagrant box add命令。但是我遇到了以下错误:

*vagrant box add base64 package.box

Downloading or copying the box...
Extracting box...te: 147M/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):
x ./box-disk1.vmdk: Write failed
x ./box.ovf: Write failed
x ./Vagrantfile: Write failed
bsdtar: Error exit delayed from previous errors.*

我尝试使用其他版本的Vagrant(如1.2.2、1.0.1、1.3.0)重复了相同的步骤,但是出现了相同的错误。我确定我添加的Vagrant box没有损坏,因为我在Mac电脑上使用过它,而且一切正常...


此错误可能是由于磁盘空间不足引起的。 - Ryne Everett
4个回答

2
似乎.box文件没有损坏,但是你的Vagrant需要写入权限。我认为你应该检查Vagrant的安装。

我该如何给它权限? - Aryeh Armon

1
我有同样的问题,要解决这个问题,你需要添加http://www.vagrantbox.es/中与你的操作系统(Devopera Ubuntu 12.04 LAMP stack)相匹配的url源。如果你使用LAMP,请搜索相关内容。
sudo vagrant box add laravel/homestead http://devopera.com/node/63/download/ubuntu1204/dobu12-lamp-vagrant.box

1
我遇到了同样的问题。当你看到“写入失败”时,通常意味着你的磁盘空间已经用尽。答案是你需要比实际文件大小大两倍的硬盘空间。在打包过程中,Vagrant 需要原始空间的 2 倍,因为它会复制所有文件。

0

问题 / 解释

我确定我要添加的虚拟机镜像没有损坏,因为我在 Mac 电脑上使用同样的虚拟机镜像时它能正常工作...

通过以下步骤,我已经多次复现了这个问题:

  1. 在 macOS(任何基于 Intel 的 Mac,如 Mojave、Catalina、Mojave、Big Sur 等)中创建 Virtualbox VM。

  2. vagrant package --base $VIRTUALBOX_VM_NAME_HERE --output test.box

  3. .box 文件传输到 Ubuntu。

  4. vagrant box add --provider virtualbox --name $VAGRANT_BOX_NAME_HERE test.box

  5. 解压错误:

     The box failed to unpackage properly. Please verify that the box
     file you're trying to add is not corrupted and that enough disk space
     is available and then try again.
     The output from attempting to unpackage (if any):
    
     x ./include/
     x ./include/README.md
     x ./include/_Vagrantfile
     x ./include/LICENSE
     x ./metadata.json
     x ./box.ovf
     x ./Vagrantfile
     x ./info.json
     x ./box-disk001.vmdk: gzip decompression failed
     bsdtar: Error exit delayed from previous errors.
    

答案在错误消息背后隐藏的上下文中:

bsdtar: Error exit delayed from previous errors.*

请注意,这个vagrant box add ...是在Ubuntu上运行的,而且正在尝试使用bsdtar来解压缩,而不是通常的tar命令。该.box文件是在macOS上创建的,并使用其自己的版本的bsdtar进行压缩。通常,在Linux上本地的.tar文件是使用GNU版本的tar创建的。bsdtar、GNU tar和Linux版本libarchive bsdtar之间有一些重要的区别

这意味着我们不能指望在一个平台上创建一个 .tar 文件,并且能够在另一个平台上解压缩它,除非有适当兼容的版本的 tar 可以处理该文件。该文件并非损坏,只是与 Linux 版本的 bsdtar 期望处理的格式不同。
有人可能会认为vagrant package旨在创建可移植的.box文件。然而,由于经典bsdtarlibarchive bsdtar和GNU tar之间的差异,我们遇到了一个不可移植的问题。虚拟机磁盘文件通常使用稀疏文件实现。VirtualBox使用稀疏文件格式.vmdk来支持在Guest VM动态增长和缩小磁盘的同时,在主机操作系统上仍保持相对较小。根据您的版本,bsdtar处理这些稀疏文件的方式与其他版本的tar不同。Vagrant使用bsdtar,但这并不能确保生成的.box文件在各个系统上都是兼容和完全可移植的。MacOS附带的bsdtar版本与Ubuntu Linux当前可用的版本不同。
macOS Big Sur
$ sw_vers
ProductName:    macOS
ProductVersion: 11.6.1
BuildVersion:   20G224
$ ls -l /usr/bin/tar
lrwxr-xr-x  1 root  wheel  6 Jan  1  2020 /usr/bin/tar -> bsdtar
$ bsdtar --version
bsdtar 3.3.2 - libarchive 3.3.2 zlib/1.2.11 liblzma/5.0.5 bz2lib/1.0.6
乌班图弗科尔福萨
$ lsb_release -a
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.3 LTS
Release:        20.04
Codename:       focal
$ tar --version
tar (GNU tar) 1.30
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by John Gilmore and Jay Fenlason.
$ apt-cache show libarchive-tools | grep 'Description-en'
Description-en: FreeBSD implementations of 'tar' and 'cpio' and other archive tools
$ sudo apt-get install libarchive-tools
$ bsdtar --version
bsdtar 3.4.0 - libarchive 3.4.0 zlib/1.2.11 liblzma/5.2.4 bz2lib/1.0.8 liblz4/1.9.2 libzstd/1.4.4

解决方案

我发现一个解决此问题的方法是避免在 macOS 上使用由 vagrant package 创建的 .box 文件。除非您还要导入到另一台 macOS 机器,否则这个 .box 文件将无法工作,因为存在 bsdtar 问题。相反,从 $HOME/.vagrant.d/boxes/$VAGRANT_BOX_NAME_HERE 中单独复制文件。这些是裸的 VirtualBox .ovf.vmdk 文件,应该与 Linux 上的 VirtualBox 兼容。一旦这些文件通过您喜欢的任何方法安全地传输到 Linux,它们就可以被加载到那里的 VirtualBox 中,或者通过 vagrant 命令直接从 .vagrant.d/boxes 使用。

您有几种选项来传输文件。我建议使用 rsync 来避免 tarbsdtar 的问题。

# From macOS machine
rsync --progress -av ~/.vagrant.d/boxes/someuser-VAGRANTSLASH-vagrant-box-example-name  target-machine.local:~/.vagrant.d/boxes/
# Or... from Linux machine side
rsync --progress -av your-mbp.local:~/.vagrant.d/boxes/someuser-VAGRANTSLASH-vagrant-box-example-name  ~/.vagrant.d/boxes/

注意:/斜杠在rsync源路径和目标路径中很重要!查看这个简短的rsync教程以获取使用rsync的帮助

文件传输完成后,请确保检查它们是否相同。我使用shasum -a 256为文件生成SHA256哈希值。两边的哈希值应该匹配。

# Check on both machines separately...
cd  ~/.vagrant.d/boxes/someuser-VAGRANTSLASH-vagrant-box-example-name/0/virtualbox/
shasum -a 256 box-disk001.vmdk
# Or... use `shasum -c -` and SSH for a one-liner:
# Prints "OK" and exit status 0 if checksums match
( cd  ~/.vagrant.d/boxes/someuser-VAGRANTSLASH-vagrant-box-example-name/0/virtualbox/  && shasum -a 256 box-disk001.vmdk )  | ssh  exampleuser@your-mbp.local '( cd ~/.vagrant.d/boxes/someuser-VAGRANTSLASH-vagrant-box-example-name/0/virtualbox/ && shasum -a 256 -c - )'

如果你真的想尝试使用[bsd]tar.box文件...

另一个选择是使用Homebrew中的gnu-tar将文件重新打包为兼容的.tar存档。然后将其复制并解压缩到.vagrant.d/boxes中。我尝试过这种方法,发现在Linux端仍会产生不同的.vmdk磁盘文件(可以使用sha256sum或perl的shasum -a 256在两台机器上检查)。

另一种选择是在Ubuntu机器上使用libarchive-tools软件包中的bsdtar。我尝试过这种方法,并能够重现来自vagrant box add的相同错误。

# View .box file contents
bsdtar -v -t  -f /path/to/Vagrant_Box/example.box
# Try to extract
mkdir ~/.vagrant.d/boxes/someuser-VAGRANTSLASH-vagrant-box-example-name
cd ~/.vagrant.d/boxes/someuser-VAGRANTSLASH-vagrant-box-example-name
bsdtar -v -x  -f /path/to/Vagrant_Box/example.box
x ./include/
x ./include/README.md
x ./include/_Vagrantfile
x ./include/LICENSE
x ./metadata.json
x ./box.ovf
x ./Vagrantfile
x ./info.json
x ./box-disk001.vmdk: gzip decompression failed
bsdtar: Error exit delayed from previous errors.

因此,最好避免在这些平台上使用tarbsdtar,因为它们对box-disk001.vmdk稀疏文件的处理方式不兼容。

Vagrant Box格式内容

正如我们在上面看到的那样,一个示例.box解压缩结构可能是以下内容:

/Users/exampleuser/.vagrant.d/boxes/someuser-VAGRANTSLASH-vagrant-box-example-name/
└── 0
    └── virtualbox
        ├── Vagrantfile
        ├── box-disk001.vmdk
        ├── box.ovf
        ├── include
        │   ├── LICENSE
        │   ├── README.md
        │   └── _Vagrantfile
        ├── info.json
        └── metadata.json

3 directories, 8 files

注意:info.json文件和include目录下的任何内容(例如:README.md_Vagrantfile)都是可选的。这些可以通过vagrant package选项添加:--vagrantfile--info--include。它们不是运行虚拟机所必需的。

这些文件可以按照相同的结构放入Ubuntu机器的~/.vagrant.d/boxes/文件夹中。确保盒子目录名称与您打算使用的盒子名称匹配(例如:目录someuser-VAGRANTSLASH-vagrant-box-example-name = 盒子名称someuser/vagrant-box-example-name)。

设置一个Vagrantfile来使用盒子名称运行该盒子,然后像往常一样运行vagrant up

示例:

Vagrant.configure("2") do |c|
  c.berkshelf.enabled = false if Vagrant.has_plugin?("vagrant-berkshelf")
  c.vm.box = "someuser/vagrant-box-example-name"
  c.vm.hostname = "default-vagrant-box-example-name.vagrantup.com"
  c.vm.boot_timeout = 1200
  c.vm.synced_folder ".", "/vagrant", disabled: true
  c.vm.provider :virtualbox do |p|
    p.name = "vagrant-box-example-name"
    p.customize ["modifyvm", :id, "--audio", "none"]
  end
end

macOS虚拟机笔记

如果涉及的.box文件是一个macOS虚拟机,那么你可能仍然不能轻松地在Linux上运行它。原因是苹果的boot.efi具有macOS特定的引导固件。从技术上讲,在非苹果硬件上运行macOS是不受支持的(你知道的...因为资本主义...)。我相信某个地方肯定有人已经想出了解决方法,因为创建硬件Hackintosh机器是可能的。我还没有找到一种方法来使其工作,但也许其他人知道...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接