Merge branch 'main' into kc.docs-install-updates

This commit is contained in:
Ashlee Boyer 2023-01-20 17:45:12 -05:00
commit 7acb94cac8
185 changed files with 7220 additions and 11505 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,33 @@
#!/usr/bin/env bash
success="✅"
csource="${BASH_SOURCE[0]}"
while [ -h "$csource" ] ; do csource="$(readlink "$csource")"; done
root="$( cd -P "$( dirname "$csource" )/../" && pwd )"
. "${root}/.ci/init.sh"
pushd "${root}" > "${output}"
pushd "${root}"
echo -n "Building RubyGem... "
# Build our gem
wrap gem build *.gemspec \
wrap gem build ./*.gemspec \
"Failed to build Vagrant RubyGem"
echo "${success}"
# Get the path of our new gem
g=(vagrant*.gem)
gem=$(printf "%s" "${g}")
gem=$(printf "%s" "${g[0]}")
# Store the gem asset
wrap aws s3 cp "${gem}" "${ASSETS_PRIVATE_BUCKET}/${repository}/vagrant-main.gem" \
"Failed to store Vagrant RubyGem main build"
# Create folder to store artifacts
wrap mkdir -p "generated-artifacts" \
"Failed to create artifiact directory"
wrap mv "${gem}" ./generated-artifacts \
"Failed to move Vagrant RubyGem"
# Install submodules
wrap git submodule update --init --recursive \
@ -26,6 +35,8 @@ wrap git submodule update --init --recursive \
# Build our binaries
echo -n "Building vagrant-go linux amd64... "
# Build linux amd64 binary
wrap make bin/linux \
"Failed to build the Vagrant go linux amd64 binary"
@ -38,9 +49,12 @@ wrap mv vagrant vagrant-go_linux_amd64 \
wrap zip vagrant-go_linux_amd64 vagrant-go_linux_amd64 \
"Failed to compress go linux amd64 binary"
# Store the binary asset
wrap aws s3 cp vagrant-go_linux_amd64.zip "${ASSETS_PRIVATE_BUCKET}/${repository}/vagrant-go_main_linux_amd64.zip" \
"Failed to store Vagrant Go linux amd64 main build"
# Move the binary asset
wrap mv vagrant-go_linux_amd64.zip ./generated-artifacts \
"Failed to move Vagrant Go linux amd64 build"
echo "${success}"
echo -n "Building vagrant-go linux 386... "
# Build linux 386 binary
wrap make bin/linux-386 \
@ -54,9 +68,12 @@ wrap mv vagrant vagrant-go_linux_386 \
wrap zip vagrant-go_linux_386 vagrant-go_linux_386 \
"Failed to compress go linux 386 binary"
# Store the binary asset
wrap aws s3 cp vagrant-go_linux_386.zip "${ASSETS_PRIVATE_BUCKET}/${repository}/vagrant-go_main_linux_386.zip" \
"Failed to store Vagrant Go linux 386 main build"
# Move the binary asset
wrap mv vagrant-go_linux_386.zip ./generated-artifacts \
"Failed to move Vagrant Go linux 386 build"
echo "${success}"
echo -n "Building vagrant-go darwin amd64... "
# Build darwin binary
wrap make bin/darwin \
@ -70,6 +87,14 @@ wrap mv vagrant vagrant-go_darwin_amd64 \
wrap zip vagrant-go_darwin_amd64 vagrant-go_darwin_amd64 \
"Failed to compress go darwin amd64 binary"
# Store the binary asset
wrap aws s3 cp vagrant-go_darwin_amd64.zip "${ASSETS_PRIVATE_BUCKET}/${repository}/vagrant-go_main_darwin_amd64.zip" \
"Failed to store Vagrant Go darwin amd64 main build"
# Move the binary asset
wrap mv vagrant-go_darwin_amd64.zip ./generated-artifacts \
"Failed to move Vagrant Go darwin amd64 build"
echo "${success}"
echo -n "Storing artifacts... "
# Store the artifacts for the builders
draft_release "${ident_ref}" ./generated-artifacts
echo "${success}"

View File

@ -1,86 +1,23 @@
#!/usr/bin/env bash
# shellcheck disable=SC1091
echo "🤖 Loading VagrantCI 🤖"
ldir="$(realpath ./.ci-utility-files)"
# Disable IMDS lookup
export AWS_EC2_METADATA_DISABLED=true
# If utility files have not yet been pulled, fetch them
if [ ! -e "${ldir}/.complete" ]; then
# Validate that we have the AWS CLI available
if ! command -v aws > /dev/null 2>&1; then
echo "⚠ ERROR: Missing required aws executable ⚠"
exit 1
fi
# Validate that we have the jq tool available
if ! command -v jq > /dev/null 2>&1; then
echo "⚠ ERROR: Missing required jq executable ⚠"
exit 1
fi
# If we have a role defined, assume it so we can get access to files
if [ "${AWS_ASSUME_ROLE_ARN}" != "" ] && [ "${AWS_SESSION_TOKEN}" = "" ]; then
if output="$(aws sts assume-role --role-arn "${AWS_ASSUME_ROLE_ARN}" --role-session-name "CI-initializer")"; then
export CORE_AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}"
export CORE_AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}"
id="$(printf '%s' "${output}" | jq -r .Credentials.AccessKeyId)" || failed=1
key="$(printf '%s' "${output}" | jq -r .Credentials.SecretAccessKey)" || failed=1
token="$(printf '%s' "${output}" | jq -r .Credentials.SessionToken)" || failed=1
expire="$(printf '%s' "${output}" | jq -r .Credentials.Expiration)" || failed=1
if [ "${failed}" = "1" ]; then
echo "🛑 ERROR: Failed to extract role credentials 🛑"
exit 1
fi
unset output
export AWS_ACCESS_KEY_ID="${id}"
export AWS_SECRET_ACCESS_KEY="${key}"
export AWS_SESSION_TOKEN="${token}"
export AWS_SESSION_EXPIRATION="${expire}"
else
echo "⛔ ERROR: Failed to assume configured AWS role ⛔"
exit 1
fi
fi
# Create a local directory to stash our stuff in
if ! mkdir -p "${ldir}"; then
echo "⛔ ERROR: Failed to create utility file directory ⛔"
exit 1
fi
# Jump into local directory and grab files
if ! pushd "${ldir}"; then
echo "⁉ ERROR: Unexpected error, failed to relocate to expected directory ⁉"
exit 1
fi
if ! aws s3 sync "${VAGRANT_CI_LOADER_BUCKET}/ci-files/" ./; then
echo "🛑 ERROR: Failed to retrieve utility files 🛑"
exit 1
fi
if ! chmod a+x ./*; then
echo "⛔ ERROR: Failed to set permissions on CI files ⛔"
exit 1
fi
# Mark that we have pulled files
touch .complete || echo "WARNING: Failed to mark CI files as fetched"
# Time to load and configure
if ! popd; then
echo "⁉ ERROR: Unexpected error, failed to relocate to expected directory ⁉"
exit 1
fi
csource="${BASH_SOURCE[0]}"
while [ -h "$csource" ] ; do csource="$(readlink "$csource")"; done
if ! root="$( cd -P "$( dirname "$csource" )/../" && pwd )"; then
echo "⛔ ERROR: Failed to determine root local directory ⛔"
exit 1
fi
source "${ldir}/common.sh"
export PATH="${PATH}:${ldir}"
export root
export ci_bin_dir="${root}/.ci/.ci-utility-files"
if ! source "${ci_bin_dir}/common.sh"; then
echo "⛔ ERROR: Failed to source Vagrant CI common file ⛔"
exit 1
fi
export PATH="${PATH}:${ci_bin_dir}"
# And we are done!
echo "🎉 VagrantCI Loaded! 🎉"

View File

@ -1,7 +1,5 @@
#!/usr/bin/env bash
ghr_version="0.13.0"
# NOTE: This release will generate a new release on the installers
# repository which in turn triggers a full package build
target_owner="hashicorp"
@ -13,15 +11,10 @@ root="$( cd -P "$( dirname "$csource" )/../" && pwd )"
. "${root}/.ci/init.sh"
pushd "${root}" > "${output}" 2>&1
pushd "${root}"
# Install ghr
wrap curl -Lso /tmp/ghr.tgz "https://github.com/tcnksm/ghr/releases/download/v${ghr_version}/ghr_v${ghr_version}_linux_amd64.tar.gz" \
"Failed to download ghr utility"
wrap tar -C /tmp/ -xf /tmp/ghr.tgz \
"Failed to unpack ghr archive"
wrap mv "/tmp/ghr_v${ghr_version}_linux_amd64/ghr" "${root}/.ci/" \
"Failed to install ghr utility"
install_ghr
# Build our gem
wrap gem build ./*.gemspec \
@ -29,7 +22,7 @@ wrap gem build ./*.gemspec \
# Get the path of our new gem
g=(vagrant*.gem)
gem=$(printf "%s" "${g}")
gem=$(printf "%s" "${g[0]}")
# Determine the version of the release
vagrant_version="$(gem specification "${gem}" version)"
@ -91,16 +84,17 @@ repo_owner="${target_owner}"
repo_name="${target_repository}"
full_sha="main"
# Use the hashibot token since we are creating the (pre)release
# in a different repository.
export GITHUB_TOKEN="${HASHIBOT_TOKEN}"
if [ "${tag}" = "" ]; then
if [ -z "${tag}" ]; then
echo "Generating Vagrant RubyGem pre-release... "
version="v${vagrant_version}+${short_sha}"
prerelease "${version}" ./release-assets
else
# Validate this is a proper release version
valid_release_version "${vagrant_version}"
if [ $? -ne 0 ]; then
if ! valid_release_version "${vagrant_version}"; then
fail "Invalid version format for Vagrant release: ${vagrant_version}"
fi

View File

@ -21,6 +21,7 @@ To ensure that the Vagrant community remains an open and safe space for everyone
3. Unless it is critical, the issue is left for a period of time, giving outside contributors a chance to address the issue. Later, the issue may be assigned to a Vagrant collaborator and planned for a specific release [milestone](https://github.com/hashicorp/vagrant/milestones)
4. The issue is addressed in a pull request or commit. The issue will be referenced in the commit message so that the code that fixes it is clearly linked.
5. The issue is closed. Sometimes, valid issues will be closed to keep the issue tracker clean. The issue is still indexed and available for future viewers, or can be re-opened if necessary.
6. The issue is locked. After about 30 days the issue will be locked. This is done to keep issue activity in open issues and encourge users to open a new issue if an old issue is being encountered again.
## Pull Requests

View File

@ -1,7 +1,7 @@
---
name: Bug Report
about: Let us know about an unexpected error, a crash, or an incorrect behavior.
labels: "bug"
labels: "waiting-intake"
---
<!--

View File

@ -2,7 +2,7 @@
name: Vagrant Feature request
about: Suggest an idea or enhancement for Vagrant
title: 'Enhancement Request: Your description here'
labels: 'enhancement'
labels: ['enhancement', 'waiting-intake']
assignees: ''
---

View File

@ -6,18 +6,21 @@ on:
- 'CHANGELOG.md'
- 'website/**'
permissions:
contents: write
jobs:
build-gem:
if: github.repository == 'hashicorp/vagrant'
name: Build Vagrant RubyGem
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- name: Code Checkout
uses: actions/checkout@v1
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '2.7'
ruby-version: '3.1'
- name: Setup Go
uses: actions/setup-go@v3
with:
@ -26,19 +29,5 @@ jobs:
run: ./.ci/build.sh
working-directory: ${{github.workspace}}
env:
ASSETS_LONGTERM_PREFIX: elt
ASSETS_PRIVATE_BUCKET: ${{ secrets.ASSETS_PRIVATE_BUCKET }}
ASSETS_PRIVATE_LONGTERM: ${{ secrets.ASSETS_PRIVATE_LONGTERM }}
ASSETS_PRIVATE_SHORTTERM: ${{ secrets.ASSETS_PRIVATE_SHORTTERM }}
ASSETS_PUBLIC_BUCKET: ${{ secrets.ASSETS_PUBLIC_BUCKET }}
ASSETS_PUBLIC_LONGTERM: ${{ secrets.ASSETS_PUBLIC_LONGTERM }}
ASSETS_PUBLIC_SHORTTERM: ${{ secrets.ASSETS_PUBLIC_SHORTTERM }}
ASSETS_SHORTTERM_PREFIX: est
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ASSUME_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
HASHIBOT_EMAIL: ${{ secrets.HASHIBOT_EMAIL }}
HASHIBOT_TOKEN: ${{ secrets.HASHIBOT_TOKEN }}
HASHIBOT_USERNAME: ${{ secrets.HASHIBOT_USERNAME }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
VAGRANT_CI_LOADER_BUCKET: ${{ secrets.VAGRANT_CI_LOADER_BUCKET }}

View File

@ -0,0 +1,17 @@
name: Legacy Link Format Checker
on:
push:
paths:
- 'website/content/**/*.mdx'
- 'website/data/*-nav-data.json'
jobs:
check-links:
uses: hashicorp/dev-portal/.github/workflows/docs-content-check-legacy-links-format.yml@d7c2fceac2dc41e3f857f1ce7c344141fd6a13dd
with:
repo-owner: 'hashicorp'
repo-name: 'vagrant'
commit-sha: ${{ github.sha }}
mdx-directory: 'website/content'
nav-data-directory: 'website/data'

View File

@ -7,25 +7,17 @@ on:
jobs:
sync-acceptance:
if: github.repository == 'hashicorp/vagrant'
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- name: Code Checkout
uses: actions/checkout@v2
with:
persist-credentials: false
fetch-depth: 0
- name: Set Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '2.6'
- name: Sync Acceptance Testing Repository
run: ./.ci/sync.sh
working-directory: ${{github.workspace}}
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ASSUME_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
HASHIBOT_TOKEN: ${{ secrets.HASHIBOT_TOKEN }}
HASHIBOT_USERNAME: ${{ secrets.HASHIBOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
VAGRANT_CI_LOADER_BUCKET: ${{ secrets.VAGRANT_CI_LOADER_BUCKET }}

View File

@ -15,15 +15,15 @@ on:
jobs:
vagrant-spec-tests:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
strategy:
matrix:
go: ['^1.16']
ruby: ['2.7']
ruby: ['3.1']
name: Vagrant acceptance tests
steps:
- name: Code Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: 'recursive'
# Also fetch all tags, since we need our version number in the build
@ -37,10 +37,7 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby}}
- name: Setup ruby vagrant
run: |
gem install --no-document bundler
bundle install
bundler-cache: true
- name: Build Vagrant
run: |
git config --global url."https://${HASHIBOT_USERNAME}:${HASHIBOT_TOKEN}@github.com".insteadOf "https://github.com"

View File

@ -22,15 +22,15 @@ on:
jobs:
unit-tests-go:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
strategy:
matrix:
go: ['^1.16']
ruby: ['2.7', '3.0']
ruby: ['3.0', '3.1']
name: Vagrant unit tests on Go
steps:
- name: Code Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Go
uses: actions/setup-go@v3
with:
@ -39,10 +39,7 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby}}
- name: Setup ruby vagrant
run: |
gem install --no-document bundler
bundle install
bundler-cache: true
- name: Get dependencies
run: |
git config --global url."https://${HASHIBOT_USERNAME}:${HASHIBOT_TOKEN}@github.com".insteadOf "https://github.com"

View File

@ -7,17 +7,12 @@ on:
jobs:
lock:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: dessant/lock-threads@v2
with:
github-token: ${{ github.token }}
issue-lock-comment: >
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
issue-lock-inactive-days: '30'
pr-lock-comment: >
I'm going to lock this pull request because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
pr-lock-inactive-days: '30'

View File

