【问题标题】:Why does `vagrant box add` yield a `bsdtar` error importing a `.box` in Ubuntu?为什么`vagrant box add`在Ubuntu中导入`.box`会产生`bsdtar`错误?
【发布时间】:2013-10-04 14:00:40
【问题描述】:

我在 Ubuntu 12.04.2 LTS 中安装了 vagrant 和 virtual box。 (流浪者版本 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 机器上使用过它并且它工作正常......

【问题讨论】:

  • 这个错误可能是磁盘空间不足造成的。

标签: macos ubuntu vagrant add bsdtar


【解决方案1】:

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

【讨论】:

  • 我如何给它权限?
【解决方案2】:

我有同样的问题要解决这个问题,如果您使用 LAMP,您需要添加来自 http://www.vagrantbox.es/ 的 url 源搜索您的操作系统(Devopera Ubuntu 12.04 LAMP 堆栈)。

sudo vagrant box add laravel/homestead http://devopera.com/node/63/download/ubuntu1204/dobu12-lamp-vagrant.box

【讨论】:

    【解决方案3】:

    我遇到了同样的问题。当您看到 write failed 时,通常表示您的磁盘空间不足。答案是您需要两倍于硬盘上实际文件大小的空间。在打包过程中,Vagrant 需要 2 倍的原始空间,因为它会复制所有文件。

    【讨论】:

      【解决方案4】:

      问题/说明

      我确信我添加的 vagrant box 没有损坏,因为我在 mac 机器上使用过它并且它工作正常......

      通过执行以下操作,我能够在各种场合重现此问题:

      1. 在 macOS 中创建一个 Virtualbox VM(基于 Intel 的 mac 运行任何东西...Mojave、Catalina、Mojave、Big Sur 等...)

      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 文件是使用tar 的GNU 版本创建的。 There are some important differences between bsdtar, GNU tar, and the Linux version libarchive bsdtar.

      这意味着我们不能期望在所有情况下都在一个平台上创建一个.tar 文件,并且能够在没有可以处理该文件的tar 的适当兼容版本的情况下在另一个平台上解压它。该文件没有损坏,只是与 Linux 版本的 bsdtar 预期处理的格式不同。

      人们可能会认为vagrant package 旨在创建一个可移植的.box 文件。然而,由于经典 bsdtarlibarchivebsdtar 和 GNU tar 之间的差异,我们最终遇到了不可移植性问题。虚拟机磁盘文件通常使用稀疏文件实现。 VirtualBox 将稀疏文件用于.vmdk 文件格式,以支持动态增长和缩小来宾 VM 磁盘,同时在主机操作系统上仍然保持相对较小。根据您的版本,bsdtar handles these sparse files differently 比其他版本的tar。 Vagrant 使用bsdtar,但这并不能确保生成的.box 文件在系统之间是兼容的和完全可移植的。 MacOS 附带的 bsdtar 版本与当前在 Ubuntu Linux 上可用的版本不同。

      macOS 大苏尔
      $ 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
      
      Ubuntu Focal Fossa
      $ 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 机器,否则由于 bsdtar 问题,此 .box 文件将无法工作。相反,从$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 源路径和目标路径中,斜线/ 很重要! See this brief rsync tutorial for help using 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 文件...

      另一个选项是using gnu-tar from Homebrew 将文件重新打包为兼容的.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。它们不是运行 VM 所必需的。

      这些文件可以以相同的结构放入 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 上轻松运行它。原因是 Apple 的 boot.efi 具有 macOS 特定的启动固件。从技术上讲,不支持在非 Apple 硬件上运行 macOS(你知道......因为资本主义......??)。鉴于创建硬件 Hackintosh 机器是可能的,我敢肯定有人已经想通了。我还没有找到让这个工作的方法,但也许其他人知道......?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-16
        • 1970-01-01
        • 2023-01-03
        • 2014-12-06
        • 2016-09-27
        • 2017-01-26
        相关资源
        最近更新 更多