@ -9,15 +9,16 @@ on:
jobs:
trigger-release:
if: github.repository == 'hashicorp/vagrant'
name: Trigger Installers Build
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- name: Code Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '2.7'
ruby-version: '3.1'
- name: Setup Go
uses: actions/setup-go@v3
with:
@ -26,19 +27,7 @@ jobs:
run: ./.ci/release.sh
working-directory: ${{github.workspace}}
env:
ASSETS_LONGTERM_PREFIX: elt
ASSETS_PRIVATE_BUCKET: est
ASSETS_PRIVATE_LONGTERM: ${{ secrets.ASSETS_PRIVATE_LONGTERM }}
ASSETS_PRIVATE_SHORTTERM: ${{ secrets.ASSETS_PRIVATE_SHORTTERM }}
ASSETS_PUBLIC_BUCKET: ${{ secrets.ASSETS_PUBLIC_BUCKET }}
ASSETS_PUBLIC_LONGTERM: ${{ secrets.ASSETS_PUBLIC_LONGTERM }}
ASSETS_PUBLIC_SHORTTERM: ${{ secrets.ASSETS_PUBLIC_SHORTTERM }}
ASSETS_SHORTTERM_PREFIX: ${{ secrets.ASSETS_SHORTTERM_PREFIX }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ASSUME_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
HASHIBOT_EMAIL: ${{ secrets.HASHIBOT_EMAIL }}
HASHIBOT_TOKEN: ${{ secrets.HASHIBOT_TOKEN }}
HASHIBOT_USERNAME: ${{ secrets.HASHIBOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
VAGRANT_CI_LOADER_BUCKET: ${{ secrets.VAGRANT_CI_LOADER_BUCKET }}

View File

@ -8,22 +8,35 @@ on:
- cron: '0 5 * * 1-5'
jobs:
slack-vars:
if: github.repository == 'hashicorp/vagrant-builders'
name: Populate vars
runs-on: ['self-hosted', 'ondemand', 'linux', 'type=t3.nano']
uses: ./.github/workflows/slack-vars.yml
packet-vars:
if: github.repository == 'hashicorp/vagrant-builders'
name: Populate vars
runs-on: ['self-hosted', 'ondemand', 'linux', 'type=t3.nano']
uses: ./.github/workflows/packet-vars.yml
setup-packet:
if: github.repository == 'hashicorp/vagrant-acceptance'
runs-on: self-hosted
runs-on: ['self-hosted', 'ondemand', 'linux', 'type=t3.nano']
name: Build Packet Instance
steps:
- name: Code Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Create packet instance
run: ./.ci/spec/create-packet.sh
working-directory: ${{github.workspace}}
env:
VAGRANT_CI_LOADER_BUCKET: ${{ secrets.VAGRANT_CI_LOADER_BUCKET }}
PACKET_EXEC_TOKEN: ${{ needs.packet-vars.outputs.PACKET_EXEC_TOKEN }}
PACKET_EXEC_PROJECT_ID: ${{ needs.packet-vars.outputs.PACKET_EXEC_PROJECT_ID }}
PACKET_SSH_KEY_CONTENT: ${{ needs.packet-vars.outputs.PACKET_SSH_KEY_CONTENT }}
PKT_SECRET_PHRASE: ${{ needs.packaging-vars.outputs.ASSETS_PASSWORD }}
SLACK_WEBHOOK: ${{ needs.slack-vars.outputs.SLACK_WEBHOOK }}
setup-hosts:
if: github.repository == 'hashicorp/vagrant-acceptance'
runs-on: self-hosted
runs-on: ['self-hosted', 'ondemand', 'linux', 'type=t3.nano']
name: Vagrant-Spec Start Hosts
needs: setup-packet
strategy:
@ -33,22 +46,26 @@ jobs:
providers: ['virtualbox', 'docker']
steps:
- name: Code Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Create hosts for tests (provider ${{ matrix.providers }})
run: ./.ci/spec/create-hosts.sh
working-directory: ${{github.workspace}}
env:
PACKET_EXEC_TOKEN: ${{ needs.packet-vars.outputs.PACKET_EXEC_TOKEN }}
PACKET_EXEC_PROJECT_ID: ${{ needs.packet-vars.outputs.PACKET_EXEC_PROJECT_ID }}
PACKET_SSH_KEY_CONTENT: ${{ needs.packet-vars.outputs.PACKET_SSH_KEY_CONTENT }}
PKT_SECRET_PHRASE: ${{ needs.packaging-vars.outputs.ASSETS_PASSWORD }}
SLACK_WEBHOOK: ${{ needs.slack-vars.outputs.SLACK_WEBHOOK }}
VAGRANT_HOST_BOXES: ${{matrix.host_os}}
VAGRANT_GUEST_BOXES: ${{matrix.guest_os}}
VAGRANT_PRERELEASE_VERSION: ${{ github.event.client_payload.prerelease_version }}
VAGRANT_SPEC_PROVIDERS: ${{matrix.providers}}
VAGRANT_CI_LOADER_BUCKET: ${{ secrets.VAGRANT_CI_LOADER_BUCKET }}
spec-tests:
if: github.repository == 'hashicorp/vagrant-acceptance'
runs-on: self-hosted
runs-on: ['self-hosted', 'ondemand', 'linux', 'type=t3.nano']
name: Vagrant-Spec Tests
needs: setup-hosts
strategy:
@ -62,31 +79,34 @@ jobs:
run: ./.ci/spec/run-test.sh
working-directory: ${{github.workspace}}
env:
PACKET_EXEC_TOKEN: ${{ needs.packet-vars.outputs.PACKET_EXEC_TOKEN }}
PACKET_EXEC_PROJECT_ID: ${{ needs.packet-vars.outputs.PACKET_EXEC_PROJECT_ID }}
PACKET_SSH_KEY_CONTENT: ${{ needs.packet-vars.outputs.PACKET_SSH_KEY_CONTENT }}
PKT_SECRET_PHRASE: ${{ needs.packaging-vars.outputs.ASSETS_PASSWORD }}
SLACK_WEBHOOK: ${{ needs.slack-vars.outputs.SLACK_WEBHOOK }}
VAGRANT_HOST_BOXES: ${{matrix.host_os}}
VAGRANT_GUEST_BOXES: ${{matrix.guest_os}}
VAGRANT_SPEC_PROVIDERS: ${{matrix.providers}}
VAGRANT_DOCKER_IMAGES: ${{matrix.docker_images}}
VAGRANT_CI_LOADER_BUCKET: ${{ secrets.VAGRANT_CI_LOADER_BUCKET }}
HASHIBOT_USERNAME: ${{ secrets.HASHIBOT_USERNAME }}
HASHIBOT_TOKEN: ${{ secrets.HASHIBOT_TOKEN }}
- name: Pull log from guest
if: always()
run: ./.ci/spec/pull-log.sh
env:
PACKET_EXEC_TOKEN: ${{ needs.packet-vars.outputs.PACKET_EXEC_TOKEN }}
PACKET_EXEC_PROJECT_ID: ${{ needs.packet-vars.outputs.PACKET_EXEC_PROJECT_ID }}
PACKET_SSH_KEY_CONTENT: ${{ needs.packet-vars.outputs.PACKET_SSH_KEY_CONTENT }}
PKT_SECRET_PHRASE: ${{ needs.packaging-vars.outputs.ASSETS_PASSWORD }}
SLACK_WEBHOOK: ${{ needs.slack-vars.outputs.SLACK_WEBHOOK }}
VAGRANT_HOST_BOXES: ${{matrix.host_os}}
VAGRANT_GUEST_BOXES: ${{matrix.guest_os}}
VAGRANT_SPEC_PROVIDERS: ${{matrix.providers}}
VAGRANT_DOCKER_IMAGES: ${{matrix.docker_images}}
VAGRANT_CI_LOADER_BUCKET: ${{ secrets.VAGRANT_CI_LOADER_BUCKET }}
HASHIBOT_USERNAME: ${{ secrets.HASHIBOT_USERNAME }}
HASHIBOT_TOKEN: ${{ secrets.HASHIBOT_TOKEN }}
- name: Upload log
if: always()
uses: actions/upload-artifact@v3
with:
name: vagrant-spec-${{matrix.providers}}.log
path: ${{ github.workspace }}/vagrant-spec.log
notify-on-success:
if: github.repository == 'hashicorp/vagrant-acceptance' && success()
runs-on: self-hosted
@ -95,6 +115,8 @@ jobs:
steps:
- name: Notify on Success
run: ./.ci/spec/notify-success.sh
env:
SLACK_WEBHOOK: ${{ needs.slack-vars.outputs.SLACK_WEBHOOK }}
cleanup:
if: github.repository == 'hashicorp/vagrant-acceptance'
@ -104,6 +126,11 @@ jobs:
steps:
- name: Clean Packet
run: ./.ci/spec/clean-packet.sh
env:
PACKET_EXEC_TOKEN: ${{ needs.packet-vars.outputs.PACKET_EXEC_TOKEN }}
PACKET_EXEC_PROJECT_ID: ${{ needs.packet-vars.outputs.PACKET_EXEC_PROJECT_ID }}
PACKET_SSH_KEY_CONTENT: ${{ needs.packet-vars.outputs.PACKET_SSH_KEY_CONTENT }}
PKT_SECRET_PHRASE: ${{ needs.packaging-vars.outputs.ASSETS_PASSWORD }}
SLACK_WEBHOOK: ${{ needs.slack-vars.outputs.SLACK_WEBHOOK }}
- name: Clean Workspace
run: rm -rf ${{ github.workspace }}

View File

@ -0,0 +1,16 @@
name: Test Link Rewrites
on: [deployment_status]
jobs:
test-link-rewrites:
if: github.event.deployment_status.state == 'success'
uses: hashicorp/dev-portal/.github/workflows/docs-content-link-rewrites-e2e.yml@2aceb60125f6c15f4c8dbe2e4d79148047bfa437
with:
repo-owner: 'hashicorp'
repo-name: 'vagrant'
commit-sha: ${{ github.sha }}
main-branch-preview-url: 'https://vagrant-git-main-hashicorp.vercel.app/'
# Workflow is only intended to run for one single migration PR
# This variable does not need to be updated
pr-branch-preview-url: 'https://vagrant-git-docs-ambmigrate-link-formats-hashicorp.vercel.app/'

View File

@ -27,17 +27,21 @@ on:
jobs:
unit-tests-ruby:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
ruby: [ '2.6', '2.7', '3.0', '3.1' ]
ruby: [ '3.0', '3.1', '3.2' ]
name: Vagrant unit tests on Ruby ${{ matrix.ruby }}
steps:
- name: Code Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby}}
bundler-cache: true
- name: install dependencies
run: sudo apt -y install libarchive-tools
- name: Run Tests
run: .ci/test.sh
run: bundle exec rake test:unit

View File

@ -1,4 +1,4 @@
## 2.3.2 (Unreleased)
## UNRELEASED
FEATURES:
@ -8,6 +8,40 @@ BUG FIXES:
VAGRANT-GO:
## 2.3.4 (December 9, 2022)
IMPROVEMENTS:
- host/darwin: Isolate loading incompatible libraries to support EOL platforms [GH-13022]
- provider/virtualbox: Detect network type when not provided [GH-13024]
BUG FIXES:
- host/windows: Add fix for Powershell 7.3.0 [GH-13006]
- provider/virtualbox: Adjust hostnet DHCP configuration, ignore invalid devices [GH-13004]
- provisioner/ansible: Fix install package names on older debian (and derivatives) versions [GH-13017]
## 2.3.3 (November 15, 2022)
IMPROVEMENTS:
- core: Bump net-ssh dependency to 7.0 and remove patches [GH-12979]
- synced_folders/rsync: Include ssh `extra_args` value [GH-12973]
BUG FIXES:
- command/serve: Force root level namespace for Google constant [GH-12989]
- guest/solaris: Fix insecure key authorized keys removal [GH-12740]
- provider/virtualbox: Fix `:private_network` support for VirtualBox 7 on macOS [GH-12983]
- provider/virtualbox: Prevent localization of command output [GH-12994]
- provisioner/ansible: Update setup packages in debian capability [GH-12832]
## 2.3.2 (October 18, 2022)
FEATURES:
- provider/virtualbox: Add support for VirtualBox 7.0 [GH-12947]
## 2.3.1 (September 29, 2022)
IMPROVEMENTS:

View File

@ -1,6 +1,4 @@
The MIT License
Copyright (c) 2010-2019 Mitchell Hashimoto
Copyright (c) 2010 HashiCorp, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -153,6 +153,21 @@ _vagrant() {
COMPREPLY=($(compgen -W "${box_list}" -- ${cur}))
return 0
;;
"add")
local add_commands="\
--name \
--checksum \
--checksum-type \
-c --clean \
-f --force \
"
if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W "${add_commands}" -- ${cur}))
else
COMPREPLY=($(compgen -o default -- "${cur}"))
fi
return 0
;;
*)
;;
esac

View File

@ -15,9 +15,6 @@ class Log4r::BasicFormatter
end
end
# Add our patches to net-ssh
require "vagrant/patches/net-ssh"
require "optparse"
module Vagrant
@ -42,11 +39,27 @@ module VagrantPlugins
OptionParser = Vagrant::OptionParser
end
# Load in our helpers and utilities
require "vagrant/shared_helpers"
require "rubygems"
require "vagrant/util"
require "vagrant/plugin/manager"
# Update the load path so our protos can be located
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs").to_s
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs/proto").to_s
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs/proto/vagrant_plugin_sdk").to_s
# Load our protos so they are available
require 'vagrant/protobufs/proto/vagrant_server/server_pb'
require 'vagrant/protobufs/proto/vagrant_server/server_services_pb'
require 'vagrant/protobufs/proto/ruby_vagrant/ruby-server_pb'
require 'vagrant/protobufs/proto/ruby_vagrant/ruby-server_services_pb'
require 'vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_pb'
require 'vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_services_pb'
require 'vagrant/protobufs/proto/plugin/grpc_broker_pb'
require 'vagrant/protobufs/proto/plugin/grpc_broker_services_pb'
# Enable logging if it is requested. We do this before
# anything else so that we can setup the output before
# any logging occurs.

View File

@ -846,7 +846,7 @@ module Vagrant
begin
@logger.info("Creating: #{dir}")
FileUtils.mkdir_p(dir)
rescue Errno::EACCES
rescue Errno::EACCES, Errno::EROFS
raise Errors::HomeDirectoryNotAccessible, home_path: @home_path.to_s
end
end

View File

@ -972,6 +972,10 @@ module Vagrant
error_key(:virtualbox_broken_version_040214)
end
class VirtualBoxConfigNotFound < VagrantError
error_key(:virtualbox_config_not_found)
end
class VirtualBoxDisksDefinedExceedLimit < VagrantError
error_key(:virtualbox_disks_defined_exceed_limit)
end
@ -1016,6 +1020,10 @@ module Vagrant
error_key(:virtualbox_install_incomplete)
end
class VirtualBoxMachineFolderNotFound < VagrantError
error_key(:virtualbox_machine_folder_not_found)
end
class VirtualBoxNoName < VagrantError
error_key(:virtualbox_no_name)
end

View File

@ -1,286 +0,0 @@
require "net/ssh/version"
# Only patch if we have version 6.1.0 loaded as
# these patches pull 6.1.0 up to the as of now
# current 6.2.0 beta
if Net::SSH::Version::STRING == "6.1.0"
module DeprecatedRsaSha1
module KeyManager
def initialize(logger, options={})
@deprecated_rsa_sha1 = options.delete(:deprecated_rsa_sha1)
super
end
def sign(identity, data)
info = known_identities[identity] or raise Net::SSH::Authentication::KeyManager::KeyManagerError, "the given identity is unknown to the key manager"
if info[:key].nil? && info[:from] == :file
begin
info[:key] = Net::SSH::KeyFactory.load_private_key(info[:file], options[:passphrase], !options[:non_interactive], options[:password_prompt])
if @deprecated_rsa_sha1 && info[:key].respond_to?(:deprecated_rsa_sha1=)
info[:key].deprecated_rsa_sha1 = true
Vagrant.global_logger.debug("set RSA SHA1 deprecation on private key: #{info[:key].fingerprint}")
end
rescue OpenSSL::OpenSSLError, Exception => e
raise Net::SSH::Authentication::KeyManager::KeyManagerError, "the given identity is known, but the private key could not be loaded: #{e.class} (#{e.message})"
end
end
if info[:key]
return Net::SSH::Buffer.from(:string, identity.ssh_signature_type,
:mstring, info[:key].ssh_do_sign(data.to_s)).to_s
end
if info[:from] == :agent
raise Net::SSH::Authentication::KeyManager::KeyManagerError, "the agent is no longer available" unless agent
return agent.sign(info[:identity], data.to_s)
end
raise Net::SSH::Authentication::KeyManager::KeyManagerError, "[BUG] can't determine identity origin (#{info.inspect})"
end
def load_identities(identities, ask_passphrase, ignore_decryption_errors)
identities.map do |identity|
begin
case identity[:load_from]
when :pubkey_file
key = Net::SSH::KeyFactory.load_public_key(identity[:pubkey_file])
if @deprecated_rsa_sha1 && key.respond_to?(:deprecated_rsa_sha1=)
key.deprecated_rsa_sha1 = true
Vagrant.global_logger.debug("set RSA SHA1 deprecation on public key: #{key.fingerprint}")
end
{ public_key: key, from: :file, file: identity[:privkey_file] }
when :privkey_file
private_key = Net::SSH::KeyFactory.load_private_key(
identity[:privkey_file], options[:passphrase], ask_passphrase, options[:password_prompt]
)
key = private_key.send(:public_key)
if @deprecated_rsa_sha1 && key.respond_to?(:deprecated_rsa_sha1=)
key.deprecated_rsa_sha1 = true
private_key.deprecated_rsa_sha1 = true
Vagrant.global_logger.debug("set RSA SHA1 deprecation on public key: #{key.fingerprint}")
Vagrant.global_logger.debug("set RSA SHA1 deprecation on private key: #{private_key.fingerprint}")
end
{ public_key: key, from: :file, file: identity[:privkey_file], key: private_key }
when :data
private_key = Net::SSH::KeyFactory.load_data_private_key(
identity[:data], options[:passphrase], ask_passphrase, "<key in memory>", options[:password_prompt]
)
key = private_key.send(:public_key)
if @deprecated_rsa_sha1 && key.respond_to?(:deprecated_rsa_sha1=)
key.deprecated_rsa_sha1 = true
private_key.deprecated_rsa_sha1 = true
Vagrant.global_logger.debug("set RSA SHA1 deprecation on public key: #{key.fingerprint}")
Vagrant.global_logger.debug("set RSA SHA1 deprecation on private key: #{private_key.fingerprint}")
end
{ public_key: key, from: :key_data, data: identity[:data], key: private_key }
else
identity
end
rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError, OpenSSL::PKey::PKeyError, ArgumentError => e
if ignore_decryption_errors
identity
else
process_identity_loading_error(identity, e)
nil
end
rescue Exception => e
process_identity_loading_error(identity, e)
nil
end
end.compact
end
end
module AuthenticationSession
def initialize(transport, options={})
s_ver_str = transport.server_version.version.
match(/OpenSSH_.*?(?<version>\d+\.\d+)/)&.[](:version).to_s
Vagrant.global_logger.debug("ssh server version detected: #{s_ver_str}")
if !s_ver_str.empty?
begin
ver = Gem::Version.new(s_ver_str)
if ver >= Gem::Version.new("7.2")
Vagrant.global_logger.debug("ssh server supports deprecation of RSA SHA1, deprecating")
options[:deprecated_rsa_sha1] = true
else
Vagrant.global_logger.debug("ssh server does not support deprecation of RSA SHA1")
end
rescue ArgumentError => err
Vagrant.global_logger.debug("failed to determine valid ssh server version - #{err}")
end
end
super
end
end
end
require "net/ssh/transport/algorithms"
# net/ssh/transport/algorithms
[:kex, :host_key].each do |key|
idx = Net::SSH::Transport::Algorithms::ALGORITHMS[key].index(
Net::SSH::Transport::Algorithms::DEFAULT_ALGORITHMS[key].last
)
Net::SSH::Transport::Algorithms::DEFAULT_ALGORITHMS[key].push("rsa-sha2-512")
Net::SSH::Transport::Algorithms::DEFAULT_ALGORITHMS[key].push("rsa-sha2-256")
Net::SSH::Transport::Algorithms::ALGORITHMS[key].insert(idx, "rsa-sha2-256")
Net::SSH::Transport::Algorithms::ALGORITHMS[key].insert(idx, "rsa-sha2-512")
end
require "net/ssh/authentication/key_manager"
Net::SSH::Authentication::KeyManager.prepend(DeprecatedRsaSha1::KeyManager)
require "net/ssh/authentication/session"
Net::SSH::Authentication::Session.prepend(DeprecatedRsaSha1::AuthenticationSession)
require "net/ssh/authentication/agent"
# net/ssh/authentication/agent
Net::SSH::Authentication::Agent.class_eval do
SSH2_AGENT_LOCK = 22
SSH2_AGENT_UNLOCK = 23
# lock the ssh agent with password
def lock(password)
type, = send_and_wait(SSH2_AGENT_LOCK, :string, password)
raise AgentError, "could not lock agent" if type != SSH_AGENT_SUCCESS
end
# unlock the ssh agent with password
def unlock(password)
type, = send_and_wait(SSH2_AGENT_UNLOCK, :string, password)
raise AgentError, "could not unlock agent" if type != SSH_AGENT_SUCCESS
end
end
require "net/ssh/authentication/certificate"
# net/ssh/authentication/certificate
Net::SSH::Authentication::Certificate.class_eval do
def ssh_do_verify(sig, data, options = {})
key.ssh_do_verify(sig, data, options)
end
end
require "net/ssh/authentication/ed25519"
# net/ssh/authentication/ed25519
Net::SSH::Authentication::ED25519::PubKey.class_eval do
def ssh_do_verify(sig, data, options = {})
@verify_key.verify(sig,data)
end
end
require "net/ssh/transport/cipher_factory"
# net/ssh/transport/cipher_factory
Net::SSH::Transport::CipherFactory::SSH_TO_OSSL["aes256-ctr"] = ::OpenSSL::Cipher.ciphers.include?("aes-256-ctr") ? "aes-256-ctr" : "aes-256-ecb"
Net::SSH::Transport::CipherFactory::SSH_TO_OSSL["aes192-ctr"] = ::OpenSSL::Cipher.ciphers.include?("aes-192-ctr") ? "aes-192-ctr" : "aes-192-ecb"
Net::SSH::Transport::CipherFactory::SSH_TO_OSSL["aes128-ctr"] = ::OpenSSL::Cipher.ciphers.include?("aes-128-ctr") ? "aes-128-ctr" : "aes-128-ecb"
require "net/ssh/transport/kex/abstract"
# net/ssh/transport/kex/abstract
Net::SSH::Transport::Kex::Abstract.class_eval do
def matching?(key_ssh_type, host_key_alg)
return true if key_ssh_type == host_key_alg
return true if key_ssh_type == 'ssh-rsa' && ['rsa-sha2-512', 'rsa-sha2-256'].include?(host_key_alg)
end
def verify_server_key(key) #:nodoc:
unless matching?(key.ssh_type, algorithms.host_key)
raise Net::SSH::Exception, "host key algorithm mismatch '#{key.ssh_type}' != '#{algorithms.host_key}'"
end
blob, fingerprint = generate_key_fingerprint(key)
unless connection.host_key_verifier.verify(key: key, key_blob: blob, fingerprint: fingerprint, session: connection)
raise Net::SSH::Exception, 'host key verification failed'
end
end
def verify_signature(result) #:nodoc:
response = build_signature_buffer(result)
hash = digester.digest(response.to_s)
server_key = result[:server_key]
server_sig = result[:server_sig]
unless connection.host_key_verifier.verify_signature { server_key.ssh_do_verify(server_sig, hash, host_key: algorithms.host_key) }
raise Net::SSH::Exception, 'could not verify server signature'
end
hash
end
end
require "net/ssh/transport/openssl"
# net/ssh/transport/openssl
OpenSSL::PKey::RSA.class_eval do
attr_accessor :deprecated_rsa_sha1
def ssh_do_verify(sig, data, options = {})
digester =
if options[:host_key] == "rsa-sha2-512"
OpenSSL::Digest::SHA512.new
elsif options[:host_key] == "rsa-sha2-256"
OpenSSL::Digest::SHA256.new
else
OpenSSL::Digest::SHA1.new
end
verify(digester, sig, data)
end
def ssh_type
deprecated_rsa_sha1 ? signature_algorithm : "ssh-rsa"
end
def signature_algorithm
"rsa-sha2-256"
end
def ssh_do_sign(data)
if deprecated_rsa_sha1
sign(OpenSSL::Digest::SHA256.new, data)
else
sign(OpenSSL::Digest::SHA1.new, data)
end
end
end
OpenSSL::PKey::DSA.class_eval do
def ssh_do_verify(sig, data, options = {})
sig_r = sig[0,20].unpack("H*")[0].to_i(16)
sig_s = sig[20,20].unpack("H*")[0].to_i(16)
a1sig = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(sig_r),
OpenSSL::ASN1::Integer(sig_s)
])
return verify(OpenSSL::Digest::SHA1.new, a1sig.to_der, data)
end
end
OpenSSL::PKey::EC.class_eval do
def ssh_do_verify(sig, data, options = {})
digest = digester.digest(data)
a1sig = nil
begin
sig_r_len = sig[0, 4].unpack('H*')[0].to_i(16)
sig_l_len = sig[4 + sig_r_len, 4].unpack('H*')[0].to_i(16)
sig_r = sig[4, sig_r_len].unpack('H*')[0]
sig_s = sig[4 + sig_r_len + 4, sig_l_len].unpack('H*')[0]
a1sig = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(sig_r.to_i(16)),
OpenSSL::ASN1::Integer(sig_s.to_i(16))
])
rescue StandardError
end
if a1sig.nil?
return false
else
dsa_verify_asn1(digest, a1sig.to_der)
end
end
end
end
require "net/ssh"

View File

@ -3,7 +3,7 @@ module Vagrant
# Generic installation of content to shell config file
class InstallShellConfig
PERPEND_STRING = "# >>>> Vagrant command completion (start)".freeze
PREPEND_STRING = "# >>>> Vagrant command completion (start)".freeze
APPEND_STRING = "# <<<< Vagrant command completion (end)".freeze
attr_accessor :prepend_string
@ -12,7 +12,7 @@ module Vagrant
attr_accessor :config_paths
def initialize(string_insert, config_paths)
@prepend_string = PERPEND_STRING
@prepend_string = PREPEND_STRING
@string_insert = string_insert
@append_string = APPEND_STRING
@config_paths = config_paths
@ -29,7 +29,7 @@ module Vagrant
@logger.info("Searching for config in home #{home}")
@config_paths.each do |path|
config_file = File.join(home, path)
if File.exists?(config_file)
if File.exist?(config_file)
@logger.info("Found config file #{config_file}")
return config_file
end

View File

@ -1,27 +1,11 @@
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs").to_s
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs/proto").to_s
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs/proto/vagrant_plugin_sdk").to_s
require 'vagrant/protobufs/proto/vagrant_server/server_pb'
require 'vagrant/protobufs/proto/vagrant_server/server_services_pb'
require 'vagrant/protobufs/proto/ruby_vagrant/ruby-server_pb'
require 'vagrant/protobufs/proto/ruby_vagrant/ruby-server_services_pb'
require 'vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_pb'
require 'vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_services_pb'
require 'vagrant/protobufs/proto/plugin/grpc_broker_pb'
require 'vagrant/protobufs/proto/plugin/grpc_broker_services_pb'
require "optparse"
require 'grpc'
require 'grpc/health/checker'
require 'grpc/health/v1/health_services_pb'
module VagrantPlugins
module CommandServe
# Simple constant aliases to reduce namespace typing
SDK = Hashicorp::Vagrant::Sdk
SRV = Hashicorp::Vagrant
Empty = Google::Protobuf::Empty
Empty = ::Google::Protobuf::Empty
autoload :Broker, Vagrant.source_root.join("plugins/commands/serve/broker").to_s
autoload :Client, Vagrant.source_root.join("plugins/commands/serve/client").to_s
@ -34,6 +18,17 @@ module VagrantPlugins
attr_accessor :broker
attr_accessor :server
attr_reader :cache
# Loads the required dependencies for this command. This is isolated
# into a method so that the dependencies can be loaded just in time when
# the command is actually executed.
def load_dependencies!
return if @dependencies_loaded
require 'grpc'
require 'grpc/health/checker'
require 'grpc/health/v1/health_services_pb'
@dependencies_loaded = true
end
end
@cache = Util::Cacher.new
@ -49,6 +44,9 @@ module VagrantPlugins
end
def execute
# Load dependencies before we start
CommandServe.load_dependencies!
options = {
bind: DEFAULT_BIND,
min_port: DEFAULT_PORT_RANGE.first,

View File

@ -5,14 +5,14 @@ module VagrantPlugins
module Cap
class RemovePublicKey
def self.remove_public_key(machine, contents)
# TODO: code is identical to linux/cap/remove_public_key
# "sed -i" is specific to GNU sed and is not a posix standard option
contents = contents.chomp
contents = Vagrant::Util::ShellQuote.escape(contents, "'")
machine.communicate.tap do |comm|
if comm.test("test -f ~/.ssh/authorized_keys")
comm.execute(
"sed -i '/^.*#{contents}.*$/d' ~/.ssh/authorized_keys")
"cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.temp && sed '/^.*#{contents}.*$/d' ~/.ssh/authorized_keys.temp > ~/.ssh/authorized_keys && rm ~/.ssh/authorized_keys.temp")
end
end
end

View File

@ -4,7 +4,7 @@ module VagrantPlugins
module HostGentoo
class Host < Vagrant.plugin("2", :host)
def detect?(env)
File.exists?("/etc/gentoo-release")
File.exist?("/etc/gentoo-release")
end
end
end

View File

@ -4,7 +4,7 @@ module VagrantPlugins
module HostSlackware
class Host < Vagrant.plugin("2", :host)
def detect?(env)
return File.exists?("/etc/slackware-version") ||
return File.exist?("/etc/slackware-version") ||
!Dir.glob("/usr/lib/setup/Plamo-*").empty?
end
end

View File

@ -1,6 +1,21 @@
# Always stop when errors are encountered unless instructed not to
$ErrorActionPreference = "Stop"
# Check the version of Powershell currently in use. If it's
# under 7.3.0 we need to restrict the maximum version of the
# security module to prevent errors.
# Source: https://github.com/PowerShell/PowerShell/issues/18530
$checkVersion = $PSVersionTable.PSVersion
if($checkVersion -eq "") {
$checkVersion = $(Get-Host).Version
}
if([System.Version]$checkVersion -lt [System.Version]"7.3.0") {
Import-Module Microsoft.Powershell.Security -MaximumVersion 3.0.0.0
} else {
Import-Module Microsoft.Powershell.Security
}
# Vagrant VM creation functions
function New-VagrantVM {

View File

@ -21,6 +21,8 @@ module VagrantPlugins
VBOX_NET_CONF = "/etc/vbox/networks.conf".freeze
# Version of VirtualBox that introduced hostonly network range restrictions
HOSTONLY_VALIDATE_VERSION = Gem::Version.new("6.1.28")
# Version of VirtualBox on darwin platform that ignores restrictions
DARWIN_IGNORE_HOSTONLY_VALIDATE_VERSION = Gem::Version.new("7.0.0")
# Default valid range for hostonly networks
HOSTONLY_DEFAULT_RANGE = [IPAddr.new("192.168.56.0/21").freeze].freeze
@ -69,6 +71,21 @@ module VagrantPlugins
type = :internal_network
end
if !options.key?(:type) && options.key?(:ip)
begin
addr = IPAddr.new(options[:ip])
options[:type] = if addr.ipv4?
:static
else
:static6
end
rescue IPAddr::Error => err
raise Vagrant::Errors::NetworkAddressInvalid,
address: options[:ip], mask: options[:netmask],
error: err.message
end
end
# Configure it
data = nil
if type == :private_network
@ -479,10 +496,7 @@ module VagrantPlugins
#-----------------------------------------------------------------
# This creates a host only network for the given configuration.
def hostonly_create_network(config)
@env[:machine].provider.driver.create_host_only_network(
adapter_ip: config[:adapter_ip],
netmask: config[:netmask]
)
@env[:machine].provider.driver.create_host_only_network(config)
end
# This finds a matching host only network for the given configuration.
@ -517,7 +531,11 @@ module VagrantPlugins
# placed on the valid ranges
def validate_hostonly_ip!(ip, driver)
return if Gem::Version.new(driver.version) < HOSTONLY_VALIDATE_VERSION ||
Vagrant::Util::Platform.windows?
(
Vagrant::Util::Platform.darwin? &&
Gem::Version.new(driver.version) >= DARWIN_IGNORE_HOSTONLY_VALIDATE_VERSION
) ||
Vagrant::Util::Platform.windows?
ip = IPAddr.new(ip.to_s) if !ip.is_a?(IPAddr)
valid_ranges = load_net_conf

View File

@ -460,7 +460,9 @@ module VagrantPlugins
end
# Append in the options for subprocess
command << { notify: [:stdout, :stderr] }
# NOTE: We include the LANG env var set to C to prevent command output
# from being localized
command << { notify: [:stdout, :stderr], env: {LANG: "C"}}
Vagrant::Util::Busy.busy(int_callback) do
Vagrant::Util::Subprocess.execute(@vboxmanage_path, *command, &block)

View File

@ -65,6 +65,7 @@ module VagrantPlugins
"5.2" => Version_5_2,
"6.0" => Version_6_0,
"6.1" => Version_6_1,
"7.0" => Version_7_0,
}
if @@version.start_with?("4.2.14")

View File

@ -104,15 +104,15 @@ module VagrantPlugins
end
end
# Creates a disk. Default format is VDI unless overridden
#
# @param [String] disk_file
# @param [Integer] disk_size - size in bytes
# @param [String] disk_format - format of disk, defaults to "VDI"
# Creates a disk. Default format is VDI unless overridden
#
# @param [String] disk_file
# @param [Integer] disk_size - size in bytes
# @param [String] disk_format - format of disk, defaults to "VDI"
# @param [Hash] opts - additional options
def create_disk(disk_file, disk_size, disk_format="VDI", **opts)
execute("createmedium", '--filename', disk_file, '--sizebyte', disk_size.to_i.to_s, '--format', disk_format)
end
def create_disk(disk_file, disk_size, disk_format="VDI", **opts)
execute("createmedium", '--filename', disk_file, '--sizebyte', disk_size.to_i.to_s, '--format', disk_format)
end
def create_host_only_network(options)
@ -322,22 +322,22 @@ module VagrantPlugins
if adapter[:bridge]
args.concat(["--bridgeadapter#{adapter[:adapter]}",
adapter[:bridge], "--cableconnected#{adapter[:adapter]}", "on"])
adapter[:bridge], "--cableconnected#{adapter[:adapter]}", "on"])
end
if adapter[:hostonly]
args.concat(["--hostonlyadapter#{adapter[:adapter]}",
adapter[:hostonly], "--cableconnected#{adapter[:adapter]}", "on"])
adapter[:hostonly], "--cableconnected#{adapter[:adapter]}", "on"])
end
if adapter[:intnet]
args.concat(["--intnet#{adapter[:adapter]}",
adapter[:intnet], "--cableconnected#{adapter[:adapter]}", "on"])
adapter[:intnet], "--cableconnected#{adapter[:adapter]}", "on"])
end
if adapter[:mac_address]
args.concat(["--macaddress#{adapter[:adapter]}",
adapter[:mac_address]])
adapter[:mac_address]])
end
if adapter[:nic_type]
@ -361,7 +361,7 @@ module VagrantPlugins
# If the file already exists we'll throw a custom error
raise Vagrant::Errors::VirtualBoxFileExists,
stderr: e.extra_data[:stderr]
stderr: e.extra_data[:stderr]
end
end
end
@ -370,14 +370,14 @@ module VagrantPlugins
args = []
ports.each do |options|
pf_builder = [options[:name],
options[:protocol] || "tcp",
options[:hostip] || "",
options[:hostport],
options[:guestip] || "",
options[:guestport]]
options[:protocol] || "tcp",
options[:hostip] || "",
options[:hostport],
options[:guestip] || "",
options[:guestport]]
args.concat(["--natpf#{options[:adapter] || 1}",
pf_builder.join(",")])
pf_builder.join(",")])
end
execute("modifyvm", @uuid, *args, retryable: true) if !args.empty?
@ -507,11 +507,11 @@ module VagrantPlugins
# since this comes first.
current_nic = $1.to_i if line =~ /^nic(\d+)=".+?"$/
# If we care about active VMs only, then we check the state
# to verify the VM is running.
if active_only && line =~ /^VMState="(.+?)"$/ && $1.to_s != "running"
return []
end
# If we care about active VMs only, then we check the state
# to verify the VM is running.
if active_only && line =~ /^VMState="(.+?)"$/ && $1.to_s != "running"
return []
end
# Parse out the forwarded port information
# Forwarding(1)="172.22.8.201tcp32977,tcp,172.22.8.201,32977,,3777"
@ -600,7 +600,7 @@ module VagrantPlugins
if !valid_ip_address?(ip)
raise Vagrant::Errors::VirtualBoxGuestPropertyNotFound,
guest_property: "/VirtualBox/GuestInfo/Net/#{adapter_number}/V4/IP"
guest_property: "/VirtualBox/GuestInfo/Net/#{adapter_number}/V4/IP"
end
return ip
@ -662,13 +662,17 @@ module VagrantPlugins
end
def read_machine_folder
execute("list", "systemproperties", retryable: true).split("\n").each do |line|
if line =~ /^Default machine folder:\s+(.+?)$/i
return $1.to_s
end
info = execute("list", "systemproperties", retryable: true)
info.each_line do |line|
match = line.match(/Default machine folder:\s+(?<folder>.+?)$/i)
next if match.nil?
return match[:folder]
end
nil
@logger.warn("failed to determine machine folder from system properties")
@logger.debug("processed output for machine folder lookup:\n#{info}")
raise Vagrant::Errors::VirtualBoxMachineFolderNotFound
end
def read_network_interfaces
@ -771,7 +775,7 @@ module VagrantPlugins
# We got VERR_ALREADY_EXISTS. This means that we're renaming to
# a VM name that already exists. Raise a custom error.
raise Vagrant::Errors::VirtualBoxNameExists,
stderr: e.extra_data[:stderr]
stderr: e.extra_data[:stderr]
end
end
end
@ -791,9 +795,9 @@ module VagrantPlugins
hostpath = Vagrant::Util::Platform.windows_path(folder[:hostpath])
end
args = ["--name",
folder[:name],
"--hostpath",
hostpath]
folder[:name],
"--hostpath",
hostpath]
args << "--transient" if folder.key?(:transient) && folder[:transient]
args << "--automount" if folder.key?(:automount) && folder[:automount]
@ -866,8 +870,8 @@ module VagrantPlugins
# If we reached this point then it didn't work out.
raise Vagrant::Errors::VBoxManageError,
command: command.inspect,
stderr: r.stderr
command: command.inspect,
stderr: r.stderr
end
end

View File

@ -0,0 +1,302 @@
require "rexml"
require File.expand_path("../version_6_1", __FILE__)
module VagrantPlugins
module ProviderVirtualBox
module Driver
# Driver for VirtualBox 7.0.x
class Version_7_0 < Version_6_1
# VirtualBox version requirement for using host only networks
# instead of host only interfaces
HOSTONLY_NET_REQUIREMENT=Gem::Requirement.new(">= 7")
# Prefix of name used for host only networks
HOSTONLY_NAME_PREFIX="vagrantnet-vbox"
DEFAULT_NETMASK="255.255.255.0"
def initialize(uuid)
super
@logger = Log4r::Logger.new("vagrant::provider::virtualbox_7_0")
end
def read_bridged_interfaces
ifaces = super
return ifaces if !use_host_only_nets?
# Get a list of all subnets which are in use for hostonly networks
hostonly_ifaces = read_host_only_networks.map do |net|
IPAddr.new(net[:lowerip]).mask(net[:networkmask])
end
# Prune any hostonly interfaces in the list
ifaces.delete_if { |i|
addr = begin
IPAddr.new(i[:ip]).mask(i[:netmask])
rescue IPAddr::Error => err
@logger.warn("skipping bridged interface due to parse error #{err} (#{i}) ")
nil
end
addr.nil? ||
hostonly_ifaces.include?(addr)
}
ifaces
end
def delete_unused_host_only_networks
return super if !use_host_only_nets?
# First get the list of existing host only network names
network_names = read_host_only_networks.map { |net| net[:name] }
# Prune the network names to only include ones we manage
network_names.delete_if { |name| !name.start_with?(HOSTONLY_NAME_PREFIX) }
@logger.debug("managed host only network names: #{network_names}")
return if network_names.empty?
# Next get the list of host only networks currently in use
inuse_names = []
execute("list", "vms", retryable: true).split("\n").each do |line|
match = line.match(/^".+?"\s+\{(?<vmid>.+?)\}$/)
next if match.nil?
begin
info = execute("showvminfo", match[:vmid].to_s, "--machinereadable", retryable: true)
info.split("\n").each do |vmline|
if vmline.start_with?("hostonly-network")
net_name = vmline.split("=", 2).last.to_s.gsub('"', "")
inuse_names << net_name
end
end
rescue Vagrant::Errors::VBoxManageError => err
raise if !err.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
end
end
@logger.debug("currently in use network names: #{inuse_names}")
# Now remove all the networks not in use
(network_names - inuse_names).each do |name|
execute("hostonlynet", "remove", "--name", name, retryable: true)
end
end
def enable_adapters(adapters)
return super if !use_host_only_nets?
hostonly_adapters = adapters.find_all { |adapter| adapter[:hostonly] }
other_adapters = adapters - hostonly_adapters
super(other_adapters) if !other_adapters.empty?
if !hostonly_adapters.empty?
args = []
hostonly_adapters.each do |adapter|
args.concat(["--nic#{adapter[:adapter]}", "hostonlynet"])
args.concat(["--host-only-net#{adapter[:adapter]}", adapter[:hostonly],
"--cableconnected#{adapter[:adapter]}", "on"])
end
execute("modifyvm", @uuid, *args, retryable: true)
end
end
def create_host_only_network(options)
# If we are not on macOS, just setup the hostonly interface
return super if !use_host_only_nets?
opts = {
netmask: options.fetch(:netmask, DEFAULT_NETMASK),
}
if options[:type] == :dhcp
opts[:lower] = options[:dhcp_lower]
opts[:upper] = options[:dhcp_upper]
else
addr = IPAddr.new(options[:adapter_ip])
opts[:upper] = opts[:lower] = addr.mask(opts[:netmask]).to_range.first.to_s
end
name_idx = read_host_only_networks.map { |hn|
next if !hn[:name].start_with?(HOSTONLY_NAME_PREFIX)
hn[:name].sub(HOSTONLY_NAME_PREFIX, "").to_i
}.compact.max.to_i + 1
opts[:name] = HOSTONLY_NAME_PREFIX + name_idx.to_s
execute("hostonlynet", "add",
"--name", opts[:name],
"--netmask", opts[:netmask],
"--lower-ip", opts[:lower],
"--upper-ip", opts[:upper],
retryable: true)
{
name: opts[:name],
ip: options[:adapter_ip],
netmask: opts[:netmask],
}
end
# Disabled when host only nets are in use
def reconfig_host_only(options)
return super if !use_host_only_nets?
end
# Disabled when host only nets are in use since
# the host only nets will provide the dhcp server
def remove_dhcp_server(*_, **_)
super if !use_host_only_nets?
end
# Disabled when host only nets are in use since
# the host only nets will provide the dhcp server
def create_dhcp_server(*_, **_)
super if !use_host_only_nets?
end
def read_host_only_interfaces
return super if !use_host_only_nets?
# When host only nets are in use, read them and
# reformat the information to line up with how
# the interfaces is structured
read_host_only_networks.map do |net|
addr = begin
IPAddr.new(net[:lowerip])
rescue IPAddr::Error => err
@logger.warn("invalid host only network lower IP encountered: #{err} (#{net})")
next
end
# Address of the interface will be the lower bound of the range or
# the first available address in the subnet
if addr == addr.mask(net[:networkmask])
addr = addr.succ
end
net[:netmask] = net[:networkmask]
if addr.ipv4?
net[:ip] = addr.to_s
net[:ipv6] = ""
else
net[:ip] = ""
net[:ipv6] = addr.to_s
net[:ipv6_prefix] = net[:netmask]
end
net[:status] = net[:state] == "Enabled" ? "Up" : "Down"
net
end.compact
end
def read_network_interfaces
return super if !use_host_only_nets?
{}.tap do |nics|
execute("showvminfo", @uuid, "--machinereadable", retryable: true).each_line do |line|
if m = line.match(/nic(?<adapter>\d+)="(?<type>.+?)"$/)
nics[m[:adapter].to_i] ||= {}
if m[:type] == "hostonlynetwork"
nics[m[:adapter].to_i][:type] = :hostonly
else
nics[m[:adapter].to_i][:type] = m[:type].to_sym
end
elsif m = line.match(/^bridgeadapter(?<adapter>\d+)="(?<network>.+?)"$/)
nics[m[:adapter].to_i] ||= {}
nics[m[:adapter].to_i][:bridge] = m[:network]
elsif m = line.match(/^hostonly-network(?<adapter>\d+)="(?<network>.+?)"$/)
nics[m[:adapter].to_i] ||= {}
nics[m[:adapter].to_i][:hostonly] = m[:network]
end
end
end
end
# Generate list of host only networks
def read_host_only_networks
networks = []
current = nil
execute("list", "hostonlynets", retryable: true).split("\n").each do |line|
line.chomp!
next if line.empty?
key, value = line.split(":", 2).map(&:strip)
key = key.downcase
if key == "name"
networks.push(current) if !current.nil?
current = Vagrant::Util::HashWithIndifferentAccess.new
end
current[key] = value
end
networks.push(current) if !current.nil?
networks
end
# The initial VirtualBox 7.0 release has an issue with displaying port
# forward information. When a single port forward is defined, the forwarding
# information can be found in the `showvminfo` output. Once more than a
# single port forward is defined, no forwarding information is provided
# in the `showvminfo` output. To work around this we grab the VM configuration
# file from the `showvminfo` output and extract the port forward information
# from there instead.
def read_forwarded_ports(uuid=nil, active_only=false)
# Only use this override for the 7.0.0 release.
return super if get_version.to_s != "7.0.0"
uuid ||= @uuid
@logger.debug("read_forward_ports: uuid=#{uuid} active_only=#{active_only}")
results = []
info = execute("showvminfo", uuid, "--machinereadable", retryable: true)
result = info.match(/CfgFile="(?<path>.+?)"/)
if result.nil?
raise Vagrant::Errors::VirtualBoxConfigNotFound,
uuid: uuid
end
File.open(result[:path], "r") do |f|
doc = REXML::Document.new(f)
networks = REXML::XPath.each(doc.root, "//Adapter")
networks.each do |net|
REXML::XPath.each(doc.root, net.xpath + "/NAT/Forwarding") do |fwd|
# Result Array values:
# [NIC Slot, Name, Host Port, Guest Port, Host IP]
result = [
net.attribute("slot").value.to_i + 1,
fwd.attribute("name")&.value.to_s,
fwd.attribute("hostport")&.value.to_i,
fwd.attribute("guestport")&.value.to_i,
fwd.attribute("hostip")&.value.to_s
]
@logger.debug(" - #{result.inspect}")
results << result
end
end
end
results
end
private
# Returns if hostonlynets are enabled on the current
# host platform
#
# @return [Boolean]
def use_host_only_nets?
Vagrant::Util::Platform.darwin? &&
HOSTONLY_NET_REQUIREMENT.satisfied_by?(get_version)
end
# VirtualBox version in use
#
# @return [Gem::Version]
def get_version
return @version if @version
@version = Gem::Version.new(Meta.new.version)
end
end
end
end
end

View File

@ -100,6 +100,7 @@ module VagrantPlugins
autoload :Version_5_2, File.expand_path("../driver/version_5_2", __FILE__)
autoload :Version_6_0, File.expand_path("../driver/version_6_0", __FILE__)
autoload :Version_6_1, File.expand_path("../driver/version_6_1", __FILE__)
autoload :Version_7_0, File.expand_path("../driver/version_7_0", __FILE__)
end
module Model

View File

@ -37,7 +37,11 @@ INLINE_CRIPT
def self.pip_setup(machine, pip_install_cmd = "")
machine.communicate.sudo "apt-get update -y -qq"
machine.communicate.sudo "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --option \"Dpkg::Options::=--force-confold\" build-essential curl git libssl-dev libffi-dev python-dev"
python_dev_pkg = "python-dev"
if machine.communicate.test "apt-cache show python-dev-is-python3"
python_dev_pkg = "python-dev-is-python3"
end
machine.communicate.sudo "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --option \"Dpkg::Options::=--force-confold\" build-essential curl git libssl-dev libffi-dev #{python_dev_pkg}"
Pip::get_pip machine, pip_install_cmd
end

View File

@ -185,7 +185,7 @@ module VagrantPlugins
inventory_file = Pathname.new(File.join(inventory_path, 'vagrant_ansible_inventory'))
@@lock.synchronize do
if !File.exists?(inventory_file) or inventory_content != File.read(inventory_file)
if !File.exist?(inventory_file) or inventory_content != File.read(inventory_file)
begin
# ansible dir inventory will ignore files starting with '.'
inventory_tmpfile = Tempfile.new('.vagrant_ansible_inventory', inventory_path)

View File

@ -81,7 +81,7 @@ module VagrantPlugins
errors << I18n.t("vagrant.config.chef.nodes_path_empty")
else
missing_paths = Array.new
nodes_path.each { |dir| missing_paths << dir[1] if !File.exists? dir[1] }
nodes_path.each { |dir| missing_paths << dir[1] if !File.exist? dir[1] }
# If it exists at least one path on disk it's ok for Chef provisioning
if missing_paths.size == nodes_path.size
errors << I18n.t("vagrant.config.chef.nodes_path_missing", path: missing_paths.to_s)

View File

@ -108,6 +108,7 @@ module VagrantPlugins
ssh_config_file,
control_options,
]
rsh += ssh_info[:extra_args] if ssh_info[:extra_args]
# Solaris/OpenSolaris/Illumos uses SunSSH which doesn't support the
# IdentitiesOnly option. Also, we don't enable it if keys_only is false

View File

@ -1743,6 +1743,11 @@ en:
4.2.14 contains a critical bug which prevents it from working with
Vagrant. VirtualBox 4.2.16+ fixes this problem. Please upgrade
VirtualBox.
virtualbox_config_not_found: |-
Vagrant was unable to locate the configuration file for the requested
VirtualBox VM. Verify the requested VM exists and try again.
UUID provided: %{uuid}
virtualbox_disks_controller_not_found: |-
Vagrant expected to find a storage controller called '%{name}',
but there is no controller with this name attached to the current VM.
@ -1789,6 +1794,10 @@ en:
VirtualBox is complaining that the installation is incomplete. Please
run `VBoxManage --version` to see the error message which should contain
instructions on how to fix this error.
virtualbox_machine_folder_not_found: |-
Vagrant failed to determine the machine folder on this host from
the VirtualBox system information. Try running the command again.
If this error persists, please report this error as a bug.
virtualbox_mount_failed: |-
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is

View File

@ -231,10 +231,10 @@ describe VagrantPlugins::ProviderVirtualBox::Action::Network do
subject.call(env)
expect(driver).to have_received(:create_host_only_network).with({
expect(driver).to have_received(:create_host_only_network).with(hash_including({
adapter_ip: interface_ip,
netmask: 64,
})
}))
expect(guest).to have_received(:capability).with(:configure_networks, [{
type: :static6,
@ -308,10 +308,10 @@ describe VagrantPlugins::ProviderVirtualBox::Action::Network do
subject.call(env)
expect(driver).to have_received(:create_host_only_network).with({
expect(driver).to have_received(:create_host_only_network).with(hash_including({
adapter_ip: '192.168.56.1',
netmask: '255.255.255.0',
})
}))
expect(driver).to have_received(:create_dhcp_server).with('vboxnet0', {
adapter_ip: "192.168.56.1",
@ -402,6 +402,33 @@ describe VagrantPlugins::ProviderVirtualBox::Action::Network do
end
end
context "without type set" do
before { allow(subject).to receive(:hostonly_adapter).and_return({}) }
[
{ ip: "192.168.63.5" },
{ ip: "192.168.63.5", netmask: "255.255.255.0" },
{ ip: "dead:beef::100" },
{ ip: "dead:beef::100", netmask: 96 },
].each do |args|
it "sets the type automatically" do
machine.config.vm.network "private_network", **args
expect(subject).to receive(:hostonly_config) do |config|
expect(config).to have_key(:type)
addr = IPAddr.new(args[:ip])
if addr.ipv4?
expect(config[:type]).to eq(:static)
else
expect(config[:type]).to eq(:static6)
end
config
end
subject.call(env)
end
end
end
describe "#hostonly_find_matching_network" do
let(:ip){ "192.168.55.2" }
let(:config){ {ip: ip, netmask: "255.255.255.0"} }

View File

@ -186,4 +186,91 @@ OUTPUT
expect(storage_controllers.first.attachments).to eq(attachments_result)
end
end
describe "#read_machine_folder" do
let(:system_properties) { VBOX_SYSTEM_PROPERTIES }
let(:machine_folder) { "/home/username/VirtualBox VMs"}
before do
allow(subject).to receive(:execute).
with("list", "systemproperties", any_args).
and_return(system_properties)
end
it "should read the default folder" do
expect(subject.read_machine_folder).to eq(machine_folder)
end
context "when default folder value is missing" do
let(:system_properties) { VBOX_SYSTEM_PROPERTIES.sub(/^Default machine folder:.+$/, "")}
it "should raise a custom error" do
expect {
subject.read_machine_folder
}.to raise_error(Vagrant::Errors::VirtualBoxMachineFolderNotFound)
end
end
end
end
VBOX_SYSTEM_PROPERTIES=%(
API version: 7_0
Minimum guest RAM size: 4 Megabytes
Maximum guest RAM size: 2097152 Megabytes
Minimum video RAM size: 0 Megabytes
Maximum video RAM size: 256 Megabytes
Maximum guest monitor count: 64
Minimum guest CPU count: 1
Maximum guest CPU count: 64
Virtual disk limit (info): 2199022206976 Bytes
Maximum Serial Port count: 4
Maximum Parallel Port count: 2
Maximum Boot Position: 4
Maximum PIIX3 Network Adapter count: 8
Maximum ICH9 Network Adapter count: 36
Maximum PIIX3 IDE Controllers: 1
Maximum ICH9 IDE Controllers: 1
Maximum IDE Port count: 2
Maximum Devices per IDE Port: 2
Maximum PIIX3 SATA Controllers: 1
Maximum ICH9 SATA Controllers: 8
Maximum SATA Port count: 30
Maximum Devices per SATA Port: 1
Maximum PIIX3 SCSI Controllers: 1
Maximum ICH9 SCSI Controllers: 8
Maximum SCSI Port count: 16
Maximum Devices per SCSI Port: 1
Maximum SAS PIIX3 Controllers: 1
Maximum SAS ICH9 Controllers: 8
Maximum SAS Port count: 255
Maximum Devices per SAS Port: 1
Maximum NVMe PIIX3 Controllers: 1
Maximum NVMe ICH9 Controllers: 8
Maximum NVMe Port count: 255
Maximum Devices per NVMe Port: 1
Maximum virtio-scsi PIIX3 Controllers: 1
Maximum virtio-scsi ICH9 Controllers: 8
Maximum virtio-scsi Port count: 256
Maximum Devices per virtio-scsi Port: 1
Maximum PIIX3 Floppy Controllers:1
Maximum ICH9 Floppy Controllers: 1
Maximum Floppy Port count: 1
Maximum Devices per Floppy Port: 2
Default machine folder: /home/username/VirtualBox VMs
Raw-mode Supported: no
Exclusive HW virtualization use: on
Default hard disk format: VDI
VRDE auth library: VBoxAuth
Webservice auth. library: VBoxAuth
Remote desktop ExtPack:
VM encryption ExtPack:
Log history count: 3
Default frontend:
Default audio driver: ALSA
Autostart database path:
Default Guest Additions ISO: /usr/share/virtualbox/VBoxGuestAdditions.iso
Logging Level: all
Proxy Mode: System
Proxy URL:
User language: en_US
)

View File

@ -0,0 +1,852 @@
require "stringio"
require_relative "../base"
describe VagrantPlugins::ProviderVirtualBox::Driver::Version_7_0 do
include_context "virtualbox"
let(:vbox_version) { "7.0.0" }
subject { VagrantPlugins::ProviderVirtualBox::Driver::Version_7_0.new(uuid) }
it_behaves_like "a version 5.x virtualbox driver"
it_behaves_like "a version 6.x virtualbox driver"
describe "#read_forwarded_ports" do
let(:uuid) { "MACHINE-UUID" }
let(:cfg_path) { "MACHINE_CONFIG_PATH" }
let(:vm_info) {
%(name="vagrant-test_default_1665781960041_56631"
Encryption: disabled
groups="/"
ostype="Ubuntu (64-bit)"
UUID="#{uuid}"
CfgFile="#{cfg_path}"
SnapFldr="/VirtualBox VMs/vagrant-test_default_1665781960041_56631/Snapshots"
LogFldr="/VirtualBox VMs/vagrant-test_default_1665781960041_56631/Logs"
memory=1024)
}
let(:config_file) {
StringIO.new(VBOX_VMCONFIG_FILE)
}
before do
allow_any_instance_of(VagrantPlugins::ProviderVirtualBox::Driver::Meta).to receive(:version).and_return(vbox_version)
end
describe "VirtualBox version 7.0.0" do
let(:vbox_version) { "7.0.0" }
before do
allow(subject).to receive(:execute).with("showvminfo", uuid, any_args).and_return(vm_info)
allow(File).to receive(:open).with(cfg_path, "r").and_yield(config_file)
end
it "should return two port forward values" do
expect(subject.read_forwarded_ports.size).to eq(2)
end
it "should have port forwards on slot one" do
subject.read_forwarded_ports.each do |fwd|
expect(fwd.first).to eq(1)
end
end
it "should include host ip for ssh forward" do
fwd = subject.read_forwarded_ports.detect { |f| f[1] == "ssh" }
expect(fwd).not_to be_nil
expect(fwd.last).to eq("127.0.0.1")
end
describe "when config file cannot be determine" do
let(:vm_info) { %(name="vagrant-test_default_1665781960041_56631") }
it "should raise a custom error" do
expect(File).not_to receive(:open).with(cfg_path, "r")
expect { subject.read_forwarded_ports }.to raise_error(Vagrant::Errors::VirtualBoxConfigNotFound)
end
end
end
describe "VirtualBox version greater than 7.0.0" do
let(:vbox_version) { "7.0.1" }
before do
allow(subject).to receive(:execute).with("showvminfo", uuid, any_args).and_return(vm_info)
end
it "should not read configuration file" do
expect(File).not_to receive(:open).with(cfg_path, "r")
subject.read_forwarded_ports
end
end
end
describe "#use_host_only_nets?" do
context "when platform is darwin" do
before do
allow(Vagrant::Util::Platform).to receive(:darwin?).and_return(true)
end
context "when virtualbox version is less than 7" do
before do
allow_any_instance_of(VagrantPlugins::ProviderVirtualBox::Driver::Meta).
to receive(:version).and_return("6.0.28")
end
it "should return false" do
expect(subject.send(:use_host_only_nets?)).to be(false)
end
end
context "when virtualbox version is greater than 7" do
before do
allow_any_instance_of(VagrantPlugins::ProviderVirtualBox::Driver::Meta).
to receive(:version).and_return("7.0.2")
end
it "should return true" do
expect(subject.send(:use_host_only_nets?)).to be(true)
end
end
context "when virtualbox version is equal to 7" do
before do
allow_any_instance_of(VagrantPlugins::ProviderVirtualBox::Driver::Meta).
to receive(:version).and_return("7.0.0")
end
it "should return true" do
expect(subject.send(:use_host_only_nets?)).to be(true)
end
end
end
context "when platform is not darwin" do
before do
allow(Vagrant::Util::Platform).to receive(:darwin?).and_return(false)
end
context "when virtualbox version is less than 7" do
before do
allow_any_instance_of(VagrantPlugins::ProviderVirtualBox::Driver::Meta).
to receive(:version).and_return("6.0.28")
end
it "should return false" do
expect(subject.send(:use_host_only_nets?)).to be(false)
end
end
context "when virtualbox version is greater than 7" do
before do
allow_any_instance_of(VagrantPlugins::ProviderVirtualBox::Driver::Meta).
to receive(:version).and_return("7.0.2")
end
it "should return false" do
expect(subject.send(:use_host_only_nets?)).to be(false)
end
end
context "when virtualbox version is equal to 7" do
before do
allow_any_instance_of(VagrantPlugins::ProviderVirtualBox::Driver::Meta).
to receive(:version).and_return("7.0.0")
end
it "should return false" do
expect(subject.send(:use_host_only_nets?)).to be(false)
end
end
end
end
describe "#read_bridged_interfaces" do
let(:bridgedifs) { VBOX_BRIDGEDIFS }
before do
allow(subject).to receive(:execute).and_call_original
expect(subject).
to receive(:execute).
with("list", "bridgedifs").
and_return(bridgedifs)
end
context "when hostonlynets are not enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
end
it "should return all interfaces in list" do
expect(subject.read_bridged_interfaces.size).to eq(5)
end
it "should not read host only networks" do
expect(subject).not_to receive(:read_host_only_networks)
subject.read_bridged_interfaces
end
end
context "when hostonlynets are enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
end
it "should return all interfaces in list" do
expect(subject).to receive(:read_host_only_networks).and_return([])
expect(subject.read_bridged_interfaces.size).to eq(5)
end
context "when hostonly networks are defined" do
before do
expect(subject).
to receive(:execute).
with("list", "hostonlynets", any_args).
and_return(VBOX_HOSTONLYNETS)
end
it "should not return all interfaces in list" do
expect(subject.read_bridged_interfaces.size).to_not eq(5)
end
it "should not include hostonly network devices" do
expect(
subject.read_bridged_interfaces.any? { |int|
int[:name].start_with?("bridge")
}
).to be(false)
end
end
end
context "when address is empty" do
let(:bridgedifs) { VBOX_BRIDGEDIFS.sub("0.0.0.0", "") }
it "should not raise an error" do
expect { subject.read_bridged_interfaces }.to_not raise_error
end
end
end
describe "#delete_unused_host_only_networks" do
context "when hostonlynets are not enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
end
it "should remove host only interfaces" do
expect(subject).to receive(:execute).with("list", "hostonlyifs", any_args).and_return("")
expect(subject).to receive(:execute).with("list", "vms", any_args).and_return("")
subject.delete_unused_host_only_networks
end
it "should not read host only networks" do
expect(subject).to receive(:execute).with("list", "hostonlyifs", any_args).and_return("")
expect(subject).to receive(:execute).with("list", "vms", any_args).and_return("")
expect(subject).not_to receive(:read_host_only_networks)
subject.delete_unused_host_only_networks
end
end
context "when hostonlynets are enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
allow(subject).to receive(:read_host_only_networks).and_return([])
allow(subject).to receive(:execute).with("list", "vms", any_args).and_return("")
end
it "should not read host only interfaces" do
expect(subject).not_to receive(:execute).with("list", "hostonlyifs", any_args)
subject.delete_unused_host_only_networks
end
context "when no host only networks are defined" do
before do
expect(subject).to receive(:read_host_only_networks).and_return([])
end
it "should not list vms" do
expect(subject).not_to receive(:execute).with("list", "vms", any_args)
subject.delete_unused_host_only_networks
end
end
context "when host only networks are defined" do
before do
expect(subject).
to receive(:read_host_only_networks).
and_return([{name: "vagrantnet-vbox-1"}])
end
context "when no vms are using the network" do
before do
expect(subject).to receive(:execute).with("list", "vms", any_args).and_return("")
end
it "should delete the network" do
expect(subject).
to receive(:execute).
with("hostonlynet", "remove", "--name", "vagrantnet-vbox-1", any_args)
subject.delete_unused_host_only_networks
end
end
context "when vms are using the network" do
before do
expect(subject).
to receive(:execute).
with("list", "vms", any_args).
and_return(%("VM_NAME" {VM_ID}))
expect(subject).
to receive(:execute).
with("showvminfo", "VM_ID", any_args).
and_return(%(hostonly-network="vagrantnet-vbox-1"))
end
it "should not delete the network" do
expect(subject).not_to receive(:execute).with("hostonlynet", "remove", any_args)
subject.delete_unused_host_only_networks
end
end
end
end
end
describe "#enable_adapters" do
let(:adapters) {
[{hostonly: "hostonlynetwork", adapter: 1},
{bridge: "eth0", adapter: 2}]
}
before do
allow(subject).to receive(:execute).with("modifyvm", any_args)
end
context "when hostonlynets are not enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
end
it "should only call modifyvm once" do
expect(subject).to receive(:execute).with("modifyvm", any_args).once
subject.enable_adapters(adapters)
end
it "should configure host only network using hostonlyadapter" do
expect(subject).to receive(:execute) { |*args|
expect(args.first).to eq("modifyvm")
expect(args).to include("--hostonlyadapter1")
true
}
subject.enable_adapters(adapters)
end
end
context "when hostonlynets are enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
end
it "should call modifyvm twice" do
expect(subject).to receive(:execute).with("modifyvm", any_args).twice
subject.enable_adapters(adapters)
end
it "should configure host only network using hostonlynet" do
expect(subject).to receive(:execute).once
expect(subject).to receive(:execute) { |*args|
expect(args.first).to eq("modifyvm")
expect(args).to include("--host-only-net1")
true
}
subject.enable_adapters(adapters)
end
end
end
describe "#create_host_only_network" do
let(:options) {
{
adapter_ip: "127.0.0.1",
netmask: "255.255.255.0"
}
}
context "when hostonlynets are disabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
end
it "should create using hostonlyif" do
expect(subject).
to receive(:execute).
with("hostonlyif", "create", any_args).
and_return("Interface 'host_only' was successfully created")
expect(subject).
to receive(:execute).
with("hostonlyif", "ipconfig", "host_only", any_args)
subject.create_host_only_network(options)
end
end
context "when hostonlynets are enabled" do
let(:prefix) { described_class.const_get(:HOSTONLY_NAME_PREFIX) }
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
allow(subject).to receive(:read_host_only_networks).and_return([])
end
it "should create using hostonlynet" do
expect(subject).
to receive(:execute).
with("hostonlynet", "add", "--name", prefix + "1",
"--netmask", options[:netmask], "--lower-ip",
"127.0.0.0", "--upper-ip", "127.0.0.0", any_args)
subject.create_host_only_network(options)
end
context "when other host only networks exist" do
before do
expect(subject).
to receive(:read_host_only_networks).
and_return(["custom", prefix + "1", prefix + "20"].map { |n| {name: n} })
end
it "should create network with incremented name" do
expect(subject).
to receive(:execute).
with("hostonlynet", "add", "--name", prefix + "21", any_args)
subject.create_host_only_network(options)
end
end
context "when dhcp information is included" do
let(:options) {
{
type: :dhcp,
dhcp_lower: "127.0.0.1",
dhcp_upper: "127.0.1.200",
netmask: "255.255.240.0"
}
}
it "should set DHCP range" do
expect(subject).
to receive(:execute).
with("hostonlynet", "add", "--name", anything, "--netmask", options[:netmask],
"--lower-ip", options[:dhcp_lower], "--upper-ip", options[:dhcp_upper],
any_args)
subject.create_host_only_network(options)
end
end
end
end
describe "#reconfig_host_only" do
let(:interface) { {name: "iname", ipv6: "VALUE"} }
context "when hostonlynets are disabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
end
it "should apply ipv6 update" do
expect(subject).to receive(:execute).with("hostonlyif", "ipconfig", interface[:name],
"--ipv6", interface[:ipv6], any_args)
subject.reconfig_host_only(interface)
end
end
context "when hostonlynets are enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
end
it "should do nothing" do
expect(subject).not_to receive(:execute)
subject.reconfig_host_only(interface)
end
end
end
describe "#remove_dhcp_server" do
let(:dhcp_name) { double(:dhcp_name) }
context "when hostonlynets are disabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
end
it "should remove the dhcp server" do
expect(subject).to receive(:execute).with("dhcpserver", "remove", "--netname",
dhcp_name, any_args)
subject.remove_dhcp_server(dhcp_name)
end
end
context "when hostonlynets are enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
end
it "should do nothing" do
expect(subject).not_to receive(:execute)
subject.remove_dhcp_server(dhcp_name)
end
end
end
describe "#create_dhcp_server" do
let(:network) { double("network") }
let(:options) {
{
dhcp_ip: "127.0.0.1",
netmask: "255.255.255.0",
dhcp_lower: "127.0.0.2",
dhcp_upper: "127.0.0.200"
}
}
context "when hostonlynets is diabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
end
it "should create a dhcp server" do
expect(subject).to receive(:execute).with("dhcpserver", "add", "--ifname", network,
"--ip", options[:dhcp_ip], any_args)
subject.create_dhcp_server(network, options)
end
end
context "when hostonlynets is enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
end
it "should do nothing" do
expect(subject).not_to receive(:execute)
subject.create_dhcp_server(network, options)
end
end
end
describe "#read_host_only_interfaces" do
context "when hostonlynets is diabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
allow(subject).to receive(:execute).and_return("")
end
it "should list hostonlyifs" do
expect(subject).to receive(:execute).with("list", "hostonlyifs", any_args).and_return("")
subject.read_host_only_interfaces
end
it "should not call read_host_only_networks" do
expect(subject).not_to receive(:read_host_only_networks)
subject.read_host_only_interfaces
end
end
context "when hostonlynets is enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
allow(subject).to receive(:execute).with("list", "hostonlynets", any_args).
and_return(VBOX_HOSTONLYNETS)
end
it "should call read_host_only_networks" do
expect(subject).to receive(:read_host_only_networks).and_return([])
subject.read_host_only_interfaces
end
it "should return defined networks" do
expect(subject.read_host_only_interfaces.size).to eq(2)
end
it "should add compat information to network entries" do
result = subject.read_host_only_interfaces
expect(result.first[:netmask]).to eq(result.first[:networkmask])
expect(result.first[:status]).to eq("Up")
end
it "should assign the address as the first in the subnet" do
result = subject.read_host_only_interfaces
expect(result.first[:ip]).to eq(IPAddr.new(result.first[:lowerip]).succ.to_s)
end
context "when dhcp range is set" do
before do
allow(subject).to receive(:execute).with("list", "hostonlynets", any_args).
and_return(VBOX_RANGE_HOSTONLYNETS)
end
it "should assign the address as the first in the dhcp range" do
result = subject.read_host_only_interfaces
expect(result.first[:ip]).to eq(result.first[:lowerip])
end
end
end
end
describe "#read_host_only_networks" do
before do
allow(subject).to receive(:execute).with("list", "hostonlynets", any_args).
and_return(VBOX_HOSTONLYNETS)
end
it "should return defined networks" do
expect(subject.read_host_only_networks.size).to eq(2)
end
it "should return expected network information" do
result = subject.read_host_only_networks
expect(result.first[:name]).to eq("vagrantnet-vbox1")
expect(result.first[:lowerip]).to eq("192.168.61.0")
expect(result.first[:networkmask]).to eq("255.255.255.0")
expect(result.last[:name]).to eq("vagrantnet-vbox2")
expect(result.last[:lowerip]).to eq("192.168.22.0")
expect(result.last[:networkmask]).to eq("255.255.255.0")
end
end
describe "#read_network_interfaces" do
before do
allow(subject)
.to receive(:execute).
with("showvminfo", any_args).
and_return(VBOX_GUEST_HOSTONLYVNETS_INFO)
end
context "when hostonlynets is disabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(false)
end
it "should return two interfaces" do
valid_interfaces = subject.read_network_interfaces.find_all { |k, v|
v[:type] != :none
}
expect(valid_interfaces.size).to eq(2)
end
it "should include a nat type" do
expect(subject.read_network_interfaces.detect { |_, v| v[:type] == :nat }).to be
end
it "should include a hostonlynetwork type with no information" do
expect(subject.read_network_interfaces[2]).to eq({type: :hostonlynetwork})
end
end
context "when hostonlynets is enabled" do
before do
allow(subject).to receive(:use_host_only_nets?).and_return(true)
end
it "should return two interfaces" do
valid_interfaces = subject.read_network_interfaces.find_all { |k, v|
v[:type] != :none
}
expect(valid_interfaces.size).to eq(2)
end
it "should include a nat type" do
expect(subject.read_network_interfaces.detect { |_, v| v[:type] == :nat }).to be
end
it "should include a hostonly type" do
expect(subject.read_network_interfaces.detect { |_, v| v[:type] == :hostonly }).to be
end
it "should not include a hostonlynetwork type" do
expect(subject.read_network_interfaces.detect { |_, v|
v[:type] == :hostonlynetwork
}).to_not be
end
it "should include the hostonly network name" do
hostonly = subject.read_network_interfaces.values.detect { |v|
v[:type] == :hostonly
}
expect(hostonly).to be
expect(hostonly[:hostonly]).to eq("vagrantnet-vbox1")
end
end
end
end
VBOX_VMCONFIG_FILE=%(<?xml version="1.0"?>
<VirtualBox xmlns="http://www.virtualbox.org/" version="1.19-linux">
<Machine uuid="{623842dc-0947-4143-aa4e-7d180c5eb348}" name="vagrant-test_default_1665781960041_56631" OSType="Ubuntu_64" snapshotFolder="Snapshots">
<Hardware>
<Network>
<Adapter slot="0" enabled="true" MACAddress="080027BB1475" type="82540EM">
<NAT localhost-reachable="true">
<DNS use-proxy="true"/>
<Forwarding name="ssh" proto="1" hostip="127.0.0.1" hostport="2222" guestport="22"/>
<Forwarding name="tcp7700" proto="1" hostport="7700" guestport="80"/>
</NAT>
</Adapter>
<Adapter slot="1" enabled="true" MACAddress="080027DD5ADF" type="82540EM">
<DisabledModes>
<InternalNetwork name="intnet"/>
<NATNetwork name="NatNetwork"/>
</DisabledModes>
<HostOnlyInterface name="vboxnet0"/>
</Adapter>
</Network>
</Hardware>
</Machine>
</VirtualBox>)
VBOX_BRIDGEDIFS=%(Name: en1: Wi-Fi (AirPort)
GUID: 00000000-0000-0000-0000-000000000001
DHCP: Disabled
IPAddress: 10.0.0.49
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: xx:xx:xx:xx:xx:01
MediumType: Ethernet
Wireless: Yes
Status: Up
VBoxNetworkName: HostInterfaceNetworking-en1
Name: en0: Ethernet
GUID: 00000000-0000-0000-0000-000000000002
DHCP: Disabled
IPAddress: 0.0.0.0
NetworkMask: 0.0.0.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: xx:xx:xx:xx:xx:02
MediumType: Ethernet
Wireless: No
Status: Up
VBoxNetworkName: HostInterfaceNetworking-en0
Name: bridge100
GUID: 00000000-0000-0000-0000-000000000003
DHCP: Disabled
IPAddress: 192.168.61.1
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: xx:xx:xx:xx:xx:03
MediumType: Ethernet
Wireless: No
Status: Up
VBoxNetworkName: HostInterfaceNetworking-bridge100
Name: en2: Thunderbolt 1
GUID: 00000000-0000-0000-0000-000000000004
DHCP: Disabled
IPAddress: 0.0.0.0
NetworkMask: 0.0.0.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: xx:xx:xx:xx:xx:04
MediumType: Ethernet
Wireless: No
Status: Up
VBoxNetworkName: HostInterfaceNetworking-en2
Name: bridge101
GUID: 00000000-0000-0000-0000-000000000005
DHCP: Disabled
IPAddress: 192.168.22.1
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: xx:xx:xx:xx:xx:05
MediumType: Ethernet
Wireless: No
Status: Up
VBoxNetworkName: HostInterfaceNetworking-bridge101)
VBOX_HOSTONLYNETS=%(Name: vagrantnet-vbox1
GUID: 10000000-0000-0000-0000-000000000000
State: Enabled
NetworkMask: 255.255.255.0
LowerIP: 192.168.61.0
UpperIP: 192.168.61.0
VBoxNetworkName: hostonly-vagrantnet-vbox1
Name: vagrantnet-vbox2
GUID: 20000000-0000-0000-0000-000000000000
State: Enabled
NetworkMask: 255.255.255.0
LowerIP: 192.168.22.0
UpperIP: 192.168.22.0
VBoxNetworkName: hostonly-vagrantnet-vbox2)
VBOX_HOSTONLYNETS=%(Name: vagrantnet-vbox1
GUID: 10000000-0000-0000-0000-000000000000
State: Enabled
NetworkMask: 255.255.255.0
LowerIP: 192.168.61.0
UpperIP: 192.168.61.0
VBoxNetworkName: hostonly-vagrantnet-vbox1
Name: vagrantnet-vbox2
GUID: 20000000-0000-0000-0000-000000000000
State: Enabled
NetworkMask: 255.255.255.0
LowerIP: 192.168.22.0
UpperIP: 192.168.22.0
VBoxNetworkName: hostonly-vagrantnet-vbox2)
VBOX_RANGE_HOSTONLYNETS=%(Name: vagrantnet-vbox1
GUID: 10000000-0000-0000-0000-000000000000
State: Enabled
NetworkMask: 255.255.255.0
LowerIP: 192.168.61.10
UpperIP: 192.168.61.100
VBoxNetworkName: hostonly-vagrantnet-vbox1
Name: vagrantnet-vbox2
GUID: 20000000-0000-0000-0000-000000000000
State: Enabled
NetworkMask: 255.255.255.0
LowerIP: 192.168.22.0
UpperIP: 192.168.22.0
VBoxNetworkName: hostonly-vagrantnet-vbox2)
VBOX_GUEST_HOSTONLYVNETS_INFO=%(
natnet1="nat"
macaddress1="080027BB1475"
cableconnected1="on"
nic1="nat"
nictype1="82540EM"
nicspeed1="0"
mtu="0"
sockSnd="64"
sockRcv="64"
tcpWndSnd="64"
tcpWndRcv="64"
Forwarding(0)="ssh,tcp,127.0.0.1,2222,,22"
hostonly-network2="vagrantnet-vbox1"
macaddress2="080027FBC15B"
cableconnected2="on"
nic2="hostonlynetwork"
nictype2="82540EM"
nicspeed2="0"
nic3="none"
nic4="none"
nic5="none"
nic6="none"
nic7="none"
nic8="none"
)

View File

@ -22,11 +22,11 @@ shared_examples "a version 5.x virtualbox driver" do |options|
it "enables SharedFoldersEnableSymlinksCreate if true" do
expect(subprocess).to receive(:execute).
with("VBoxManage", "setextradata", anything, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/folder", "1", {:notify=>[:stdout, :stderr]}).
with("VBoxManage", "setextradata", anything, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/folder", "1", {:env => {:LANG => "C"}, :notify=>[:stdout, :stderr]}).
and_return(subprocess_result(exit_code: 0))
expect(subprocess).to receive(:execute).
with("VBoxManage", "sharedfolder", "add", anything, "--name", "folder", "--hostpath", "/Users/brian/vagrant-folder", {:notify=>[:stdout, :stderr]}).
with("VBoxManage", "sharedfolder", "add", anything, "--name", "folder", "--hostpath", "/Users/brian/vagrant-folder", {:env => {:LANG => "C"}, :notify=>[:stdout, :stderr]}).
and_return(subprocess_result(exit_code: 0))
subject.share_folders(folders)
@ -34,11 +34,11 @@ shared_examples "a version 5.x virtualbox driver" do |options|
it "enables automount if option is true" do
expect(subprocess).to receive(:execute).
with("VBoxManage", "setextradata", anything, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/folder", "1", {:notify=>[:stdout, :stderr]}).
with("VBoxManage", "setextradata", anything, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/folder", "1", {:env => {:LANG => "C"}, :notify=>[:stdout, :stderr]}).
and_return(subprocess_result(exit_code: 0))
expect(subprocess).to receive(:execute).
with("VBoxManage", "sharedfolder", "add", anything, "--name", "folder", "--hostpath", "/Users/brian/vagrant-folder", "--automount", {:notify=>[:stdout, :stderr]}).
with("VBoxManage", "sharedfolder", "add", anything, "--name", "folder", "--hostpath", "/Users/brian/vagrant-folder", "--automount", {:env => {:LANG => "C"}, :notify=>[:stdout, :stderr]}).
and_return(subprocess_result(exit_code: 0))
subject.share_folders(folders_automount)
@ -46,7 +46,7 @@ shared_examples "a version 5.x virtualbox driver" do |options|
it "disables SharedFoldersEnableSymlinksCreate if false" do
expect(subprocess).to receive(:execute).
with("VBoxManage", "sharedfolder", "add", anything, "--name", "folder", "--hostpath", "/Users/brian/vagrant-folder", {:notify=>[:stdout, :stderr]}).
with("VBoxManage", "sharedfolder", "add", anything, "--name", "folder", "--hostpath", "/Users/brian/vagrant-folder", {:env => {:LANG => "C"}, :notify=>[:stdout, :stderr]}).
and_return(subprocess_result(exit_code: 0))
subject.share_folders(folders_disabled)

View File

@ -23,6 +23,7 @@ describe VagrantPlugins::Ansible::Cap::Guest::Debian::AnsibleInstall do
before do
allow(machine).to receive(:communicate).and_return(communicator)
allow(communicator).to receive(:execute).and_return(true)
allow(communicator).to receive(:test).and_return(false)
end
describe "#ansible_install" do

View File

@ -2,6 +2,8 @@
shared_examples_for "Ansible setup via pip" do
describe "when install_mode is :pip" do
before { allow(communicator).to receive(:test) }
it "installs pip and calls Cap::Guest::Pip::pip_install" do
expect(communicator).to receive(:sudo).at_least(1).times.ordered
expect(VagrantPlugins::Ansible::Cap::Guest::Pip).to receive(:pip_install).once.ordered.
@ -12,6 +14,8 @@ shared_examples_for "Ansible setup via pip" do
end
describe "when install_mode is :pip_args_only" do
before { allow(communicator).to receive(:test) }
it "installs pip and calls Cap::Guest::Pip::pip_install with 'pip_args' parameter" do
pip_args = "-r /vagrant/requirements.txt"
@ -27,30 +31,57 @@ end
shared_examples_for "Ansible setup via pip on Debian-based systems" do
describe "installs required Debian packages and..." do
before { allow(communicator).to receive(:test) }
pip_install_cmd = "foo"
it "calls Cap::Guest::Pip::get_pip with 'pip' install_mode" do
expect(communicator).to receive(:sudo).once.ordered.
expect(communicator).to receive(:sudo).
with("apt-get update -y -qq")
expect(communicator).to receive(:sudo).once.ordered.
expect(communicator).to receive(:sudo).
with("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --option \"Dpkg::Options::=--force-confold\" build-essential curl git libssl-dev libffi-dev python-dev")
expect(communicator).to receive(:sudo).once.ordered.
expect(communicator).to receive(:sudo).
with("pip install --upgrade ansible")
subject.ansible_install(machine, :pip, "", "", pip_install_cmd)
end
it "calls Cap::Guest::Pip::get_pip with 'pip_args_only' install_mode" do
expect(communicator).to receive(:sudo).once.ordered.
expect(communicator).to receive(:sudo).
with("apt-get update -y -qq")
expect(communicator).to receive(:sudo).once.ordered.
expect(communicator).to receive(:sudo).
with("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --option \"Dpkg::Options::=--force-confold\" build-essential curl git libssl-dev libffi-dev python-dev")
expect(communicator).to receive(:sudo).once.ordered.
expect(communicator).to receive(:sudo).
with("pip install")
subject.ansible_install(machine, :pip_args_only, "", "", pip_install_cmd)
end
context "when python-dev-is-python3 package is available" do
before { allow(communicator).to receive(:test).with("apt-cache show python-dev-is-python3").and_return(true) }
it "calls Cap::Guest::Pip::get_pip with 'pip' install_mode" do
expect(communicator).to receive(:sudo).
with("apt-get update -y -qq")
expect(communicator).to receive(:sudo).
with("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --option \"Dpkg::Options::=--force-confold\" build-essential curl git libssl-dev libffi-dev python-dev-is-python3")
expect(communicator).to receive(:sudo).
with("pip install --upgrade ansible")
subject.ansible_install(machine, :pip, "", "", pip_install_cmd)
end
it "calls Cap::Guest::Pip::get_pip with 'pip_args_only' install_mode" do
expect(communicator).to receive(:sudo).
with("apt-get update -y -qq")
expect(communicator).to receive(:sudo).
with("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --option \"Dpkg::Options::=--force-confold\" build-essential curl git libssl-dev libffi-dev python-dev-is-python3")
expect(communicator).to receive(:sudo).
with("pip install")
subject.ansible_install(machine, :pip_args_only, "", "", pip_install_cmd)
end
end
end
it_behaves_like "Ansible setup via pip"

View File

@ -91,7 +91,7 @@ VF
expect(args[1]).to eq("--connection=ssh")
expect(args[2]).to eq("--timeout=30")
inventory_count = args.count { |x| x =~ /^--inventory-file=.+$/ }
inventory_count = args.count { |x| x.match(/^--inventory-file=.+$/) if x.is_a?(String) }
expect(inventory_count).to be > 0
expect(args[args.length-2]).to eq("playbook.yml")
@ -100,9 +100,9 @@ VF
it "sets --limit argument" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with('ansible-playbook', any_args) { |*args|
all_limits = args.select { |x| x =~ /^(--limit=|-l)/ }
all_limits = args.select { |x| x.match(/^(--limit=|-l)/) if x.is_a?(String) }
if config.raw_arguments
raw_limits = config.raw_arguments.select { |x| x =~ /^(--limit=|-l)/ }
raw_limits = config.raw_arguments.select { |x| x.match(/^(--limit=|-l)/) if x.is_a?(String) }
expect(all_limits.length - raw_limits.length).to eq(1)
expect(all_limits.last).to eq(raw_limits.last)
else
@ -181,7 +181,7 @@ VF
it "generates an inventory with all active machines" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with('ansible-playbook', any_args) { |*args|
expect(config.inventory_path).to be_nil
expect(File.exists?(generated_inventory_file)).to be(true)
expect(File.exist?(generated_inventory_file)).to be(true)
inventory_content = File.read(generated_inventory_file)
_ssh = config.compatibility_mode == VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0 ? "" : "_ssh"
if with_user
@ -697,7 +697,7 @@ VF
it "generates an inventory with winrm connection settings" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with('ansible-playbook', any_args) { |*args|
expect(config.inventory_path).to be_nil
expect(File.exists?(generated_inventory_file)).to be(true)
expect(File.exist?(generated_inventory_file)).to be(true)
inventory_content = File.read(generated_inventory_file)
expect(inventory_content).to include("machine1 ansible_connection=winrm ansible_ssh_host=127.0.0.1 ansible_ssh_port=55986 ansible_ssh_user='winner' ansible_ssh_pass='winword'\n")
@ -731,7 +731,7 @@ VF
expect(Vagrant::Util::Subprocess).to receive(:execute).with('ansible-playbook', any_args) { |*args|
expect(args).to include("--inventory-file=#{existing_file}")
expect(args).not_to include("--inventory-file=#{generated_inventory_file}")
expect(File.exists?(generated_inventory_file)).to be(false)
expect(File.exist?(generated_inventory_file)).to be(false)
}.and_return(default_execute_result)
end

View File

@ -343,6 +343,19 @@ describe VagrantPlugins::SyncedFolderRSync::RsyncHelper do
allow(guest).to receive(:capability?){ false }
end
context "with extra args defined" do
before { ssh_info[:extra_args] = ["-o", "Compression=yes"] }
it "appends the extra arguments from ssh_info" do
expect(Vagrant::Util::Subprocess).to receive(:execute) { |*args|
cmd = args.detect { |a| a.is_a?(String) && a.start_with?("ssh") }
expect(cmd).to be
expect(cmd).to include("-o Compression=yes")
}.and_return(result)
subject.rsync_single(machine, ssh_info, opts)
end
end
context "with an IPv6 address" do
before { ssh_info[:host] = "fe00::0" }

View File

@ -3,7 +3,7 @@ require File.expand_path("../../base", __FILE__)
require "pathname"
require 'tempfile'
describe Vagrant::BoxCollection, :skip_windows do
describe Vagrant::BoxCollection, :skip_windows, :bsdtar do
include_context "unit"
let(:box_class) { Vagrant::Box }

View File

@ -12,7 +12,7 @@ describe Vagrant::Util::InstallZSHShellConfig do
describe "#shell_installed" do
it "should return path to config file if exists" do
allow(File).to receive(:exists?).with(target_file).and_return(true)
allow(File).to receive(:exist?).with(target_file).and_return(true)
expect(subject.shell_installed(home)).to eq(target_file)
end
@ -36,7 +36,7 @@ describe Vagrant::Util::InstallZSHShellConfig do
describe "#install" do
it "installs autocomplete" do
allow(File).to receive(:exists?).with(target_file).and_return(true)
allow(File).to receive(:exist?).with(target_file).and_return(true)
allow(File).to receive(:foreach).with(target_file).and_yield("nothing")
expect(File).to receive(:open).with(target_file, "a")
subject.install(home)
@ -67,4 +67,4 @@ describe Vagrant::Util::InstallCLIAutocomplete do
expect{ subject.install(["oops"]) }.to raise_error(ArgumentError)
end
end
end
end

View File

@ -12,7 +12,7 @@ Gem::Specification.new do |s|
s.summary = "Build and distribute virtualized development environments."
s.description = "Vagrant is a tool for building and distributing virtualized development environments."
s.required_ruby_version = ">= 2.6", "< 3.2"
s.required_ruby_version = ">= 3.0", "< 3.3"
s.required_rubygems_version = ">= 1.3.6"
s.add_dependency "bcrypt_pbkdf", "~> 1.1"
@ -22,23 +22,23 @@ Gem::Specification.new do |s|
s.add_dependency 'googleapis-common-protos-types', '~> 1.3'
s.add_dependency "grpc"
s.add_dependency "hashicorp-checkpoint", "~> 0.1.5"
s.add_dependency "i18n", "~> 1.8"
s.add_dependency "listen", "~> 3.6"
s.add_dependency "i18n", "~> 1.12"
s.add_dependency "listen", "~> 3.7"
s.add_dependency "log4r", "~> 1.1.9", "< 1.1.11"
s.add_dependency "mime-types", "~> 3.3"
s.add_dependency "net-ftp", "~> 0.1"
s.add_dependency "net-ssh", ">= 6.1.0", "< 6.2"
s.add_dependency "net-sftp", "~> 3.0"
s.add_dependency "net-scp", "~> 3.0.0"
s.add_dependency "net-ftp", "~> 0.2"
s.add_dependency "net-ssh", "~> 7.0"
s.add_dependency "net-sftp", "~> 4.0"
s.add_dependency "net-scp", "~> 4.0"
s.add_dependency "rb-kqueue", "~> 0.2.0"
s.add_dependency "rexml", "~> 3.2"
s.add_dependency "rgl", "~> 0.5.7"
s.add_dependency "rubyzip", "~> 2.0"
s.add_dependency "rgl", "~> 0.5.10"
s.add_dependency "rubyzip", "~> 2.3.2"
s.add_dependency "vagrant_cloud", "~> 3.0.5"
s.add_dependency "wdm", "~> 0.1.0"
s.add_dependency "winrm", ">= 2.3.4", "< 3.0"
s.add_dependency "winrm-elevated", ">= 1.2.1", "< 2.0"
s.add_dependency "winrm-fs", ">= 1.3.4", "< 2.0"
s.add_dependency "wdm", "~> 0.1.1"
s.add_dependency "winrm", ">= 2.3.6", "< 3.0"
s.add_dependency "winrm-elevated", ">= 1.2.3", "< 2.0"
s.add_dependency "winrm-fs", ">= 1.3.5", "< 2.0"
# Needed for go generate to use grpc_tools_ruby_protoc
s.add_development_dependency "grpc-tools", "~> 1.41"
@ -49,7 +49,7 @@ Gem::Specification.new do |s|
# Constraint rake to properly handle deprecated method usage
# from within rspec
s.add_development_dependency "rake", "~> 13.0"
s.add_development_dependency "rspec", "~> 3.11.0"
s.add_development_dependency "rspec", "~> 3.11"
s.add_development_dependency "rspec-its", "~> 1.3.0"
s.add_development_dependency "fake_ftp", "~> 0.3.0"
s.add_development_dependency "webrick", "~> 1.7.0"

View File

@ -1 +1 @@
2.3.2.dev
2.3.5.dev

View File

@ -1,6 +1,21 @@
######################################################
# NOTE: This file is managed by the Digital Team's #
# Terraform configuration @ hashicorp/mktg-terraform #
######################################################
.DEFAULT_GOAL := website
# Set the preview mode for the website shell to "developer" or "io"
PREVIEW_MODE ?= developer
REPO ?= vagrant
# Enable setting alternate docker tool, e.g. 'make DOCKER_CMD=podman'
DOCKER_CMD ?= docker
CURRENT_GIT_BRANCH=$$(git rev-parse --abbrev-ref HEAD)
LOCAL_CONTENT_DIR=
PWD=$$(pwd)
DOCKER_IMAGE="hashicorp/dev-portal"
DOCKER_IMAGE_LOCAL="dev-portal-local"
DOCKER_RUN_FLAGS=-it \
@ -13,22 +28,31 @@ DOCKER_RUN_FLAGS=-it \
--volume "$(PWD)/redirects.js:/app/redirects.js" \
--volume "next-dir:/app/website-preview/.next" \
--volume "$(PWD)/.env:/app/.env" \
-e "REPO=vagrant"
-e "REPO=$(REPO)" \
-e "PREVIEW_FROM_REPO=$(REPO)" \
-e "IS_CONTENT_PREVIEW=true" \
-e "LOCAL_CONTENT_DIR=$(LOCAL_CONTENT_DIR)" \
-e "CURRENT_GIT_BRANCH=$(CURRENT_GIT_BRANCH)" \
-e "PREVIEW_MODE=$(PREVIEW_MODE)"
# Default: run this if working on the website locally to run in watch mode.
.PHONY: website
website:
@echo "==> Downloading latest Docker image..."
@docker pull $(DOCKER_IMAGE)
@$(DOCKER_CMD) pull $(DOCKER_IMAGE)
@echo "==> Starting website..."
@docker run $(DOCKER_RUN_FLAGS) $(DOCKER_IMAGE)
@$(DOCKER_CMD) run $(DOCKER_RUN_FLAGS) $(DOCKER_IMAGE)
# Use this if you have run `website/build-local` to use the locally built image.
.PHONY: website/local
website/local:
@echo "==> Starting website from local image..."
@docker run $(DOCKER_RUN_FLAGS) $(DOCKER_IMAGE_LOCAL)
@$(DOCKER_CMD) run $(DOCKER_RUN_FLAGS) $(DOCKER_IMAGE_LOCAL)
# Run this to generate a new local Docker image.
.PHONY: website/build-local
website/build-local:
@echo "==> Building local Docker image"
@docker build https://github.com/hashicorp/dev-portal.git\#main \
@$(DOCKER_CMD) build https://github.com/hashicorp/dev-portal.git\#main \
-t $(DOCKER_IMAGE_LOCAL)

View File

@ -77,7 +77,6 @@ This file can be standard Markdown and also supports [YAML frontmatter](https://
title: 'My Title'
description: "A thorough, yet succinct description of the page's contents"
---
```
The significant keys in the YAML frontmatter are:
@ -95,12 +94,12 @@ There is currently a small bug with new page creation - if you create a new page
There are several custom markdown plugins that are available by default that enhance [standard markdown](https://commonmark.org/) to fit our use cases. This set of plugins introduces a couple instances of custom syntax, and a couple specific pitfalls that are not present by default with markdown, detailed below:
- If you see the symbols `~>`, `->`, `=>`, or `!>`, these represent [custom alerts](https://github.com/hashicorp/remark-plugins/tree/master/plugins/paragraph-custom-alerts#paragraph-custom-alerts). These render as colored boxes to draw the user's attention to some type of aside.
- > **Warning**: We are deprecating the current [paragraph alerts](https://github.com/hashicorp/remark-plugins/tree/master/plugins/paragraph-custom-alerts#paragraph-custom-alerts), in favor of the newer [MDX Inline Alert](#inline-alerts) components. The legacy paragraph alerts are represented by the symbols `~>`, `->`, `=>`, or `!>`.
- If you see `@include '/some/path.mdx'`, this is a [markdown include](https://github.com/hashicorp/remark-plugins/tree/master/plugins/include-markdown#include-markdown-plugin). It's worth noting as well that all includes resolve from `website/content/partials` by default, and that changes to partials will not live-reload the website.
- If you see `# Headline ((#slug))`, this is an example of an [anchor link alias](https://github.com/hashicorp/remark-plugins/tree/je.anchor-link-adjustments/plugins/anchor-links#anchor-link-aliases). It adds an extra permalink to a headline for compatibility and is removed from the output.
- Due to [automatically generated permalinks](https://github.com/hashicorp/remark-plugins/tree/je.anchor-link-adjustments/plugins/anchor-links#anchor-links), any text changes to _headlines_ or _list items that begin with inline code_ can and will break existing permalinks. Be very cautious when changing either of these two text items.
Headlines are fairly self-explanitory, but here's an example of how list items that begin with inline code look.
Headlines are fairly self-explanatory, but here's an example of how to list items that begin with inline code look.
```markdown
- this is a normal list item
@ -120,13 +119,51 @@ There are several custom markdown plugins that are available by default that enh
A number of custom [mdx components](https://mdxjs.com/) are available for use within any `.mdx` file. Each one is documented below:
#### Inline Alerts
There are custom MDX components available to author alert data. [See the full documentation here](https://developer.hashicorp.com/swingset/components/mdxinlinealert). They render as colored boxes to draw the user's attention to some type of aside.
```mdx
## Alert types
### Tip
<Tip>
To provide general information to the user regarding the current context or
relevant actions.
</Tip>
### Highlight
<Highlight>
To provide general or promotional information to the user prominently.
</Highlight>
### Note
<Note>
To help users avoid an issue. Provide guidance and actions if possible.
</Note>
### Warning
<Warning>
To indicate critical issues that need immediate action or help users
understand something critical.
</Warning>
## Title override prop
<Note title="Hashiconf 2027">To provide general information.</Note>
```
#### Tabs
The `Tabs` component creates tabbed content of any type, but is often used for code examples given in different languages. Here's an example of how it looks from the Vagrant documentation website:
![Tabs Component](https://p176.p0.n0.cdn.getcloudapp.com/items/WnubALZ4/Screen%20Recording%202020-06-11%20at%2006.03%20PM.gif?v=1de81ea720a8cc8ade83ca64fb0b9edd)
> Please refer to the [Swingset](https://react-components.vercel.app/?component=Tabs) documention for the latest examples and API reference.
> Please refer to the [Swingset](https://react-components.vercel.app/?component=Tabs) documentation for the latest examples and API reference.
It can be used as such within a markdown file:
@ -150,7 +187,7 @@ $ curl ...
</Tab>
</Tabs>
Contined normal markdown content
Continued normal markdown content
````
The intentionally skipped line is a limitation of the mdx parser which is being actively worked on. All tabs must have a heading, and there is no limit to the number of tabs, though it is recommended to go for a maximum of three or four.
@ -404,7 +441,7 @@ This configuration would display something like the following text on the websit
A {{ release candidate }} for <Product> {{ v1.0.0 }} is available! The release can be <a href='https://releases.hashicorp.com/<product>/{{ 1.0.0-rc1 }}'>downloaded here</a>.
```
You may customize the parameters in any way you'd like. To remove a prerelease from the website, simply delete the `prerelease` paremeter from the above component.
You may customize the parameters in any way you'd like. To remove a prerelease from the website, simply delete the `prerelease` parameter from the above component.
<!-- END: releases -->
@ -448,7 +485,7 @@ One more example - let's say that content is being moved to an external website.
}
```
If we no longer want the link to be in the side nav, we can simply remove it. If we do still want the link in the side nav, but pointing to an external destnation, we need to slightly change the structure as such:
If we no longer want the link to be in the side nav, we can simply remove it. If we do still want the link in the side nav, but pointing to an external destination, we need to slightly change the structure as such:
```js
{
@ -472,9 +509,9 @@ It's also worth noting that it is possible to do glob-based redirects, for examp
We support the following browsers targeting roughly the versions specified.
| ![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_24x24.png) | ![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_24x24.png) | ![Opera](https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_24x24.png) | ![Safari](https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_24x24.png) | ![Internet Explorer](https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_24x24.png) |
| --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| **Latest** | **Latest** | **Latest** | **Latest** | **11+** |
| ![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome.svg) | ![Edge](https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge.svg) | ![Opera](https://raw.githubusercontent.com/alrra/browser-logos/main/src/opera/opera.svg) | ![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox.svg) | ![Safari](https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari/safari.svg) |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| **Latest** | **Latest** | **Latest** | **Latest** | **Latest** |
<!-- END: browser-support -->

View File

@ -40,7 +40,7 @@ following:
- SSH user so Vagrant can connect
- Perhaps Chef, Puppet, etc. but not strictly required.
In addition to this, each [provider](/docs/providers/) may require
In addition to this, each [provider](/vagrant/docs/providers/) may require
additional software. For example, if you are making a base box for VirtualBox,
you will want to include the VirtualBox guest additions so that shared folders
work properly. But if you are making an AWS base box, this is not required.
@ -58,16 +58,16 @@ boxes.
Provider-specific guides for creating base boxes are linked below:
- [Docker Base Boxes](/docs/providers/docker/boxes)
- [Hyper-V Base Boxes](/docs/providers/hyperv/boxes)
- [VMware Base Boxes](/docs/providers/vmware/boxes)
- [VirtualBox Base Boxes](/docs/providers/virtualbox/boxes)
- [Docker Base Boxes](/vagrant/docs/providers/docker/boxes)
- [Hyper-V Base Boxes](/vagrant/docs/providers/hyperv/boxes)
- [VMware Base Boxes](/vagrant/docs/providers/vmware/boxes)
- [VirtualBox Base Boxes](/vagrant/docs/providers/virtualbox/boxes)
### Packer and Vagrant Cloud
We strongly recommend using [Packer](https://www.packer.io) to create reproducible
We strongly recommend using [Packer](https://www.packer.io/) to create reproducible
builds for your base boxes, as well as automating the builds. Read more about
[automating Vagrant box creation with Packer](https://www.packer.io/guides/packer-on-cicd/build-image-in-cicd)
[automating Vagrant box creation with Packer](/packer/guides/packer-on-cicd/build-image-in-cicd)
in the Packer documentation.
### Disk Space
@ -282,7 +282,7 @@ provider-specific guides are linked to towards the top of this page.
You can distribute the box file however you would like. However, if you want
to support versioning, putting multiple providers at a single URL, pushing
updates, analytics, and more, we recommend you add the box to
[HashiCorp's Vagrant Cloud](/vagrant-cloud).
[HashiCorp's Vagrant Cloud](/vagrant/vagrant-cloud).
You can upload both public and private boxes to this service.

View File

@ -10,7 +10,7 @@ description: |-
In the past, boxes were just [tar files](<https://en.wikipedia.org/wiki/Tar_(computing)>)
of VirtualBox exports. With Vagrant supporting multiple
[providers](/docs/providers/) and [versioning](/docs/boxes/versioning)
[providers](/vagrant/docs/providers/) and [versioning](/vagrant/docs/boxes/versioning)
now, box files are slightly more complicated.
Box files made for Vagrant 1.0.x (the VirtualBox export `tar` files) continue
@ -26,7 +26,7 @@ Today, there are three different components:
box file and so on.
- Box Catalog Metadata - This is a JSON document (typically exchanged
during interactions with [HashiCorp's Vagrant Cloud](/vagrant-cloud))
during interactions with [HashiCorp's Vagrant Cloud](/vagrant/vagrant-cloud))
that specifies the name of the box, a description, available
versions, available providers, and URLs to the actual box files
(next component) for each provider and version. If this catalog
@ -35,7 +35,7 @@ Today, there are three different components:
- Box Information - This is a JSON document that can provide additional
information about the box that displays when a user runs
`vagrant box list -i`. More information is provided [here](/docs/boxes/info).
`vagrant box list -i`. More information is provided [here](/vagrant/docs/boxes/info).
The first two components are covered in more detail below.
@ -47,7 +47,7 @@ are supported for legacy reasons in 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](/docs/providers/). Vagrant core itself only unpacks
[provider](/vagrant/docs/providers/). Vagrant core itself only unpacks
the boxes for use later.
Within the archive, Vagrant does expect a single file:
@ -80,11 +80,11 @@ file.
## Box Metadata
The metadata is an optional component for a box (but highly recommended)
that enables [versioning](/docs/boxes/versioning), updating, multiple
that enables [versioning](/vagrant/docs/boxes/versioning), updating, multiple
providers from a single file, and more.
-> **You do not need to manually make the metadata.** If you
have an account with [HashiCorp's Vagrant Cloud](/vagrant-cloud), you
have an account with [HashiCorp's Vagrant Cloud](/vagrant/vagrant-cloud), you
can create boxes there, and HashiCorp's Vagrant Cloud automatically creates
the metadata for you. The format is still documented here.

View File

@ -1,71 +1,62 @@
---
layout: docs
page_title: Boxes
page_title: Vagrant Boxes
description: |-
Boxes are the package format for Vagrant environments. A box can be used by
anyone on any platform that Vagrant supports to bring up an identical
working environment.
---
# Boxes
# Vagrant boxes
Boxes are the package format for Vagrant environments. A box can be used by
anyone on any platform that Vagrant supports to bring up an identical
working environment.
Boxes are the package format for Vagrant environments. You specify a box environment and operating configurations in your [Vagrantfile](/vagrant/docs/vagrantfile). You can use a box on any [supported platform](/vagrant/downloads) to bring up identical working environments. To enable teams to use and manage the same boxes, [versions are supported](/vagrant/docs/boxes/versioning).
The `vagrant box` utility provides all the functionality for managing
boxes. You can read the documentation on the [vagrant box](/docs/cli/box)
~> **Note**: Boxes require a provider, a virtualization product, to operate. Before you can use a box,
ensure that you have properly installed a supported [provider](/vagrant/docs/providers).
The quickest way to get started is to select a pre-defined box environment from the
[publicly available catalog on Vagrant Cloud](https://vagrantcloud.com/boxes/search).
You can also add and share your own customized boxes on Vagrant Cloud.
The `vagrant box` CLI utility provides all the functionality for box management. You can read the documentation on the [vagrant box](/vagrant/docs/cli/box)
command for more information.
The easiest way to use a box is to add a box from the
[publicly available catalog of Vagrant boxes](https://vagrantcloud.com/boxes/search).
You can also add and share your own customized boxes on this website.
## Discover boxes
Boxes also support versioning so that members of your team using Vagrant
can update the underlying box easily, and the people who create boxes
can push fixes and communicate these fixes efficiently.
You can learn all about boxes by reading this page as well as the
sub-pages in the navigation to the left.
## Discovering Boxes
The easiest way to find boxes is to look on the
To find boxes, explore the
[public Vagrant box catalog](https://vagrantcloud.com/boxes/search)
for a box matching your use case. The catalog contains most major operating
systems as bases, as well as specialized boxes to get you up and running
quickly with LAMP stacks, Ruby, Python, etc.
for a box that matches your use case. The catalog contains most major operating
systems as bases, as well as specialized boxes to get you started with common
configurations such as LAMP stacks, Ruby, and Python.
The boxes on the public catalog work with many different
[providers](/docs/providers/). Whether you are using Vagrant with
VirtualBox, VMware, AWS, etc. you should be able to find a box you need.
[providers](/vagrant/docs/providers/). The list of supported providers is located in the box descriptions.
Adding a box from the catalog is very easy. Each box shows you instructions
with how to add it, but they all follow the same format:
### Add a box
```shell-session
$ vagrant box add USER/BOX
```
You can add a box from the public catalog at any time. The box's description includes instructions
on how to add it to an existing Vagrantfile or initiate it as a new environment on the command-line.
For example: `vagrant box add hashicorp/bionic64`. You can also quickly
initialize a Vagrant environment with `vagrant init hashicorp/bionic64`.
~> **Namespaces do not guarantee canonical boxes!** A common misconception is
that a namespace like "ubuntu" represents the canonical space for Ubuntu boxes.
A common misconception is
that a namespace like "ubuntu" represents the official space for Ubuntu boxes.
This is untrue. Namespaces on Vagrant Cloud behave very similarly to namespaces on
GitHub, for example. Just as GitHub's support team is unable to assist with
GitHub. Just as GitHub's support team is unable to assist with
issues in someone's repository, HashiCorp's support team is unable to assist
with third-party published boxes.
## Official Boxes
## Official boxes
HashiCorp (the makers of Vagrant) publish a basic Ubuntu 18.04 64-bit box that is available for minimal use cases. It is highly optimized, small in size, and includes support for VirtualBox, Hyper-V, and VMware. You can use it like this:
There are only two officially-recommended box sets.
HashiCorp publishes a basic Ubuntu 18.04 64-bit box that is available for minimal use cases. It is highly optimized, small in size, and includes support for VirtualBox, Hyper-V, and VMware.
To get started, use the `init` command to initialize your environment.
```shell-session
$ vagrant init hashicorp/bionic64
```
or you can update your `Vagrantfile` as follows:
If you have an existing Vagrantfile, add `hashicorp/bionic64`.
```ruby
Vagrant.configure("2") do |config|
@ -73,10 +64,15 @@ Vagrant.configure("2") do |config|
end
```
For other users, we recommend the [Bento boxes](https://vagrantcloud.com/bento). The Bento boxes are [open source](https://github.com/chef/bento) and built for a number of providers including VMware, VirtualBox, and Parallels. There are a variety of operating systems and versions available.
These are the only two officially-recommended box sets.
For other base operating system environments, we recommend the [Bento boxes](https://vagrantcloud.com/bento). The Bento boxes are [open source](https://github.com/chef/bento) and built for a number of providers including VMware, VirtualBox, and Parallels. There are a variety of operating systems and versions available.
Special thanks to the Bento project for providing a solid base template for the `hashicorp/bionic64` box.
~> **It is often a point of confusion**, but Canonical (the company that makes the Ubuntu operating system) publishes boxes under the "ubuntu" namespace on Vagrant Cloud. These boxes only support VirtualBox and do not provide an ideal experience for most users. If you encounter issues with these boxes, please try the Bento boxes instead.
It is often a point of confusion but Canonical, the company that makes the Ubuntu operating system, publishes boxes under the "ubuntu" namespace on Vagrant Cloud. These boxes only support VirtualBox.
## Create a box
If you are unable to find a box that meets your specific use case, you can create one. We recommend that you first create a [base box](/vagrant/docs/boxes/base) to have a clean slate to start from when you build future development environments.
Learn more about [box formats](/vagrant/docs/boxes/format) to get started.

View File

@ -23,7 +23,7 @@ hashicorp/bionic64 (virtualbox, 1.0.0)
## Box Info
To accomplish this, you simply need to include a file named `info.json` when
creating a [base box](/docs/boxes/base) which is a JSON document containing
creating a [base box](/vagrant/docs/boxes/base) which is a JSON document containing
any and all relevant information that will be displayed to the user when the
`-i` option is used with `vagrant box list`.
@ -37,5 +37,5 @@ any and all relevant information that will be displayed to the user when the
There are no special keys or values in `info.json`, and Vagrant will print each
key and value on its own line.
The [Box File Format](/docs/boxes/format) provides more information about what
The [Box File Format](/vagrant/docs/boxes/format) provides more information about what
else goes into a Vagrant box.

View File

@ -23,13 +23,13 @@ to Vagrant makes it easy to use and fit nicely into the Vagrant workflow.
This page will cover how to use versioned boxes. It does _not_ cover how
to update your own custom boxes with versions. That is covered in
[creating a base box](/docs/boxes/base).
[creating a base box](/vagrant/docs/boxes/base).
## Viewing Versions and Updating
`vagrant box list` only shows _installed_ versions of boxes. If you want
to see all available versions of a box, you will have to find the box
on [HashiCorp's Vagrant Cloud](/vagrant-cloud). An easy way to find a box
on [HashiCorp's Vagrant Cloud](/vagrant/vagrant-cloud). An easy way to find a box
is to use the url `https://vagrantcloud.com/$USER/$BOX`. For example, for
the `hashicorp/bionic64` box, you can find information about it at
`https://vagrantcloud.com/hashicorp/bionic64`.
@ -47,7 +47,7 @@ command just downloads these updates locally.
## Version Constraints
You can constrain a Vagrant environment to a specific version or versions
of a box using the [Vagrantfile](/docs/vagrantfile/) by specifying
of a box using the [Vagrantfile](/vagrant/docs/vagrantfile/) by specifying
the `config.vm.box_version` option.
If this option is not specified, the latest version is always used. This is
@ -76,7 +76,7 @@ of the format `X.Y.Z` where `X`, `Y`, and `Z` are all positive integers.
## Automatic Update Checking
Using the [Vagrantfile](/docs/vagrantfile/), you can also configure
Using the [Vagrantfile](/vagrant/docs/vagrantfile/), you can also configure
Vagrant to automatically check for updates during any `vagrant up`. This is
enabled by default, but can easily be disabled with
`config.vm.box_check_update = false` in your Vagrantfile.

View File

@ -11,7 +11,7 @@ description: |-
**Command: `vagrant box`**
This is the command used to manage (add, remove, etc.) [boxes](/docs/boxes).
This is the command used to manage (add, remove, etc.) [boxes](/vagrant/docs/boxes).
The main functionality of this command is exposed via even more subcommands:

View File

@ -36,7 +36,7 @@ Vagrant Cloud.
**Command: `vagrant cloud auth login`**
The login command is used to authenticate with [HashiCorp's Vagrant Cloud](/vagrant-cloud)
The login command is used to authenticate with [HashiCorp's Vagrant Cloud](/vagrant/vagrant-cloud)
server. Logging in is only necessary if you are accessing protected boxes.
**Logging in is not a requirement to use Vagrant.** The vast majority
@ -171,7 +171,7 @@ The provider create command is used to create a new provider entry on Vagrant Cl
The `url` argument is expected to be a remote URL that Vagrant Cloud can use
to download the provider. If no `url` is specified, the provider entry can be updated
later with a url or the [upload](#cloud-provider-upload) command can be used to
upload a Vagrant [box file](/docs/boxes).
upload a Vagrant [box file](/vagrant/docs/boxes).
## Cloud Provider Delete
@ -191,7 +191,7 @@ Vagrant Cloud with the given options.
**Command: `vagrant cloud provider upload ORGANIZATION/BOX-NAME PROVIDER-NAME VERSION BOX-FILE`**
The provider upload command will upload a Vagrant [box file](/docs/boxes) to Vagrant Cloud for
The provider upload command will upload a Vagrant [box file](/vagrant/docs/boxes) to Vagrant Cloud for
the specified version and provider.
# Cloud Publish

View File

@ -11,9 +11,9 @@ description: |-
**Command: `vagrant connect NAME`**
The connect command complements the
[share command](/docs/cli/share) by enabling access to shared
[share command](/vagrant/docs/cli/share) by enabling access to shared
environments. You can learn about all the details of Vagrant Share in the
[Vagrant Share section](/docs/share/).
[Vagrant Share section](/vagrant/docs/share/).
The reference of available command-line flags to this command
is available below.

View File

@ -35,4 +35,4 @@ the box installed in the system will still be present on the hard drive. To
return your computer to the state as it was before `vagrant up` command, you
need to use `vagrant box remove`.
For more information, read about the [`vagrant box remove`](/docs/cli/box) command.
For more information, read about the [`vagrant box remove`](/vagrant/docs/cli/box) command.

View File

@ -25,7 +25,7 @@ available by reading the appropriate sub-section available in the left
navigational area of this site.
You may also wish to consult the
[documentation](/docs/other/environmental-variables) regarding the
[documentation](/vagrant/docs/other/environmental-variables) regarding the
environmental variables that can be used to configure and control
Vagrant in a global way.

View File

@ -11,7 +11,7 @@ description: |-
**Command: `vagrant init [name [url]]`**
This initializes the current directory to be a Vagrant environment
by creating an initial [Vagrantfile](/docs/vagrantfile/) if
by creating an initial [Vagrantfile](/vagrant/docs/vagrantfile/) if
one does not already exist.
If a first argument is given, it will prepopulate the `config.vm.box`

View File

@ -11,13 +11,13 @@ description: |-
**Command: `vagrant login`**
The login command is used to authenticate with the
[HashiCorp's Vagrant Cloud](/vagrant-cloud) server. Logging in is only
[HashiCorp's Vagrant Cloud](/vagrant/vagrant-cloud) server. Logging in is only
necessary if you are accessing protected boxes or using
[Vagrant Share](/docs/share/).
[Vagrant Share](/vagrant/docs/share/).
**Logging in is not a requirement to use Vagrant.** The vast majority
of Vagrant does _not_ require a login. Only certain features such as protected
boxes or [Vagrant Share](/docs/share/) require a login.
boxes or [Vagrant Share](/vagrant/docs/share/) require a login.
The reference of available command-line flags to this command
is available below.

View File

@ -14,7 +14,7 @@ is replaced with machine-friendly output.
This mode makes it easy to programmatically execute Vagrant and read data
out of it. This output format is protected by our
[backwards compatibility](/docs/installation/backwards-compatibility)
[backwards compatibility](/vagrant/docs/installation/backwards-compatibility)
policy. Until Vagrant 2.0 is released, however, the machine readable output
may change as we determine more use cases for it. But the backwards
compatibility promise should make it safe to write client libraries to

View File

@ -26,8 +26,8 @@ non-primary subcommands. They're executed just like any other subcommand:
The list of non-primary commands is below. Click on any command to learn
more about it.
- [docker-exec](/docs/providers/docker/commands)
- [docker-logs](/docs/providers/docker/commands)
- [docker-run](/docs/providers/docker/commands)
- [rsync](/docs/cli/rsync)
- [rsync-auto](/docs/cli/rsync-auto)
- [docker-exec](/vagrant/docs/providers/docker/commands)
- [docker-logs](/vagrant/docs/providers/docker/commands)
- [docker-run](/vagrant/docs/providers/docker/commands)
- [rsync](/vagrant/docs/cli/rsync)
- [rsync-auto](/vagrant/docs/cli/rsync-auto)

View File

@ -11,8 +11,8 @@ description: |-
**Command: `vagrant package [name|id]`**
This packages a currently running _VirtualBox_ or _Hyper-V_ environment into a
re-usable [box](/docs/boxes). This command can only be used with
other [providers](/docs/providers/) based on the provider implementation
re-usable [box](/vagrant/docs/boxes). This command can only be used with
other [providers](/vagrant/docs/providers/) based on the provider implementation
and if the provider supports it.
## Options
@ -30,15 +30,15 @@ and if the provider supports it.
tasks.
- `--info path/to/info.json` - The package will include a custom JSON file containing
information to be displayed by the [list](/docs/cli/box#box-list) command when invoked
information to be displayed by the [list](/vagrant/docs/cli/box#box-list) command when invoked
with the `-i` flag
- `--vagrantfile FILE` - Packages a Vagrantfile with the box, that is loaded
as part of the [Vagrantfile load order](/docs/vagrantfile/#load-order)
as part of the [Vagrantfile load order](/vagrant/docs/vagrantfile/#load-order)
when the resulting box is used.
-> **A common misconception** is that the `--vagrantfile`
option will package a Vagrantfile that is used when `vagrant init`
is used with this box. This is not the case. Instead, a Vagrantfile
is loaded and read as part of the Vagrant load process when the box is
used. For more information, read about the [Vagrantfile load order](/docs/vagrantfile/#load-order).
used. For more information, read about the [Vagrantfile load order](/vagrant/docs/vagrantfile/#load-order).

View File

@ -10,7 +10,7 @@ description: |-
**Command: `vagrant plugin`**
This is the command used to manage [plugins](/docs/plugins/).
This is the command used to manage [plugins](/vagrant/docs/plugins/).
The main functionality of this command is exposed via another level
of subcommands:
@ -104,7 +104,7 @@ This command accepts optional command-line flags:
**Command: `vagrant plugin license <name> <license-file>`**
This command installs a license for a proprietary Vagrant plugin,
such as the [VMware Fusion provider](/docs/providers/vmware).
such as the [VMware Fusion provider](/vagrant/docs/providers/vmware).
# Plugin List

View File

@ -37,4 +37,4 @@ $ vagrant port my-machine
- `--machine-readable` - This tells Vagrant to display machine-readable output
instead of the human-friendly output. More information is available in the
[machine-readable output](/docs/cli/machine-readable) documentation.
[machine-readable output](/vagrant/docs/cli/machine-readable) documentation.

View File

@ -10,7 +10,7 @@ description: |-
**Command: `vagrant provision [vm-name]`**
Runs any configured [provisioners](/docs/provisioning/)
Runs any configured [provisioners](/vagrant/docs/provisioning/)
against the running Vagrant managed machine.
This command is a great way to quickly test any provisioners, and is especially

View File

@ -10,8 +10,8 @@ description: |-
**Command: `vagrant reload [name|id]`**
The equivalent of running a [halt](/docs/cli/halt) followed by an
[up](/docs/cli/up).
The equivalent of running a [halt](/vagrant/docs/cli/halt) followed by an
[up](/vagrant/docs/cli/up).
This command is usually required for changes made in the Vagrantfile to
take effect. After making any modifications to the Vagrantfile, a `reload`

View File

@ -12,7 +12,7 @@ description: |-
**Command: `vagrant resume [name|id]`**
This resumes a Vagrant managed machine that was previously suspended,
perhaps with the [suspend command](/docs/cli/suspend).
perhaps with the [suspend command](/vagrant/docs/cli/suspend).
The configured provisioners will not run again, by default. You can force
the provisioners to re-run by specifying the `--provision` flag.

View File

@ -12,7 +12,7 @@ description: |-
**Command: `vagrant rsync-auto`**
This command watches all local directories of any
[rsync synced folders](/docs/synced-folders/rsync) and automatically
[rsync synced folders](/vagrant/docs/synced-folders/rsync) and automatically
initiates an rsync transfer when changes are detected. This command does
not exit until an interrupt is received.
@ -41,7 +41,7 @@ To ensure that the command works properly, you should start `rsync-auto`
only when the machine is running, and shut it down before any machine
state changes.
You can always force a resync with the [rsync](/docs/cli/rsync) command.
You can always force a resync with the [rsync](/vagrant/docs/cli/rsync) command.
## Vagrantfile Changes

View File

@ -9,7 +9,7 @@ description: The "vagrant rsync" command forces a re-sync of any rsync synced fo
**Command: `vagrant rsync`**
This command forces a re-sync of any
[rsync synced folders](/docs/synced-folders/rsync).
[rsync synced folders](/vagrant/docs/synced-folders/rsync).
Note that if you change any settings within the rsync synced folders such
as exclude paths, you will need to `vagrant reload` before this command will

View File

@ -15,7 +15,7 @@ share your Vagrant environment with anyone in the world, enabling collaboration
directly in your Vagrant environment in almost any network environment.
You can learn about all the details of Vagrant Share in the
[Vagrant Share section](/docs/share/).
[Vagrant Share section](/vagrant/docs/share/).
The reference of available command-line flags to this command
is available below.

View File

@ -11,10 +11,10 @@ description: |-
**Command: `vagrant suspend [name|id]`**
This suspends the guest machine Vagrant is managing, rather than fully
[shutting it down](/docs/cli/halt) or [destroying it](/docs/cli/destroy).
[shutting it down](/vagrant/docs/cli/halt) or [destroying it](/vagrant/docs/cli/destroy).
A suspend effectively saves the _exact point-in-time state_ of the machine,
so that when you [resume](/docs/cli/resume) it later, it begins running
so that when you [resume](/vagrant/docs/cli/resume) it later, it begins running
immediately from that point, rather than doing a full boot.
This generally requires extra disk space to store all the contents of the

View File

@ -11,15 +11,16 @@ description: |-
**Command: `vagrant up [name|id]`**
This command creates and configures guest machines according to your
[Vagrantfile](/docs/vagrantfile/).
[Vagrantfile](/vagrant/docs/vagrantfile/).
This is the single most important command in Vagrant, since it is how
any Vagrant machine is created. Anyone using Vagrant must use this command
on a day-to-day basis.
any Vagrant machine is created.
## Options
- `name` - Name of machine defined in [Vagrantfile](/docs/vagrantfile/)
- `name` - Name of machine defined in [Vagrantfile](/vagrant/docs/vagrantfile/). Using
`name` to specify the Vagrant machine to act on must be done from within a
Vagrant project (directory where the Vagrantfile exists).
- `id` - Machine id found with `vagrant global-status`. Using `id` allows
you to call `vagrant up id` from any directory.
@ -37,7 +38,7 @@ on a day-to-day basis.
is supported.
- `--provider x` - Bring the machine up with the given
[provider](/docs/providers/). By default this is "virtualbox".
[provider](/vagrant/docs/providers/). By default this is "virtualbox".
- `--[no-]provision` - Force, or prevent, the provisioners to run.

View File

@ -8,7 +8,7 @@ description: The "vagrant validate" command is used to validate your Vagrantfile
**Command: `vagrant validate`**
This command validates your [Vagrantfile](/docs/vagrantfile/).
This command validates your [Vagrantfile](/vagrant/docs/vagrantfile/).
## Options

View File

@ -39,7 +39,7 @@ or directly `inline` in a Vagrantfile.
option.
Examples of how to define these options can be found in the
[usage documentation](/docs/cloud-init/configuration).
[usage documentation](/vagrant/docs/cloud-init/configuration).
### cloud_init Type

View File

@ -10,8 +10,8 @@ description: Introduction to using cloud-init with Vagrant
change in between releases. Use at your own risk. It currently is not officially
supported or functional.
For examples on how to achieve this, among other use cases, please refer to the [usage](/docs/cloud-init/usage)
For examples on how to achieve this, among other use cases, please refer to the [usage](/vagrant/docs/cloud-init/usage)
guide for more information!
For more information about what options are available for configuring cloud-init, see the
[configuration section](/docs/cloud-init/configuration).
[configuration section](/vagrant/docs/cloud-init/configuration).

View File

@ -17,7 +17,7 @@ VAGRANT_EXPERIMENTAL="cloud_init,disks"
```
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
information about this flag visit the [Experimental docs page](/docs/experimental)
information about this flag visit the [Experimental docs page](/vagrant/docs/experimental)
for more info. Without this flag enabled, any cloud-init configs defined will
not be configured.

View File

@ -19,7 +19,7 @@ VAGRANT_EXPERIMENTAL="disks"
```
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
information about this flag visit the [Experimental docs page](/docs/experimental/)
information about this flag visit the [Experimental docs page](/vagrant/docs/experimental/)
for more info. Without this flag enabled, any disks defined will not be configured.
Because of how Hyper-V handles disk management, a Vagrant guest _must_ be powered
@ -28,5 +28,5 @@ with a guests disk, you will need to `vagrant reload` the guest for any changes
to be applied.
For more information on how to use Hyper-V to configure disks for a guest, refer
to the [general usage](/docs/disks/usage) and [configuration](/docs/disks/configuration)
to the [general usage](/vagrant/docs/disks/usage) and [configuration](/vagrant/docs/disks/configuration)
guide for more information.

View File

@ -19,11 +19,11 @@ VAGRANT_EXPERIMENTAL="disks"
```
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
information about this flag visit the [Experimental docs page](/docs/experimental/)
information about this flag visit the [Experimental docs page](/vagrant/docs/experimental/)
for more info. Without this flag enabled, any disks defined will not be configured.
For examples of how to use the disk feature with Hyper-V, please refer to the
[general disk usage guide](/docs/disks/usage) for more examples.
[general disk usage guide](/vagrant/docs/disks/usage) for more examples.
## provider_config options
@ -32,7 +32,7 @@ Vagrant supports most options for these operations. You should be able to define
the PowerShell specific argument to a given Hyper-V command in the provider_config
hash, and Vagrant should properly pass it along to the command.
To define a provider specific option, please refer to the [Disk Options documentation page](/docs/disks/configuration) for more info.
To define a provider specific option, please refer to the [Disk Options documentation page](/vagrant/docs/disks/configuration) for more info.
### Note about options defined below

View File

@ -14,12 +14,12 @@ for more information on how to use and enable this feature.
Vagrant Disks is a feature that allows users to define what mediums should be attached
to their guests, as well as allowing users to resize their primary disk.
For examples on how to achieve this, among other use cases, please refer to the [usage](/docs/disks/usage)
For examples on how to achieve this, among other use cases, please refer to the [usage](/vagrant/docs/disks/usage)
guide for more information!
For more information about what options are available for configuring disks, see the
[configuration section](/docs/disks/configuration).
[configuration section](/vagrant/docs/disks/configuration).
## Supported Providers
Currently, only VirtualBox is supported. Please refer to the [VirtualBox documentation](/docs/disks/virtualbox) for more information on using disks with the VirtualBox provider!
Currently, only VirtualBox is supported. Please refer to the [VirtualBox documentation](/vagrant/docs/disks/virtualbox) for more information on using disks with the VirtualBox provider!

View File

@ -17,7 +17,7 @@ VAGRANT_EXPERIMENTAL="disks"
```
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
information about this flag visit the [Experimental docs page](/docs/experimental/)
information about this flag visit the [Experimental docs page](/vagrant/docs/experimental/)
for more info. Without this flag enabled, any disks defined will not be configured.
Below are some very simple examples of how to use Vagrant Disks with the VirtualBox provider.

View File

@ -19,7 +19,7 @@ VAGRANT_EXPERIMENTAL="disks"
```
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
information about this flag visit the [Experimental docs page](/docs/experimental/)
information about this flag visit the [Experimental docs page](/vagrant/docs/experimental/)
for more info. Without this flag enabled, any disks defined will not be configured.
**Vagrant currently only supports VirtualBox version 5.x and newer for configuring and
@ -42,7 +42,7 @@ disks to a particular storage controller based on the type of disk configured:
Vagrant will not be able to configure disks of a given type if the associated
storage controller does not exist. In this case, you may use
[provider-specific customizations](/docs/providers/virtualbox/configuration#vboxmanage-customizations)
[provider-specific customizations](/vagrant/docs/providers/virtualbox/configuration#vboxmanage-customizations)
to add a required storage controller.
It should also be noted that storage controllers have different limits for the
@ -51,5 +51,5 @@ maximum number of disks for a storage controller type will result in a Vagrant
error.
For more information on how to use VirtualBox to configure disks for a guest, refer
to the [general usage](/docs/disks/usage) and [configuration](/docs/disks/configuration)
to the [general usage](/vagrant/docs/disks/usage) and [configuration](/vagrant/docs/disks/configuration)
guide for more information.

View File

@ -19,11 +19,11 @@ VAGRANT_EXPERIMENTAL="disks"
```
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
information about this flag visit the [Experimental docs page](/docs/experimental/)
information about this flag visit the [Experimental docs page](/vagrant/docs/experimental/)
for more info. Without this flag enabled, any disks defined will not be configured.
For examples of how to use the disk feature with VirtualBox, please refer to the
[general disk usage guide](/docs/disks/usage) for more examples.
[general disk usage guide](/vagrant/docs/disks/usage) for more examples.
## provider_config options

View File

@ -36,6 +36,6 @@ Vagrant will not decrease the size of a disk.
If snapshots exist for a VM, disk functionality will be limited. Vagrant will return
an error for any actions that are limited due to the existence of snapshots. In order
to restore functionality the snapshots must be removed. This can be done using the
[`vagrant snapshot delete`](/docs/cli/snapshot) command. To delete all snapshots
[`vagrant snapshot delete`](/vagrant/docs/cli/snapshot) command. To delete all snapshots
for a VMware backed VM try `vagrant cap provider delete_all_snapshots --target <target vm name>`.
Note once a snapshot is deleted, it can not be restored.

View File

@ -21,7 +21,7 @@ VAGRANT_EXPERIMENTAL="disks"
```
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
information about this flag visit the [Experimental docs page](/docs/experimental/)
information about this flag visit the [Experimental docs page](/vagrant/docs/experimental/)
for more info. Without this flag enabled, any disks defined will not be configured.
Because of how VMware handles disk management, a Vagrant guest _must_ be powered
@ -30,5 +30,5 @@ with a guests disk, you will need to `vagrant reload` the guest for any changes
to be applied.
For more information on how to use VMware to configure disks for a guest, refer
to the [general usage](/docs/disks/usage) and [configuration](/docs/disks/configuration)
to the [general usage](/vagrant/docs/disks/usage) and [configuration](/vagrant/docs/disks/configuration)
guide for more information.

View File

@ -21,17 +21,17 @@ VAGRANT_EXPERIMENTAL="disks"
```
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
information about this flag visit the [Experimental docs page](/docs/experimental/)
information about this flag visit the [Experimental docs page](/vagrant/docs/experimental/)
for more info. Without this flag enabled, any disks defined will not be configured.
For examples of how to use the disk feature with VMWware, please refer to the
[general disk usage guide](/docs/disks/usage) for more examples.
[general disk usage guide](/vagrant/docs/disks/usage) for more examples.
## provider_config options
Vagrant supports some additional VMWware specific options for specifying disk.
To define a provider specific option, please refer to the [Disk Options documentation page](/docs/disks/configuration) for more info.
To define a provider specific option, please refer to the [Disk Options documentation page](/vagrant/docs/disks/configuration) for more info.
### Note about options defined below

View File

@ -42,22 +42,22 @@ This is a list of all the valid experimental features that Vagrant recognizes:
### `cloud_init`
Enabling this feature allows Vagrant to use the `cloud-init` feature. More
information about these options can be found on the [cloud-init documentation page](/docs/cloud-init/usage)
information about these options can be found on the [cloud-init documentation page](/vagrant/docs/cloud-init/usage)
### `dependency_provisioners`
Enabling this feature allows all provisioners to specify `before` and `after`
options. These options allow provisioners to be configured to run before or after
any given "root" provisioner. More information about these options can be found
on the [base provisioner documentation page](/docs/provisioning/basic_usage)
on the [base provisioner documentation page](/vagrant/docs/provisioning/basic_usage)
### `disks`
Enabling this feature will allow Vagrant to manage and configure virtual hard disks
for certain providers. More information about supported providers and how to
configure disks can be found on the [disk documentation page](/docs/disks)
configure disks can be found on the [disk documentation page](/vagrant/docs/disks)
### `typed_triggers`
Enabling this feature allows triggers to recognize and execute `:type` triggers.
More information about how these should be used can be found on the [trigger documentation page](/docs/triggers/configuration#trigger-types)
More information about how these should be used can be found on the [trigger documentation page](/vagrant/docs/triggers/configuration#trigger-types)

View File

@ -105,7 +105,7 @@ The form of these directories is as follows:
Vagrant-go does not have knowledge of the Vagrant-ruby data directories so does not
have access to that data and vice versa. Both Vagrant-go and Vagrant-ruby
respect the [Vagrant environment variables](/docs/other/environmental-variables/) for
respect the [Vagrant environment variables](/vagrant/docs/other/environmental-variables/) for
setting data directory paths. However, the layout and content of these directories
are different for Vagrant-go and Vagrant-ruby.

View File

@ -14,10 +14,10 @@ Welcome to the documentation for Vagrant - the command line utility for managing
the lifecycle of virtual machines. This website aims to document every feature
of Vagrant from top-to-bottom, covering as much detail as possible. If you are
just getting started with Vagrant, we highly recommended starting with
the [getting started tutorial](https://learn.hashicorp.com/vagrant) on
the [getting started tutorial](/vagrant/tutorials) on
HashiCorp's Learn platform first, and then returning to this page.
The navigation will take you through each component of Vagrant. Click on a
navigation item to get started, or read more about
[why developers, designers, and operators choose Vagrant](/intro)
[why developers, designers, and operators choose Vagrant](/vagrant/intro)
for their needs.

View File

@ -1,45 +1,45 @@
---
layout: docs
page_title: Installing Vagrant
page_title: Install Vagrant
description: |-
Installing Vagrant is extremely easy. Head over to the Vagrant downloads page
and get the appropriate installer or package for your platform. Install the
Vagrant is available for most platforms. Install the Vagrant
package using standard procedures for your operating system.
---
# Installing Vagrant
# Install Vagrant
Installing Vagrant is extremely easy. Head over to the
[Vagrant downloads page](/downloads) and get the appropriate installer or
package for your platform. Install the package using standard procedures for
To get started with Vagrant, download the appropriate installer or
package for your platform from our
[Vagrant downloads page](/vagrant/downloads). Install the package with the standard procedures for
your operating system.
The installer will automatically add `vagrant` to your system path
so that it is available in terminals. If it is not found, please try
logging out and logging back in to your system (this is particularly
necessary sometimes for Windows).
The installer automatically adds `vagrant` to your system path
so that it is available in terminals. If it is not found,
log out and back into your system; this is a common issue for Windows.
~> **Looking for the gem install?** Vagrant 1.0.x had the option to
~> **Rubygem installation is unsupported** Vagrant 1.0.x has the option to
be installed as a [RubyGem](https://en.wikipedia.org/wiki/RubyGems).
This installation method is no longer supported. If you have an old version
of Vagrant installed via Rubygems, please remove it prior to installing newer
However, this installation method is no longer supported. If you have an old version
of Vagrant installed via Rubygems, remove it prior to installing newer
versions of Vagrant.
~> **Beware of system package managers!** Some operating system
distributions include a vagrant package in their upstream package repos.
Please do not install Vagrant in this manner. Typically these packages are
missing dependencies or include very outdated versions of Vagrant. If you
install via your system's package manager, it is very likely that you will
experience issues. Please use the official installers on the downloads page.
## First development environment
## Running Multiple Hypervisors
If you are new to Vagrant, the next step to set up a development environment is to install
a [box](/vagrant/tutorials/getting-started/getting-started-boxes).
Sometimes, certain hypervisors do not allow you to bring up virtual machines
if more than one hypervisor is in use. If you are lucky, you might see the following
error message come up when trying to bring up a virtual machine with Vagrant and
VirtualBox:
## How to use multiple hypervisors
```text
Hypervisors often do not allow you to bring up virtual machines if you have more than one hypervisor in use.
Below are a couple of examples to allow you
to use Vagrant and VirtualBox if another hypervisor is present.
### Linux, VirtualBox, and KVM
If you encounter the following error message, it is because another hypervisor, like KVM, is in use.
```shell-session
There was an error while executing `VBoxManage`, a CLI used by Vagrant for controlling VirtualBox. The command and stderr is shown below.
Command: ["startvm", <ID of the VM>, "--type", "headless"]
@ -50,16 +50,9 @@ VBoxManage: error: VirtualBox can't operate in VMX root mode. Please disable the
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component ConsoleWrap, interface IConsole
```
Other operating systems like Windows will blue screen if you attempt to bring up
a VirtualBox VM with Hyper-V enabled. Below are a couple of ways to ensure you
can use Vagrant and VirtualBox if another hypervisor is present.
You must add the additional hypervisors to the deny list in order for VirtualBox to run correctly.
### Linux, VirtualBox, and KVM
The above error message is because another hypervisor (like KVM) is in use.
We must blacklist these in order for VirtualBox to run correctly.
First find out the name of the hypervisor:
First, find out the name of the hypervisor.
```shell-session
$ lsmod | grep kvm
@ -68,31 +61,33 @@ kvm 593920 1 kvm_intel
irqbypass 16384 1 kvm
```
The one we're interested in is `kvm_intel`. You might have another.
Blacklist the hypervisor (run the following as root):
Use the `blacklist` command to add the hypervisor to your denylist.
```shell-session
$ echo 'blacklist kvm-intel' >> /etc/modprobe.d/blacklist.conf
```
Restart your machine and try running vagrant again.
Restart your machine and try the `vagrant` command again.
### Windows, VirtualBox, and Hyper-V
If you encounter an issue with Windows, you will get a blue screen if you attempt to bring up
a VirtualBox VM with Hyper-V enabled.
If you wish to use VirtualBox on Windows, you must ensure that Hyper-V is not enabled
on Windows. You can turn off the feature by running this Powershell command for Windows 10:
on Windows. You can turn off the feature with the following Powershell command for Windows 10.
```powershell
Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All
```
For Windows 11, you can run on an elevated Powershell:
For Windows 11, you can use an elevated Powershell.
```powershell
bcdedit /set hypervisorlaunchtype off
```
You can also disable it by going through the Windows system settings:
You can also disable Hyper-V in the Windows system settings.
- Right click on the Windows button and select Apps and Features.
- Select Turn Windows Features on or off.
@ -100,3 +95,5 @@ You can also disable it by going through the Windows system settings:
You might have to reboot your machine for the changes to take effect. More information
about Hyper-V can be read [here](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v).

View File

@ -42,8 +42,8 @@ rm -f /usr/bin/vagrant
## Remove user data
The removal of user data will remove all [boxes](/docs/boxes),
[plugins](/docs/plugins/), license files, and any stored state that may be used
The removal of user data will remove all [boxes](/vagrant/docs/boxes),
[plugins](/vagrant/docs/plugins), license files, and any stored state that may be used
by Vagrant. Removing the user data effectively makes Vagrant think it
is a fresh install.

View File

@ -10,13 +10,13 @@ description: |-
# Upgrade from Vagrant 1.0.x
The upgrade process from 1.0.x to 1.x is straightforward, Vagrant is
[backwards compatible](/docs/installation/backwards-compatibility)
with Vagrant 1.0.x. To reinstall Vagrant
over your previous installation, download the latest package and
install it with standard procedures for your operating system.
The upgrade process from 1.0.x to 1.x is straightforward. Vagrant is quite
[backwards compatible](/vagrant/docs/installation/backwards-compatibility)
with Vagrant 1.0.x, so you can simply reinstall Vagrant
over your previous installation by downloading the latest package and
installing it using standard procedures for your operating system.
As the [backwards compatibility](/docs/installation/backwards-compatibility)
As the [backwards compatibility](/vagrant/docs/installation/backwards-compatibility)
page says, **Vagrant 1.0.x plugins will not work with Vagrant 1.1+**. Many
of these plugins have been updated to work with newer versions of Vagrant,
so you will need to verify if they've been updated. If not however, you will have

View File

@ -1,31 +1,34 @@
---
layout: docs
page_title: Upgrading Vagrant
page_title: Upgrade Vagrant
description: |-
If you are upgrading from Vagrant 1.0.x, please read the specific page
dedicated to that. This page covers upgrading Vagrant in general during the
1.x series.
This page details the general process to upgrade Vagrant for the
1.x.x series. If you need to upgrade from Vagrant 1.0.x, read the specific page
dedicated to that.
---
# Upgrading Vagrant
# Upgrade Vagrant
If you are upgrading from Vagrant 1.0.x, please read the
[specific page dedicated to that](/docs/installation/upgrading-from-1-0).
This page covers upgrading Vagrant in general during the 1.x series.
This page details how to upgrade Vagrant in the 1.x.x series.
Vagrant upgrades during the 1.x release series are straightforward:
~> If you need to upgrade from Vagrant 1.0.x, read the
[specific page dedicated to that](/vagrant/docs/installation/upgrading-from-1-0).
1. [Download](/downloads) the new package
Vagrant upgrades during the 1.x.x release series are straightforward:
1. [Download](/vagrant/downloads) the new package
2. Install it over the existing package
The installers will properly overwrite and remove old files. It is recommended
that no other Vagrant processes are running during the upgrade process.
Note that Vagrantfile stability for the new Vagrantfile syntax is not
promised until 2.0 final. So while Vagrantfiles made for 1.0.x will
[continue to work](/docs/installation/backwards-compatibility),
newer Vagrantfiles may have backwards incompatible changes until 2.0 final.
## Vagrantfile compatibility with 3.0
-> **Run into troubles upgrading?** Please [report an issue](https://github.com/hashicorp/vagrant/issues)
if you run into problems upgrading. Upgrades are meant to be a smooth
process and we consider it a bug if it was not.
Note that Vagrantfile stability for the new Vagrantfile syntax is not
guaranteed until Vagrant 3.0. While Vagrantfiles made for 1.0.x will
[continue to work](/vagrant/docs/installation/backwards-compatibility),
newer Vagrantfiles may have backwards incompatible changes until 3.0.
## Issue reports
If you encounter any problems at upgrade time, [report them as an issue in Github](https://github.com/hashicorp/vagrant/issues). Upgrades are meant to be a smooth process and we consider it a bug if it was not.

Some files were not shown because too many files have changed in this diff Show More