website: add docs back to the main Vagrant repo

This commit is contained in:
Mitchell Hashimoto 2013-09-03 11:08:28 -07:00
parent 3154669835
commit d03110eaa3
130 changed files with 13891 additions and 0 deletions

5
.gitignore vendored
View File

@ -35,3 +35,8 @@ doc/
.ruby-gemset
.ruby-version
.rvmrc
# Website: docs
website/docs/.sass-cache
website/docs/build
website/docs/Rakefile

13
website/docs/Gemfile Normal file
View File

@ -0,0 +1,13 @@
source "https://rubygems.org"
gem "less", "~> 2.2.2"
gem "middleman", "~> 3.0.6"
gem "middleman-minify-html", "~> 3.0.0"
gem "rack-contrib", "~> 1.1.0"
gem "redcarpet", "~> 2.2.2"
gem "therubyracer", "~> 0.10.2"
gem "thin", "~> 1.5.0"
group :development do
gem "highline", "~> 1.6.15"
end

1
website/docs/Procfile Normal file
View File

@ -0,0 +1 @@
web: bundle exec thin start -p $PORT

26
website/docs/README.md Normal file
View File

@ -0,0 +1,26 @@
# Vagrant Documentation
This is the repository for the [Vagrant Documentation website](http://docs.vagrantup.com).
This is a [Middleman](http://middlemanapp.com) project, which builds a static
site from these source files. The site is hosted on [Heroku](http://heroku.com)
and then fronted by [Fastly](http://fastly.com).
## Contributions Welcome!
If you find a typo or you feel like you can improve the HTML, CSS, or
JavaScript, we welcome contributions. Feel free to open issues or pull
requests like any normal GitHub project, and we'll merge it in.
## Running the Site Locally
Running the site locally is simple. Clone this repo and run the following
commands:
```
$ bundle
$ bundle exec middleman server
```
Then open up `localhost:4567`. Note that some URLs you may need to append
".html" to make them work (in the navigation and such).

78
website/docs/config.rb Normal file
View File

@ -0,0 +1,78 @@
###
# Compass
###
# Susy grids in Compass
# First: gem install susy --pre
# require 'susy'
# Change Compass configuration
# compass_config do |config|
# config.output_style = :compact
# end
###
# Page options, layouts, aliases and proxies
###
# Per-page layout changes:
#
# With no layout
# page "/path/to/file.html", :layout => false
#
# With alternative layout
# page "/path/to/file.html", :layout => :otherlayout
#
# A path which all have the same layout
# with_layout :admin do
# page "/admin/*"
# end
# Proxy (fake) files
# page "/this-page-has-no-template.html", :proxy => "/template-file.html" do
# @which_fake_page = "Rendering a fake page with a variable"
# end
###
# Helpers
###
# Automatic image dimensions on image_tag helper
# activate :automatic_image_sizes
# Methods defined in the helpers block are available in templates
# helpers do
# def some_helper
# "Helping"
# end
# end
set :css_dir, 'stylesheets'
set :js_dir, 'javascripts'
set :images_dir, 'images'
# Use the RedCarpet Markdown engine
set :markdown_engine, :redcarpet
set :markdown, :fenced_code_blocks => true
# Build-specific configuration
configure :build do
activate :asset_hash
activate :minify_css
activate :minify_html
activate :minify_javascript
# Enable cache buster
# activate :cache_buster
# Use relative URLs
# activate :relative_assets
# Compress PNGs after build
# First: gem install middleman-smusher
# require "middleman-smusher"
# activate :smusher
# Or use a different image path
# set :http_path, "/Content/images/"
end

44
website/docs/config.ru Normal file
View File

@ -0,0 +1,44 @@
require "rack"
require "rack/auth/basic"
require "rack/contrib/not_found"
require "rack/contrib/response_headers"
require "rack/contrib/static_cache"
require "rack/contrib/try_static"
require File.expand_path("../lib/redirect_to_latest", __FILE__)
require File.expand_path("../lib/redirect_v1_docs", __FILE__)
# Properly compress the output if the client can handle it.
use Rack::Deflater
# Redirect the homepage to the latest documentation
use HashiCorp::Rack::RedirectToLatest
# Redirect the V1 documentation to the GitHub pages hosted version
use HashiCorp::Rack::RedirectV1Docs
# Set the "forever expire" cache headers for these static assets. Since
# we hash the contents of the assets to determine filenames, this is safe
# to do.
use Rack::StaticCache,
:root => "build",
:urls => ["/images", "/javascripts", "/stylesheets"],
:duration => 2,
:versioning => false
# For anything that matches below this point, we set the surrogate key
# for Fastly so that we can quickly purge all the pages without touching
# the static assets.
use Rack::ResponseHeaders do |headers|
headers["Surrogate-Key"] = "page"
end
# Try to find a static file that matches our request, since Middleman
# statically generates everything.
use Rack::TryStatic,
:root => "build",
:urls => ["/"],
:try => [".html", "index.html", "/index.html"]
# 404 if we reached this point. Sad times.
run Rack::NotFound.new(File.expand_path("../build/404.html", __FILE__))

View File

@ -0,0 +1,19 @@
module SidebarHelpers
# This helps by setting the "current" class for sidebar nav elements
# if the YAML frontmatter matches the expected value.
def sidebar_current(expected)
current = current_page.data.sidebar_current
if current == expected || sidebar_section == expected
return " class=\"current\""
else
return ""
end
end
# This returns the overall section of the documentation we're on.
def sidebar_section
current = current_page.data.sidebar_current
return "" if !current
current.split("-")[0]
end
end

View File

@ -0,0 +1,25 @@
module HashiCorp
module Rack
# This redirects to the latest version of the docs.
class RedirectToLatest
def initialize(app)
@app = app
end
def call(env)
if env["PATH_INFO"] =~ /^\/$/
headers = {
"Content-Type" => "text/html",
"Location" => "/v2/",
"Surrogate-Key" => "page"
}
message = "Redirecting to new URL..."
return [301, headers, [message]]
end
@app.call(env)
end
end
end
end

View File

@ -0,0 +1,26 @@
module HashiCorp
module Rack
# This redirects the V1 docs to the GitHub pages hosted version.
class RedirectV1Docs
def initialize(app)
@app = app
end
def call(env)
if env["PATH_INFO"] =~ /^\/v1/
headers = {
"Content-Type" => "text/html",
"Location" => "http://docs-v1.vagrantup.com#{env["PATH_INFO"]}",
"Surrogate-Key" => "page"
}
message = "Redirecting to old documentation URL..."
return [301, headers, [message]]
end
@app.call(env)
end
end
end
end

View File

@ -0,0 +1,7 @@
<h2>Page Not Found</h4>
<p>
Sorry, the page you tried to visit doesn't exist. This could be our fault,
and if so we'll fix that up right away. Please go back, or go back
<a href="/">home</a> to get back on track.
</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

View File

@ -0,0 +1,4 @@
/*! Backstretch - v2.0.1 - 2012-10-01
* http://srobbin.com/jquery-plugins/backstretch/
* Copyright (c) 2012 Scott Robbin; Licensed MIT */
(function(e,t,n){"use strict";e.fn.backstretch=function(r,s){return(r===n||r.length===0)&&e.error("No images were supplied for Backstretch"),e(t).scrollTop()===0&&t.scrollTo(0,0),this.each(function(){var t=e(this),n=t.data("backstretch");n&&(s=e.extend(n.options,s),n.destroy(!0)),n=new i(this,r,s),t.data("backstretch",n)})},e.backstretch=function(t,n){return e("body").backstretch(t,n).data("backstretch")},e.expr[":"].backstretch=function(t){return e(t).data("backstretch")!==n},e.fn.backstretch.defaults={centeredX:!0,centeredY:!0,duration:5e3,fade:0};var r={wrap:{left:0,top:0,overflow:"hidden",margin:0,padding:0,height:"100%",width:"100%",zIndex:-999999},img:{position:"absolute",display:"none",margin:0,padding:0,border:"none",width:"auto",height:"auto",maxWidth:"none",zIndex:-999999}},i=function(n,i,o){this.options=e.extend({},e.fn.backstretch.defaults,o||{}),this.images=e.isArray(i)?i:[i],e.each(this.images,function(){e("<img />")[0].src=this}),this.isBody=n===document.body,this.$container=e(n),this.$wrap=e('<div class="backstretch"></div>').css(r.wrap).appendTo(this.$container),this.$root=this.isBody?s?e(t):e(document):this.$container;if(!this.isBody){var u=this.$container.css("position"),a=this.$container.css("zIndex");this.$container.css({position:u==="static"?"relative":u,zIndex:a==="auto"?0:a,background:"none"}),this.$wrap.css({zIndex:-999998})}this.$wrap.css({position:this.isBody&&s?"fixed":"absolute"}),this.index=0,this.show(this.index),e(t).on("resize.backstretch",e.proxy(this.resize,this)).on("orientationchange.backstretch",e.proxy(function(){this.isBody&&t.pageYOffset===0&&(t.scrollTo(0,1),this.resize())},this))};i.prototype={resize:function(){try{var e={left:0,top:0},n=this.isBody?this.$root.width():this.$root.innerWidth(),r=n,i=this.isBody?t.innerHeight?t.innerHeight:this.$root.height():this.$root.innerHeight(),s=r/this.$img.data("ratio"),o;s>=i?(o=(s-i)/2,this.options.centeredY&&(e.top="-"+o+"px")):(s=i,r=s*this.$img.data("ratio"),o=(r-n)/2,this.options.centeredX&&(e.left="-"+o+"px")),this.$wrap.css({width:n,height:i}).find("img:not(.deleteable)").css({width:r,height:s}).css(e)}catch(u){}return this},show:function(t){if(Math.abs(t)>this.images.length-1)return;this.index=t;var n=this,i=n.$wrap.find("img").addClass("deleteable"),s=e.Event("backstretch.show",{relatedTarget:n.$container[0]});return clearInterval(n.interval),n.$img=e("<img />").css(r.img).bind("load",function(t){var r=this.width||e(t.target).width(),o=this.height||e(t.target).height();e(this).data("ratio",r/o),n.resize(),e(this).fadeIn(n.options.speed||n.options.fade,function(){i.remove(),n.paused||n.cycle(),n.$container.trigger(s)})}).appendTo(n.$wrap),n.$img.attr("src",n.images[t]),n},next:function(){return this.show(this.index<this.images.length-1?this.index+1:0)},prev:function(){return this.show(this.index===0?this.images.length-1:this.index-1)},pause:function(){return this.paused=!0,this},resume:function(){return this.paused=!1,this.next(),this},cycle:function(){return this.images.length>1&&(clearInterval(this.interval),this.interval=setInterval(e.proxy(function(){this.paused||this.next()},this),this.options.duration)),this},destroy:function(n){e(t).off("resize.backstretch orientationchange.backstretch"),clearInterval(this.interval),n||this.$wrap.remove(),this.$container.removeData("backstretch")}};var s=function(){var e=navigator.userAgent,n=navigator.platform,r=e.match(/AppleWebKit\/([0-9]+)/),i=!!r&&r[1],s=e.match(/Fennec\/([0-9]+)/),o=!!s&&s[1],u=e.match(/Opera Mobi\/([0-9]+)/),a=!!u&&u[1],f=e.match(/MSIE ([0-9]+)/),l=!!f&&f[1];return!((n.indexOf("iPhone")>-1||n.indexOf("iPad")>-1||n.indexOf("iPod")>-1)&&i&&i<534||t.operamini&&{}.toString.call(t.operamini)==="[object OperaMini]"||u&&a<7458||e.indexOf("Android")>-1&&i&&i<533||o&&o<6||"palmGetResource"in t&&i&&i<534||e.indexOf("MeeGo")>-1&&e.indexOf("NokiaBrowser/8.5.0")>-1||l&&l<=6)}()})(jQuery,window);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,43 @@
/*global jQuery */
/*!
* FitText.js 1.1
*
* Copyright 2011, Dave Rupert http://daverupert.com
* Released under the WTFPL license
* http://sam.zoy.org/wtfpl/
*
* Date: Thu May 05 14:23:00 2011 -0600
*/
(function( $ ){
$.fn.fitText = function( kompressor, options ) {
// Setup options
var compressor = kompressor || 1,
settings = $.extend({
'minFontSize' : Number.NEGATIVE_INFINITY,
'maxFontSize' : Number.POSITIVE_INFINITY
}, options);
return this.each(function(){
// Store the object
var $this = $(this);
// Resizer() resizes items based on the object width divided by the compressor * 10
var resizer = function () {
$this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
};
// Call once to set.
resizer();
// Call on resize. Opera debounces their resize by default.
$(window).on('resize', resizer);
});
};
})( jQuery );

View File

@ -0,0 +1,161 @@
/*
* Heads-Up Grid
* Simple HTML + CSS grid overlay for web design and development.
*
* Files: hugrid.css, hugrid.js, example.html
*
* Example and documentation at: http://bohemianalps.com/tools/grid
*
* Shurane, thanks for your help! https://github.com/shurane
*
* Copyright (c) 2011 Jason Simanek
*
* Version: 1.5 (09/03/2011)
* Requires: jQuery v1.6+
*
* Licensed under the GPL license:
* http://www.gnu.org/licenses/gpl.html
*/
;(function ($) {
// "use strict";
window.hugrid = {
toggleState : function() {
// change our indicators of state
if (window.hugrid.state == 'on') {
window.hugrid.state = 'off' ;
}
else if( window.hugrid.state == 'off'){
window.hugrid.state = 'on' ;
}
}
} ;
makehugrid = function () {
// called at startup. Remove grids, clear state.
initialCleanUp() ;
/* Column Container */
var hugridDiv = document.createElement("div");
hugridDiv.id = "hugrid";
/* Left Margin Column */
leftDiv = document.createElement("div");
leftDiv.className = "mline mlineL";
hugridDiv.appendChild(leftDiv);
/* Create Columns */
for (var i = 0; i < (columns - 1); i++) {
colDiv = document.createElement("div");
colDiv.className = "hugcol";
hugridDiv.appendChild(colDiv);
lineLDiv = document.createElement("div");
lineLDiv.className = "lineL";
colDiv.appendChild(lineLDiv);
lineRDiv = document.createElement("div");
lineRDiv.className = "lineR";
colDiv.appendChild(lineRDiv);
}
/* Right Margin Column */
rightDiv = document.createElement("div");
rightDiv.className = "mline mlineR";
hugridDiv.appendChild(rightDiv);
document.body.appendChild(hugridDiv);
/* If Rows */
if (rowheight !== 0) {
/* Row Container */
pageheight = $(document.body).height();
var hugridRows = document.createElement("div") ;
hugridRows.id = "hugridRows";
/* Create Rows */
for (var i = 0; i < (pageheight / rowheight); i++) {
rowDiv = document.createElement("div");
rowDiv.className = "hugrow";
hugridRows.appendChild(rowDiv);
lineB = document.createElement("div");
lineB.className = "lineB";
rowDiv.appendChild(lineB);
}
document.body.appendChild(hugridRows);
}
/* Apply CSS Properties */
$('#hugrid').css('width', pagewidth + pageUnits);
if (typeof window.pageleftmargin === 'number') {
$('#hugrid').css('left', pageleftmargin + pageUnits);
$('#hugrid').css('margin', '0');
} else if (typeof window.pagerightmargin === 'number') {
$('#hugrid').css('right', pagerightmargin + pageUnits);
$('#hugrid').css('left', 'auto');
$('#hugrid').css('margin', '0');
} else {
if (pageUnits === '%') {
$('#hugrid').css('left', ((100 - pagewidth) / 2) + pageUnits);
$('#hugrid').css('margin-left', 'auto');
} else {
$('#hugrid').css('margin-left', '-' + (pagewidth / 2) + pageUnits);
}
}
$('#hugrid div.hugcol').css('margin-left', columnwidth + colUnits);
$('#hugrid div.hugcol').css('width', gutterwidth + colUnits);
$('#hugridRows').css('margin-top', pagetopmargin + 'px');
$('#hugridRows div.hugrow').css('margin-top', (rowheight - 1) + 'px');
/* Create hugridUX and button */
var hugridUX = document.createElement("div");
hugridUX.id = "hugridUX";
document.body.appendChild(hugridUX);
$('#hugridUX').append('<div id="hugridButtonBkgd"></div><button id="hugridButton"></button>');
$('#hugridButton').append('<span id="hugbuttonON">ON</span>');
$('#hugridButton').append('<span id="hugbuttonOFF" style="display:none;">OFF</span>');
/* On/Off Button - click functionality */
$('#hugridButton').click(function () {
$('#hugridButton').toggleClass('buttonisoff') ;
$('#hugrid').toggle();
$('#hugridRows').toggle();
$("#hugridButton span").toggle();
window.hugrid.toggleState() ;
});
};
function initialCleanUp() {
/* Remove Previously Existing Grid Elements */
$('#hugrid').remove();
$('#hugridRows').remove();
$('#hugridUX').remove();
}
setgridonload = function () {
if ( gridonload === 'off') {
$('#hugridButton').toggleClass('buttonisoff') ;
$('#hugrid').toggle();
$('#hugridRows').toggle();
$("#hugridButton span").toggle();
window.hugrid.state = 'off'
} else {
window.hugrid.state = 'on'
}
} ;
setgridonresize = function () {
if ( window.hugrid.state === 'off') {
$('#hugridButton').toggleClass('buttonisoff') ;
$('#hugrid').toggle();
$('#hugridRows').toggle();
$("#hugridButton span").toggle();
}
} ;
})(jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
// add dropshadow to nav on scroll
$(document).ready(function(){
$(document).scroll(function() {
var top = $(document).scrollTop();
if (top > 0) $('nav').addClass("drop-shadow");
if (top === 0) $('nav').removeClass("drop-shadow");
});
});
// open/close documentation side nav on small screens
$(document).ready(function(){
$(".toggle").click(function() {
$(".sidebar-nav ul").slideToggle('slow');
});
});

View File

@ -0,0 +1,265 @@
<!DOCTYPE html>
<html>
<head>
<title>Vagrant Documentation</title>
<!-- meta -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- lib styles -->
<%= stylesheet_link_tag "bootstrap", "vagrantup" %>
<!-- lib js -->
<%= javascript_include_tag "jquery" %>
<%= javascript_include_tag "modernizr" %>
<%= javascript_include_tag "bootstrap.min" %>
<%= javascript_include_tag "backstretch" %>
<%= javascript_include_tag "vagrantup" %>
<!-- fonts -->
<link href='http://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="http://use.typekit.net/xfs6zus.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<!-- Google analytics -->
</head>
<body>
<!-- wrap everything -->
<div class="wrapper">
<!-- nav -->
<nav class="docs">
<!-- vagrant logo -->
<a class="vagrant-docs-logo" href="/">Vagrant Documentation</a>
<!-- nav -->
<ul class="pull-right unstyled">
<li><a href="http://www.vagrantup.com/">Home</a></li>
</ul>
</nav>
<div class="page docs docs-home">
<div class="container">
<div class="row">
<div class="sidebar span3">
<!-- get the sidebar nav -->
<!-- side nav docs -->
<aside class="sidebar-nav">
<div class="toggle hidden-desktop">
<div class="open-close open"></div>
<a href="#">Contents</a>
</div>
<ul class="unstyled">
<li<%= sidebar_current("overview") %>><a href="/v2/">Overview</a></li>
<li<%= sidebar_current("why") %>><a href="/v2/why-vagrant/index.html">Why Vagrant?</a></li>
<li<%= sidebar_current("installation") %>><a href="/v2/installation/index.html">Installation</a></li>
<% if sidebar_section == "installation" %>
<ul class="sub unstyled">
<li<%= sidebar_current("installation-backwards-compatibility") %>><a href="/v2/installation/backwards-compatibility.html">Backwards Compatibility</a></li>
<li<%= sidebar_current("installation-upgrading") %>><a href="/v2/installation/upgrading.html">Upgrading</a></li>
<li<%= sidebar_current("installation-upgrading-1-0") %>><a href="/v2/installation/upgrading-from-1-0.html">Upgrading from 1.0.x</a></li>
<li<%= sidebar_current("installation-uninstallation") %>><a href="/v2/installation/uninstallation.html">Uninstallation</a></li>
</ul>
<% end %>
<li<%= sidebar_current("gettingstarted") %>><a href="/v2/getting-started/index.html">Getting Started</a></li>
<% if sidebar_section == "gettingstarted" %>
<ul class="sub unstyled">
<li<%= sidebar_current("gettingstarted-projectsetup") %>><a href="/v2/getting-started/project_setup.html">Project Setup</a></li>
<li<%= sidebar_current("gettingstarted-boxes") %>><a href="/v2/getting-started/boxes.html">Boxes</a></li>
<li<%= sidebar_current("gettingstarted-up") %>><a href="/v2/getting-started/up.html">Up and SSH</a></li>
<li<%= sidebar_current("gettingstarted-syncedfolders") %>><a href="/v2/getting-started/synced_folders.html">Synced Folders</a></li>
<li<%= sidebar_current("gettingstarted-provisioning") %>><a href="/v2/getting-started/provisioning.html">Provisioning</a></li>
<li<%= sidebar_current("gettingstarted-networking") %>><a href="/v2/getting-started/networking.html">Networking</a></li>
<li<%= sidebar_current("gettingstarted-teardown") %>><a href="/v2/getting-started/teardown.html">Teardown</a></li>
<li<%= sidebar_current("gettingstarted-rebuild") %>><a href="/v2/getting-started/rebuild.html">Rebuild</a></li>
<li<%= sidebar_current("gettingstarted-providers") %>><a href="/v2/getting-started/providers.html">Providers</a></li>
</ul>
<% end %>
<li<%= sidebar_current("cli") %>><a href="/v2/cli/index.html">Command-Line Interface</a></li>
<% if sidebar_section == "cli" %>
<ul class="sub unstyled">
<li<%= sidebar_current("cli-box") %>><a href="/v2/cli/box.html">box</a></li>
<li<%= sidebar_current("cli-destroy") %>><a href="/v2/cli/destroy.html">destroy</a></li>
<li<%= sidebar_current("cli-halt") %>><a href="/v2/cli/halt.html">halt</a></li>
<li<%= sidebar_current("cli-init") %>><a href="/v2/cli/init.html">init</a></li>
<li<%= sidebar_current("cli-package") %>><a href="/v2/cli/package.html">package</a></li>
<li<%= sidebar_current("cli-plugin") %>><a href="/v2/cli/plugin.html">plugin</a></li>
<li<%= sidebar_current("cli-provision") %>><a href="/v2/cli/provision.html">provision</a></li>
<li<%= sidebar_current("cli-reload") %>><a href="/v2/cli/reload.html">reload</a></li>
<li<%= sidebar_current("cli-resume") %>><a href="/v2/cli/resume.html">resume</a></li>
<li<%= sidebar_current("cli-ssh") %>><a href="/v2/cli/ssh.html">ssh</a></li>
<li<%= sidebar_current("cli-ssh_config") %>><a href="/v2/cli/ssh_config.html">ssh-config</a></li>
<li<%= sidebar_current("cli-status") %>><a href="/v2/cli/status.html">status</a></li>
<li<%= sidebar_current("cli-suspend") %>><a href="/v2/cli/suspend.html">suspend</a></li>
<li<%= sidebar_current("cli-up") %>><a href="/v2/cli/up.html">up</a></li>
</ul>
<% end %>
<li <%= sidebar_current("vagrantfile") %>><a href="/v2/vagrantfile/index.html">Vagrantfile</a></li>
<% if sidebar_section == "vagrantfile" %>
<ul class="sub unstyled">
<li<%= sidebar_current("vagrantfile-version") %>><a href="/v2/vagrantfile/version.html">Configuration Version</a></li>
<li<%= sidebar_current("vagrantfile-machine") %>><a href="/v2/vagrantfile/machine_settings.html">Machine Settings</a></li>
<li<%= sidebar_current("vagrantfile-ssh") %>><a href="/v2/vagrantfile/ssh_settings.html">SSH Settings</a></li>
<li<%= sidebar_current("vagrantfile-vagrant") %>><a href="/v2/vagrantfile/vagrant_settings.html">Vagrant Settings</a></li>
</ul>
<% end %>
<li<%= sidebar_current("boxes") %>><a href="/v2/boxes.html">Boxes</a></li>
<% if sidebar_section == "boxes" %>
<ul class="sub unstyled">
<li<%= sidebar_current("boxes-format") %>><a href="/v2/boxes/format.html">Box File Format</a></li>
</ul>
<% end %>
<li<%= sidebar_current("provisioning") %>><a href="/v2/provisioning/index.html">Provisioning</a></li>
<% if sidebar_section == "provisioning" %>
<ul class="sub unstyled">
<li<%= sidebar_current("provisioning-basic") %>><a href="/v2/provisioning/basic_usage.html">Basic Usage</a></li>
<li<%= sidebar_current("provisioning-shell") %>><a href="/v2/provisioning/shell.html">Shell</a></li>
<li<%= sidebar_current("provisioning-ansible") %>><a href="/v2/provisioning/ansible.html">Ansible</a></li>
<li<%= sidebar_current("provisioning-chefsolo") %>><a href="/v2/provisioning/chef_solo.html">Chef Solo</a></li>
<li<%= sidebar_current("provisioning-chefclient") %>><a href="/v2/provisioning/chef_client.html">Chef Client</a></li>
<li<%= sidebar_current("provisioning-puppetapply") %>><a href="/v2/provisioning/puppet_apply.html">Puppet Apply</a></li>
<li<%= sidebar_current("provisioning-puppetagent") %>><a href="/v2/provisioning/puppet_agent.html">Puppet Agent</a></li>
</ul>
<% end %>
<li<%= sidebar_current("networking") %>><a href="/v2/networking/index.html">Networking</a></li>
<% if sidebar_section == "networking" %>
<ul class="sub unstyled">
<li<%= sidebar_current("networking-basic") %>><a href="/v2/networking/basic_usage.html">Basic Usage</a></li>
<li<%= sidebar_current("networking-fp") %>><a href="/v2/networking/forwarded_ports.html">Forwarded Ports</a></li>
<li<%= sidebar_current("networking-private") %>><a href="/v2/networking/private_network.html">Private Network</a></li>
<li<%= sidebar_current("networking-public") %>><a href="/v2/networking/public_network.html">Public Network</a></li>
</ul>
<% end %>
<li<%= sidebar_current("syncedfolder") %>><a href="/v2/synced-folders/index.html">Synced Folders</a></li>
<% if sidebar_section == "syncedfolder" %>
<ul class="sub unstyled">
<li<%= sidebar_current("syncedfolder-basic") %>><a href="/v2/synced-folders/basic_usage.html">Basic Usage</a></li>
<li<%= sidebar_current("syncedfolder-nfs") %>><a href="/v2/synced-folders/nfs.html">NFS</a></li>
</ul>
<% end %>
<li<%= sidebar_current("multimachine") %>><a href="/v2/multi-machine/index.html">Multi-Machine</a></li>
<li<%= sidebar_current("providers") %>><a href="/v2/providers/index.html">Providers</a></li>
<% if sidebar_section == "providers" %>
<ul class="sub unstyled">
<li<%= sidebar_current("providers-installation") %>><a href="/v2/providers/installation.html">Installation</a></li>
<li<%= sidebar_current("providers-basic-usage") %>><a href="/v2/providers/basic_usage.html">Basic Usage</a></li>
<li<%= sidebar_current("providers-configuration") %>><a href="/v2/providers/configuration.html">Configuration</a></li>
<li<%= sidebar_current("providers-custom") %>><a href="/v2/providers/custom.html">Custom Provider</a></li>
</ul> <!-- /.sub -->
<% end %>
<li<%= sidebar_current("virtualbox") %>><a href="/v2/virtualbox/index.html">VirtualBox</a></li>
<% if sidebar_section == "virtualbox" %>
<ul class="sub unstyled">
<li<%= sidebar_current("virtualbox-usage") %>><a href="/v2/virtualbox/usage.html">Usage</a></li>
<li<%= sidebar_current("virtualbox-boxes") %>><a href="/v2/virtualbox/boxes.html">Boxes</a></li>
<li<%= sidebar_current("virtualbox-configuration") %>><a href="/v2/virtualbox/configuration.html">Configuration</a></li>
</ul>
<% end %>
<li<%= sidebar_current("vmware") %>><a href="/v2/vmware/index.html">VMware</a></li>
<% if sidebar_section == "vmware" %>
<ul class="sub unstyled">
<li<%= sidebar_current("vmware-installation") %>><a href="/v2/vmware/installation.html">Installation</a></li>
<li<%= sidebar_current("vmware-usage") %>><a href="/v2/vmware/usage.html">Usage</a></li>
<li<%= sidebar_current("vmware-boxes") %>><a href="/v2/vmware/boxes.html">Boxes</a></li>
<li<%= sidebar_current("vmware-configuration") %>><a href="/v2/vmware/configuration.html">Configuration</a></li>
<li<%= sidebar_current("vmware-known-issues") %>><a href="/v2/vmware/known-issues.html">Known Issues</a></li>
</ul>
<% end %>
<li<%= sidebar_current("plugins") %>><a href="/v2/plugins/index.html">Plugins</a></li>
<% if sidebar_section == "plugins" %>
<ul class="sub unstyled">
<li<%= sidebar_current("plugins-usage") %>><a href="/v2/plugins/usage.html">Usage</a></li>
<li<%= sidebar_current("plugins-development-basics") %>><a href="/v2/plugins/development-basics.html">Plugin Development Basics</a></li>
<li<%= sidebar_current("plugins-commands") %>><a href="/v2/plugins/commands.html">Commands</a></li>
<li<%= sidebar_current("plugins-configuration") %>><a href="/v2/plugins/configuration.html">Configuration</a></li>
<li<%= sidebar_current("plugins-guests") %>><a href="/v2/plugins/guests.html">Guests</a></li>
<li<%= sidebar_current("plugins-guestcapabilities") %>><a href="/v2/plugins/guest-capabilities.html">Guest Capabilities</a></li>
<li<%= sidebar_current("plugins-hosts") %>><a href="/v2/plugins/hosts.html">Hosts</a></li>
<li<%= sidebar_current("plugins-providers") %>><a href="/v2/plugins/providers.html">Providers</a></li>
<li<%= sidebar_current("plugins-provisioners") %>><a href="/v2/plugins/provisioners.html">Provisioners</a></li>
<li<%= sidebar_current("plugins-packaging") %>><a href="/v2/plugins/packaging.html">Packaging & Distribution</a></li>
</ul>
<% end %>
<li<%= sidebar_current("debugging") %>><a href="/v2/debugging.html">Debugging</a></li>
</ul>
</aside> <!-- /.sidebar -->
</div> <!-- /.sidebar -->
<div class="page-contents span9">
<div class="page-background"></div>
<!-- start page content -->
<div class="row">
<div class="span8 offset1">
<%= yield %>
</div> <!-- /.span8 -->
</div> <!-- /.row -->
</div> <!-- /.page-contents -->
</div> <!-- /.row -->
</div> <!-- /.container -->
</div> <!-- /.page -->
<!-- footer -->
<footer>
<div class="container">
<div class="row">
<div class="span12">
<ul class="unstyled footer-nav">
<li><a href="http://docs.vagrantup.com/">Documentation</a></li>
<li><a href="http://www.vagrantup.com/about">About</a></li>
<li><a href="http://www.vagrantup.com/support">Support</a></li>
<a href="http://downloads.vagrantup.com/">
<li class="button inline-button">Download</li>
</a>
</ul>
<ul class="unstyled logos">
<a href="http://www.vagrantup.com">
<li class="vagrant-logo-monochrome"></li>
</a>
<li><span>by</span></li>
<a href="http://www.hashicorp.com">
<li class="hashi-logo-monochrome "></li>
</a>
</ul> <!-- /span -->
</div> <!-- /span -->
</div> <!-- /row -->
<div class="row">
<h6 class="legal">
&#169; 2013 HashiCorp
</h6>
</div> <!-- row -->
</div> <!-- container -->
</footer>
<!-- close .wrapper -->
</div>
<!-- load scripts -->
<!-- load full-width image into any div with class="big-background -->
<script>
$(".big-background").backstretch("assets/photos/full_width.jpg");
</script>
</body>
</html>

View File

@ -0,0 +1,321 @@
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
text-rendering: optimizeLegibility;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: @sans-serif-stack;
font-size: @base-font-size;
line-height: @base-line-height;
color: @black;
background-color: @white;
letter-spacing: 2px;
.museo-sans-regular;
}
.wrapper {
margin-top: 80px;
}
.container {
z-index: 999; //keep content on top
position: relative;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
padding: 0;
color: inherit;
text-rendering: optimizelegibility;
.museo-sans-bold;
}
h1 {
@font-size: 70px;
font-size: @font-size;
line-height: 80px;
letter-spacing: 3px;
span {
font-size: @headline-span-size;
display: block;
}
&.all-caps {
text-transform: uppercase;
text-align: center;
font-size: 40px;
}
}
h2 {
@font-size: 30px;
font-size: @font-size;
line-height: 35px;
}
h3 {
@font-size: 30px;
font-size: @font-size;
line-height: @font-size;
}
h4 {
@font-size: 24px;
font-size: @font-size;
line-height: @font-size;
}
h5 {
@font-size: 20px;
font-size: @font-size;
line-height: @font-size;
}
h6 {
@font-size: 12px;
font-size: @font-size;
line-height: @font-size;
}
p {
letter-spacing: 1px;
line-height: 32px;
a {
color: @docs-blue;
text-decoration: none;
border-bottom: 1px solid @docs-blue;
&:hover {
text-decoration: none;
color: darken(@blue, 10%);
border-bottom: 1px solid darken(@blue, 10%);
}
}
}
a {
color: inherit;
text-decoration: none;
&:hover {
text-decoration: none;
color: @purple;
.animate-text-color;
}
&:active {
color: @blue;
}
&:visited {
}
}
ul {
}
li {
line-height: @base-line-height;
}
blockquote {
border: none;
margin: 60px;
p { // blockquote p
font-size: @base-font-size * 2;
line-height: @base-line-height * 2;
font-style: italic;
}
}
strong {
.museo-sans-bold;
}
em {
.museo-sans-regular-italic;
}
br {
display:block;
line-height: (@baseline * 2);
}
pre,
code {
font-family: @mono-stack;
}
code {
font-size: inherit;
}
pre {
border: none;
font-size: @base-font-size;
background: @black;
color: @white;
padding: 20px;
line-height: @base-line-height;
margin-top: 20px;
margin-bottom: 20px;
span {
color: @code-highlight-text;
}
}
hr {
}
.vr {
width: 2px;
height: 100%;
}
form {
}
input {
letter-spacing: 3px;
&:focus {
outline: none;
}
}
::-webkit-input-placeholder {
overflow: visible;
padding-top: 3px;
color: @light-gray-text;
}
input:-moz-placeholder {
overflow: visible;
padding-top: 3px;
color: @light-gray-text;
}
/* type and styles */
::selection, ::-moz-selection {
background: ; /* highlight color */
}
.meta,
.legal,
.date {
color: @medium-gray-text;
line-height: @base-line-height;
.museo-sans-regular;
}
.date {
text-transform: uppercase;
}
.button {
color: @white;
text-align: center;
background-color: @primary-button-color;
display: block;
padding: 15px 0;
margin-top: 20px !important;
text-transform: uppercase;
font-size: 25px;
letter-spacing: 5px;
.museo-sans-light;
.rounded;
.hover;
&.inline-button {
background-color: @vagrant-blue;
padding: 5px 20px;
color: @white !important;
font-size: 15px;
letter-spacing: 1px;
.rounded;
a,
a:hover {
color: @white;
}
}
&.white-button {
background: fade(@white, 20%);
&:hover {
background: fade(@white, 30%);
}
}
&.secondary-button {
background: @light-gray;
&:hover {
background: @purple;
}
}
&.with-carat span {
margin-right: -10px; //recenter text if there's a carat after text
}
span {
// button text styles can go here
}
&:hover {
background-color: @purple;
.animate-background-color;
}
&:active {
}
&.disabled {
background-color: @light-gray-background;
}
}
a.read-more {
color: @blue;
&:hover {
color: darken(@blue, 10%);
}
}
// misc. styles
.loading {
text-align: center;
font-size: @base-font-size;
text-transform: uppercase;
letter-spacing: 5px;
color: @medium-gray-text;
padding: 30px 0 20px;
}
.pinned {
position:fixed;
}

5946
website/docs/source/stylesheets/bootstrap.css vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
/* compontents */
//search
.search-bar {
border-bottom: 1px solid fade(@black, 10%);
position: relative;
z-index: 99999; //keep search above content
margin-bottom: -1px;
.search-icon {
height: 60px;
width: 40px;
background: url(/images/search_icon.png) no-repeat 0 center;
}
.search {
//.debug;
background: @white;
height: 60px;
input,
button,
form {
.kill-effects;
border: none;
height: 60px;
font-size: 20px;
.museo-sans-light-italic;
}
input {
margin:0;
padding: 0 0 0 0;
font-size: 20px;
&:focus {
} //focus
}
button {
padding: 0 20px;
text-transform: uppercase;
}
} //search
} //search bar
//pagination
.pagination {
height: 80px;
background: @gray-background;
padding: 0;
margin:0 auto;
text-transform: uppercase;
color: @blue-text;
z-index: 999;
position:relative;
a.previous,
a.next {
padding: 25px 0;
}
a.previous {
margin-left: 20px;
}
a.next {
margin-right: 20px;
}
}

View File

@ -0,0 +1,101 @@
// footer
footer {
padding: 80px 0;
background: @black url(/images/footer_background.png) center center;
text-align: center;
color: @white;
z-index: 999;
position: relative; //z-index needs position!
ul.footer-nav {
color: @blue;
text-transform: uppercase;
font-size: 15px;
.museo-sans-light;
li {
display: inline-block;
margin: 0 10px;
a {
color: @blue;
&:hover {
color: @purple;
} //li a:hover
} // li a
} //li
} //ul
ul.logos {
margin: (@baseline * 2) 0;
li {
display: inline-block;
}
span {
color: @dark-gray-text;
.museo-sans-light;
text-transform: uppercase;
font-size: 40px;
margin: 0 10px;
}
.vagrant-logo-monochrome,
.hashi-logo-monochrome {
&:hover {
-khtml-opacity: .85;
-moz-opacity: .85;
opacity: .85;
filter: alpha(opacity=85);
.animate-opacity;
}
}
.vagrant-logo-monochrome {
height: 80px;
width: 80px;
background: url(/images/footer_vagrant_logo.png) no-repeat center center;
margin-bottom: -25px;
}
.hashi-logo-monochrome {
height: 80px;
width: 80px;
background: url(/images/footer_hashi_logo.png) no-repeat center center;
margin-bottom: -25px;
}
}
a.contact-link {
color: @dark-gray-text;
line-height: @base-line-height * 2;
font-size: 30px;
&:hover {
color: @white;
}
&:visited {
color: inherit;
}
&:active {
color: @blue;
}
} //contact link
} //footer

View File

@ -0,0 +1,452 @@
@media (max-width: 480px) {
nav {
position: absolute !important;
height: auto;
font-size: 13px;
padding: 10px 0;
.drop-shadow;
a.vagrant-docs-logo {
background: url(/images/logo_docs_small.png) no-repeat center center !important;
display: inline-block !important;
float: none !important;
position: relative;
width: 200px !important;
left: 50%;
padding: 10px 0;
.reset;
margin-left: -100px !important;
}
a.vagrant-logo {
background: url(/images/logo_vagrant.png) no-repeat center center !important;
display: inline-block !important;
float: none !important;
position: relative;
width: 80% !important;
left: 50%;
padding: 10px 0;
.reset;
margin-left: -130px !important;
}
ul {
position: relative;
margin: 0 auto;
width: 100%;
text-align: center;
padding: 10px 0 0;
}
}
a.brand {
display: none !important;
position: static !important;
width: 200px !important;
margin: 0 0 0 0 !important;
background-position: center center !important;
}
.search {
input {
font-size: 20px !important;
padding: 0 !important;
}
}
::-webkit-input-placeholder {
overflow: visible;
padding-top: 3px;
font-size: 15px;
}
input:-moz-placeholder {
overflow: visible;
padding-top: 3px;
font-size: 15px;
}
.page {
.page-contents {
} //page contents
&.home {
.hero {
background-size: 300%;
background-position: center 0;
height: 400px;
.hero-content {
margin-top: 80px;
}
h1 {
font-size: 40px !important;
line-height: 40px !important;
margin-bottom: 30px !important;
letter-spacing: 1px;
margin-bottom: ;
} //h1
h2 {
font-size: 20px !important;
line-height: 25px;
} //h2
} //hero
} //home
.why-vagrant {
padding: 40px 0 !important;
hgroup {
margin: 40px 0 !important;
:last-child {
margin-bottom: 0;
}
} //hgroup
h1 {
font-size: 30px !important;
line-height: 30px !important;
}
h3 {
font-size: 40px !important;
line-height: 40px !important;
margin-bottom: 20px !important;
}
h4 {
.hyphenate;
}
} //why-vagrant
.get-started {
padding: 40px 0 !important;
h1 {
width: 60%;
font-size: 30px !important;
line-height: 30px !important;
}
pre {
margin: 30px auto 30px !important;
}
} //get-started
.customers {
padding: 40px 0 !important;
h1 {
font-size: 30px !important;
line-height: 30px !important;
}
} //customers
&.inner {
padding-top: 30px;
.page-contents {
padding: 40px 0;
}
} //inner
&.docs {
.page-contents {
padding: 40px 0;
}
h1 {
font-size: 40px;
line-height: 40px;
}
h2 {
font-size: 25px;
line-height: 30px;
}
h2.steps img {
display: block;
margin-bottom: 20px;
}
} //docs
} //page
footer {
padding: 40px 0 !important;
background-size: 300%;
background-position: center bottom;
background-repeat: no-repeat;
ul.footer-nav {
font-size: 13px;
}
}
.button {
padding: 6px 0;
font-size: 20px;
letter-spacing: 3px;
.museo-sans-regular;
}
.search-bar {
margin-top: 160px !important;
}
.pagination {
font-size: 15px;
}
footer {
a.contact-link {
font-size: 20px;
} // contact link
}
} //mobile
@media (min-width: 768px) and (max-width: 979px) {
nav {
a.vagrant-logo {
background: url(/images/logo_small.png) no-repeat 0 0 !important;
width: 80px;
}
ul {
margin: 25px 20px;
}
} // nav
.toggle {
display: none !important;
}
.sidebar-nav ul {
display: block !important;
}
} // 768 < x < 979
@media (min-width: 1200px) {
} // > 1200
@media (max-width: 979px) {
.vagrant-docs-logo {
background: url(/images/logo_docs_small.png) no-repeat 0 0 !important;
width: 165px !important;
}
} // < 979
@media (min-width: 980px) {
} // > 980
@media (max-width: 767px) {
// these modules go full-width at smaller sizes
.pagination,
.hero,
.why-vagrant,
.get-started,
.customers,
footer {
.full-width;
}
nav {
height: auto;
font-size: 13px;
padding: 10px 0;
//.drop-shadow;
.vagrant-logo {
display: inline-block !important;
background-position: center center;
float: none !important;
position: relative;
width: 350px !important;
left: 50%;
padding: 10px 0;
.reset;
margin-left: -175px !important;
}
.vagrant-docs-logo {
background: url(/images/logo_docs.png) no-repeat 0 0 !important;
display: inline-block !important;
background-position: center center;
float: none !important;
position: relative;
width: 350px !important;
left: 50%;
padding: 10px 0;
.reset;
margin-left: -175px !important;
}
ul {
position: relative;
margin: 0 auto;
width: 100%;
text-align: center;
padding: 10px 0 0;
li:first-child {
margin-left: 0;
}
}
}
a.brand {
display: none !important;
position: static !important;
width: 200px !important;
margin: 0 0 0 0 !important;
background-position: center center !important;
}
.wrapper {
margin-top: 128px;
}
.sidebar {
ul {
margin-top: 0 !important;
li {
display: block;
text-indent: 20px;
&:hover,
&:active {
background-color: fade(@black, 5%);
.animate-background-color;
}
} //li
ul.sub {
li {
}
} //ul.sub
} //ul
.docs & {
.docs-bg-small;
ul {
display: none;
}
.sidebar-nav {
margin-right: -20px;
margin-left: -20px;
.docs-bg-small;
} //docs sidebar-nav
} // docs sidebar
} //sidebar
.page {
.page-background {
left: 0; //make it full-width to cover the gutters on small screens
}
.page-contents {
}
&.home {
.hero {
padding: 40px 0;
}
h1,
h4,
pre,
.customers-content, {
max-width: 80% !important;
margin: 0 auto;
}
pre {
padding: 20px 20px 0 !important;
}
.customer-logos {
margin-top: @baseline !important;
}
} //home
&.inner {
.page-contents {
}
.sidebar {
padding: 0;
position: relative;
}
.sidebar-nav {
.inner-bg-small;
margin-right: -20px;
margin-left: -20px;
}
h1 {
padding: 15px 0 15px;
margin: 0 0 0 20px !important;
}
ul {
margin: 0;
}
.button {
width: 80%;
}
}
&.docs {
background: transparent;
} //docs
} //page
.button {
max-width: 300px;
position: relative;
//margin: 20px 0 20px 20px;
}
.full-width {
margin-right: -20px !important;
margin-left: -20px ;
}
} // < 767

View File

@ -0,0 +1,174 @@
// styles and effects
.round-corners {
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
-khtml-border-radius: 3px;
border-radius: 3px;
}
.rounded {
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
-khtml-border-radius: 50px;
border-radius: 50px;
}
.animate-background-color {
transition: background-color .3s ease-in-out;
-moz-transition: background-color .3s ease-in-out;
-webkit-transition: background-color .3s ease-in-out;
-o-transition: background-color .3s ease-in-out;
}
.animate-text-color {
transition: color .2s ease-in-out;
-moz-transition: color .2s ease-in-out;
-webkit-transition: color .2s ease-in-out;
-o-transition: color .2s ease-in-out;
}
.animate-opacity {
transition: opacity .2s ease-in-out;
-moz-transition: opacity .2s ease-in-out;
-webkit-transition: opacity .2s ease-in-out;
-o-transition: opacity .2s ease-in-out;
}
.drop-shadow {
-webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1) !important;
-moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1) !important;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1) !important;
.animate-opacity;
}
.hyphenate {
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}
.uppercase {
text-transform: uppercase;
}
.padded {
padding: (@baseline * 3) 0;
}
.padded-medium {
padding: (@baseline * 2) 0;
}
.padded-small{
padding: @baseline 0;
}
.inner-bg-large {
background-image: #c1b4d5; /* Old browsers */
background-image: url(/images/sidebar_background_inner.png), -moz-linear-gradient(45deg, #c1b4d5 0%, #98d3f8 100%); /* FF3.6+ */
background-image: url(/images/sidebar_background_inner.png), -webkit-gradient(linear, left bottom, right top, color-stop(0%,#c1b4d5), color-stop(100%,#98d3f8)); /* Chrome,Safari4+ */
background-image: url(/images/sidebar_background_inner.png), -webkit-linear-gradient(45deg, #c1b4d5 0%,#98d3f8 100%); /* Chrome10+,Safari5.1+ */
background-image: url(/images/sidebar_background_inner.png), -o-linear-gradient(45deg, #c1b4d5 0%,#98d3f8 100%); /* Opera 11.10+ */
background-image: url(/images/sidebar_background_inner.png), -ms-linear-gradient(45deg, #c1b4d5 0%,#98d3f8 100%); /* IE10+ */
background-image: url(/images/sidebar_background_inner.png), linear-gradient(45deg, #c1b4d5 0%,#98d3f8 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c1b4d5', endColorstr='#98d3f8',GradientType=1 ); /* IE6-8 fallback on horizontal gradient */
background-repeat: no-repeat;
background-position: 0 0;
background-attachment:fixed;
}
.inner-bg-small {
background: #c1b4d5; /* Old browsers */
background: -moz-linear-gradient(45deg, #c1b4d5 0%, #98d3f8 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left bottom, right top, color-stop(0%,#c1b4d5), color-stop(100%,#98d3f8)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(45deg, #c1b4d5 0%,#98d3f8 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(45deg, #c1b4d5 0%,#98d3f8 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(45deg, #c1b4d5 0%,#98d3f8 100%); /* IE10+ */
background: linear-gradient(45deg, #c1b4d5 0%,#98d3f8 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c1b4d5', endColorstr='#98d3f8',GradientType=1 ); /* IE6-8 fallback on horizontal gradient */
}
.docs-bg-large {
background-image: url(/images/sidebar_background_docs.png), #362d6c; /* Old browsers */
background-image: url(/images/sidebar_background_docs.png), -moz-linear-gradient(45deg, #362d6c 0%, #0c5593 100%); /* FF3.6+ */
background-image: url(/images/sidebar_background_docs.png), -webkit-gradient(linear, left bottom, right top, color-stop(0%,#362d6c), color-stop(100%,#0c5593)); /* Chrome,Safari4+ */
background-image: url(/images/sidebar_background_docs.png), -webkit-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* Chrome10+,Safari5.1+ */
background-image: url(/images/sidebar_background_docs.png), -o-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* Opera 11.10+ */
background-image: url(/images/sidebar_background_docs.png), -ms-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* IE10+ */
background-image: url(/images/sidebar_background_docs.png), linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#362d6c', endColorstr='#0c5593',GradientType=1 ); /* IE6-8 fallback on horizontal gradient */
background-repeat: no-repeat;
background-attachment:fixed;
}
.docs-bg-small {
background: #362d6c; /* Old browsers */
background: -moz-linear-gradient(45deg, #362d6c 0%, #0c5593 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left bottom, right top, color-stop(0%,#362d6c), color-stop(100%,#0c5593)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* IE10+ */
background: linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#362d6c', endColorstr='#0c5593',GradientType=1 ); /* IE6-8 fallback on horizontal gradient */
}
.get-started-bg {
background-image: #362d6c; /* Old browsers */
background-image: -moz-linear-gradient(45deg, #362d6c 0%, #0c5593 100%); /* FF3.6+ */
background-image: -webkit-gradient(linear, left bottom, right top, color-stop(0%,#362d6c), color-stop(100%,#0c5593)); /* Chrome,Safari4+ */
background-image: -webkit-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* Chrome10+,Safari5.1+ */
background-image: -o-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* Opera 11.10+ */
background-image: -ms-linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* IE10+ */
background-image: linear-gradient(45deg, #362d6c 0%,#0c5593 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#362d6c', endColorstr='#0c5593',GradientType=1 ); /* IE6-8 fallback on horizontal gradient */
background-position: center 0;
background-repeat: no-repeat;
}
/*
.sidebar-nav-selected {
background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(71,101,118,1) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0)), color-stop(100%,rgba(71,101,118,1)));
background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(71,101,118,1) 100%);
background: -o-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(71,101,118,1) 100%);
background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(71,101,118,1) 100%);
background: linear-gradient(to right, rgba(255,255,255,0) 0%,rgba(71,101,118,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#476576',GradientType=1 );
}
*/
// helpers
.reset {
margin: 0;
padding: 0;
}
.kill-effects {
-webkit-box-shadow: 0 0;
-moz-box-shadow: 0 0;
box-shadow: 0 0;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
font-family: inherit;
color: inherit;
background-color: transparent;
background-image: none;
border: 0;
text-shadow: none;
}
.debug {
border: 1px solid #ff0000;
}
.hover {
&:hover {
cursor: pointer;
.animate-text-color;
}
}

View File

@ -0,0 +1,71 @@
// roll your own nav
nav {
width: 100%;
font-size: 15px;
text-transform: uppercase;
.museo-sans-light;
color: @medium-gray-text;
height: 80px;
position: fixed;
top: 0;
left: 0;
background-color: @white;
z-index: 9999999999;
&.docs {
background: @gray-background;
}
.vagrant-logo {
display: block;
text-indent: -999999px;
background: url(/images/logo_vagrant.png) no-repeat 0 0;
height: 70px;
width: 275px;
float: left;
margin: 10px 20px;
}
.vagrant-docs-logo {
display: block;
text-indent: -999999px;
background: url(/images/logo_docs.png) no-repeat 0 0;
height: 70px;
width: 350px;
float: left;
margin: 10px 20px;
}
ul {
margin: 25px 20px;
li {
display: inline;
margin-left: 15px;
}
}
.active-nav {
color: @blue;
}
.contact {
&:hover {
background-color: @light-gray-background;
padding: 10px;
margin-right: -10px;
margin-left: 5px;
.rounded;
}
&:active {
background-color: darken(@light-gray-background, 5%);
}
}
}

View File

@ -0,0 +1,276 @@
/* page */
.page { //style all pages
.page-background { //page background color
width: 100%;
height: 100%;
top: 0;
position: fixed;
z-index: -5; //keep it in the back
} //.background
.page-contents {
h1,
h2 {
text-transform: uppercase;
text-align: left;
.museo-sans-light;
}
h1 {
font-size: 60px;
line-height: 70px;
margin: (@baseline * 2) 0 @baseline;
&:first-child {
margin-top: 0;
} //h1 first child
}
h2 {
font-size: 40px;
line-height: 45px;
margin: (@baseline * 2) 0 @baseline;
&:first-child {
margin-top: @baseline * .5;
} //h2 first child
} //h2
} //page-contents
/* home */
&.home { //style homepage
h1 {
text-align: center;
}
.hero {
.padded;
background: @gray-background url(/images/vagrant_header_background.png) no-repeat center -80px;
text-align: center;
border-bottom: 1px solid #c6e0f0;
.hero-content {
top: 50%;
hgroup {
margin: (@baseline * 4) 0 20px 0;
h1 {
color: @purple-text;
margin-bottom: (@baseline * 4);
font-size: 60px;
line-height: 60px;
}
h2 {
.museo-sans-light;
color: @blue-text;
font-size: 30px;
line-height: 40px;
}
} //hero hgroup
} //hero-content
} //homepage hero
.why-vagrant {
.padded;
background: @light-blue-background url(/images/steps_background.png) center -120px;
h1 {
color: @blue-text;
text-transform: uppercase;
text-align: center;
font-size: 40px;
line-height: 40px;
} //h1
hgroup {
margin: (@baseline * 3) 0;
h3 {
text-align: center;
text-transform: uppercase;
font-size: 40px;
margin-bottom: @baseline;
color: @purple-text;
.museo-sans-light;
} //h3
h4 {
font-size: 20px;
line-height: @baseline * 1.5;
.museo-sans-light;
} //h4
} //hgroup
} //why-vagrant
.get-started {
.padded;
.get-started-bg;
h1 {
color: @white;
}
pre {
padding: 60px 80px 40px;
margin: 40px auto;
background: fade(@black, 60%);
}
.button {
//background: fade(@white, 20%);
}
} //get-started
.customers {
.padded;
background-color: @black;
border-bottom: 1px solid #333;
h1 {
color: @dark-gray-text;
.museo-sans-light
}
.customer-logos {
margin-top: @baseline * 3;
img {
width:100%;
height: auto;
-khtml-opacity: .5;
-moz-opacity: .5;
opacity: .5;
filter: alpha(opacity=50);
}
}
ul.customer-logos {
li {
img {
} //img
} //li
} //ul.cusotmer-logos
}
} //home
/* inner */
&.inner { //style inner pages
.inner-bg-large; //sidebar background
.page-background { //change inner background color!
background-color: @gray-background; //page background
}
.page-contents {
background-color: @gray-background;
.padded;
}
h2 {
color: @dark-blue-text;
}
p {
}
} //inner
/* docs */
&.docs { //style all docs
.docs-bg-large; //sidebar background
.page-background { //change the sidebar background color!
background: @white; //page background
}
.page-contents {
padding-top: 30px;
background-color: @white;
padding-bottom: 40px;
}
h1,
h2 {
color: @docs-blue;
}
h2.steps img {
margin-top: -7px;
}
li {
letter-spacing: 1px;
}
.alert {
margin-top: 20px;
h3 {
font-size: 22px;
letter-spacing: 1px;
margin-bottom: 8px;
}
p {
line-height: 26px;
}
}
&.docs-home { //style docs-home
} //documentation-home
&.docs-inner { //style docs-inner
h3 {
color: @docs-blue;
text-transform: uppercase;
margin: @baseline 0;
.museo-sans-light;
}
h4 {
line-height: 30px;
}
h5.subhead {
.museo-sans-light;
color: @purple-text;
line-height: @baseline;
margin: -10px 0 @baseline;
}
h6.subhead {
.museo-sans-regular-italic;
color: @dark-gray-text;
line-height: @baseline;
margin: -10px 0 @baseline;
font-size: 15px;
//text-transform: uppercase;
}
} //documentation-inner
} //documentation
} //page

View File

@ -0,0 +1,136 @@
.sidebar { //general styles for the sidebar
h1 {
text-align: left;
color: @white;
line-height: 60px;
margin-bottom: 20px;
}
.button {
font-size: 15px;
color: @dark-blue-text;
letter-spacing: 3px;
}
.toggle {
font-size: 20px;
.museo-sans-light;
color: @white;
margin-left: 20px;
padding: 20px 0;
a {
display: block;
color: @white;
&:hover {
color: @white;
}
}
.open-close {
background: url(/images/open_close.png) no-repeat 0 0;
height: 20px;
width: 20px;
position: absolute;
right: 0;
top: 25px;
}
}
.sidebar-nav { //style all sidebar-navs
//position:fixed;
}
ul { //general sidebar list styles
li { //general sidebar list item styles
font-size: 20px;
.museo-sans-light;
a {
display: block;
} //li a
&:hover {
}
} //li
ul.sub { //subnav list styles
border-top: none;
list-style-type: none;
margin:0 0 5px 0;
li {
padding: 5px 0 5px 20px;
font-size: 15px;
border: none;
border-bottom: none !important;
} //ul.sub li
} //ul.sub
@media screen and (min-width: 768px) {
display: block !important;
} //@media 768px
} //ul
.inner & { //styles for the inner-page sidebar
.padded;
position:fixed;
li.current a {
color: @purple;
}
ul { //style inner list
li { //style inner list item
color: @dark-blue-text;
padding: 20px 0;
border-top: 1px solid fade(@white, 40%);
&:last-child {
border-bottom: none;
}
&.current { //style the current selected list item
} //current
} //li
} //ul
} //.inner .sidebar
.docs & { //styles for the documentation sidebar
li.current a {
color: @blue;
}
ul { //style documentation list
li { //style documentation list items
text-transform: capitalize;
color: @white;
padding: 12px 0;
border-top: 1px solid fade(@white, 20%);
&:first-child {
border-top: none;
}
&:last-child {
border-bottom: none;
}
&.current { //style the current selected list item
} //current
} //li
} //ul
} //.documentation .sidebar
} //sidebar

View File

@ -0,0 +1,36 @@
//typogrpahy
.museo-sans-light {
font-family: "museo-sans", helvetica, arial, sans-serif;
font-style: normal;
font-weight: 100;
}
.museo-sans-regular {
font-family: "museo-sans", helvetica, arial, sans-serif;
font-style: normal;
font-weight: 300;
}
.museo-sans-bold {
font-family: "museo-sans", helvetica, arial, sans-serif;
font-style: normal;
font-weight: 700;
}
.museo-sans-light-italic {
font-family: "museo-sans", helvetica, arial, sans-serif;
font-style: italic;
font-weight: 100;
}
.museo-sans-regular-italic {
font-family: "museo-sans", helvetica, arial, sans-serif;
font-style: italic;
font-weight: 300;
}
.museo-sans-bold-italic {
font-family: "museo-sans", helvetica, arial, sans-serif;
font-style: italic;
font-weight: 700;
}

View File

@ -0,0 +1,16 @@
/*
/|\/|\/|\/|\/|\/|\
v a g r a n t u p
\|/\|/\|/\|/\|/\|/
*/
@import 'variables';
@import 'type';
@import 'mixins';
@import 'base';
@import 'nav';
@import 'components';
@import 'sidebar';
@import 'pages';
@import 'footer';
@import 'media-queries';

View File

@ -0,0 +1,39 @@
/* variables */
//grayscale
@black: #000;
@white: #fff;
@gray-background: #f7f6f1;
@dark-gray-text: #7f7f7f;
@light-gray-background: #f0f0f0;
@light-gray: #ccc;
@light-gray-text: #eeeeee;
@dark-gray-background: #333;
@medium-gray-text: #666;
//vagrant colors
@blue-text: #2490cc;
@dark-blue-text: #476576;
@light-blue-background: #dbf1ff;
@vagrant-blue: #0094bf;
@light-sidebar-background: #a1ccf0;
@docs-blue: #22407f;
@blue-background: #1e71a1;
@purple-text: #270836;
@purple: #735f9f;
//misc colors
@blue: #48b4fb;
@green: #43d193;
@code-highlight-text: #73c5dd;
@current-color: inherit;
@button-color: @vagrant-blue;
@primary-button-color: #48b4fb;
//type
@sans-serif-stack: 'Museo Sans', 'helvetica neue', helvetica, arial, sans-serif;
@mono-stack: 'Inconsolata', monaco, courier, monospace;
@base-font-size: 18px;
@base-line-height: 30px;
@baseline: 20px;
@headline-span-size: 30px;

View File

@ -0,0 +1,85 @@
---
sidebar_current: "boxes"
---
# Boxes
Boxes are the skeleton from which Vagrant machines are constructed. They are
portable files which can be used by others on any platform that runs Vagrant
to bring up a working environment.
The `vagrant box` utility provides all the functionality for managing
boxes. Boxes must currently be created manually.
Boxes are [provider-specific](/v2/providers/index.html), so you must obtain
the proper box depending on what provider you're using.
If you're interested in more details on the exact file format of
boxes, there is a seperate [page dedicated to that](/v2/boxes/format.html), since
it is an advanced topic that general users don't need to know.
## Adding Boxes
Adding boxes is straightforward:
```
$ vagrant box add name url
```
`name` is a logical name by which the box is referenced from the
Vagrantfile. You can put anything you want here, but know that Vagrant
matches the `config.vm.box` directive with this name in order to look up
the box to use.
`url` is the location of the box. This can be a path to your local filesystem
or an HTTP URL to the box remotely.
Vagrant will automatically determine the provider the box was built
for by reading the "metadata.json" file within the box archive. You
may also tell Vagrant what provider the box is for by specifying the
`--provider` flag.
This is recommended as it adds an extra level of verification
to the box you're downloading. Additionally, Vagrant can exit early with
an error if a box with that name and provider already exists, whereas
it must download the entire box before showing such an error in the other
case.
Multiple boxes with the same name can exist as long as they are all
for different providers. The example of listing boxes below shows this,
where there are multiple precise64 boxes, backed by different providers.
This lets a single `config.vm.box` configuration within a Vagrantfile
properly reference boxes across providers.
## Listing Boxes
To view what boxes Vagrant has locally installed, use `vagrant box list`:
```
$ vagrant box list
precise64 (virtualbox)
precise64 (vmware_fusion)
```
Vagrant lists all boxes along with the providers the box is for in parentheses.
## Removing Boxes
Boxes can be removed just as easily as they are added:
```
$ vagrant box remove precise64 virtualbox
```
The two arguments are the logical name of the box and the provider of the
box.
<div class="alert alert-info">
<h3>Optional Provider Parameter?</h3>
<p>
A future release of Vagrant will make the provider parameter optional
when removing a box. In this case, Vagrant will show a list of
boxes that can be removed and ask the user which they want to remove.
This is not currently implemented.
</p>
</div>

View File

@ -0,0 +1,31 @@
---
sidebar_current: "boxes-format"
---
# Box File Format
In the past, boxes were just [tar files](http://en.wikipedia.org/wiki/Tar_\(computing\))
of VirtualBox exports. With Vagrant supporting multiple providers, box files
are now tar files where the contents differ for each provider. They are
still tar files, but they may now optionally be [gzipped](http://en.wikipedia.org/wiki/Gzip)
as well.
Box files made for Vagrant 1.0.x and VirtualBox continue to work with
Vagrant 1.1+ and the VirtualBox provider.
The only file required within a box is a "metadata.json" file. This is
a [JSON](http://www.json.org/) file that has a top-level object that
can contain any metadata about the box. Vagrant requires that a "provider"
key exists in this metadata with the name of the provider the box is made
for.
The "metadata.json" file for a VirtualBox box:
```json
{
"provider": "virtualbox"
}
```
If there is no metadata.json file or the file does not contain valid JSON
with at least a "provider" key, then Vagrant will error when adding the box.

View File

@ -0,0 +1,61 @@
---
sidebar_current: "cli-box"
---
# Box
**Command: `vagrant box`**
This is the command used to manage (add, remove, etc.) [boxes](/v2/boxes/index.html).
The main functionality of this command is exposed via even more subcommands:
* `add`
* `list`
* `remove`
* `repackage`
# Box Add
**Command: `vagrant box add NAME URL`**
This adds a box add the given URL to Vagrant and stores it under the
logical name `NAME`.
The URL may be a file path or an HTTP URL. For HTTP, basic authentication
is supported and `http_proxy` environmental variables are respected. HTTPS
is also supported.
The name argument of this command is a _logical name_, meaning you can
effectively choose whatever you want. This is the name that Vagrant searches
for to match with the `config.vm.box` setting in Vagrantfiles.
## Options
* `--provider PROVIDER` - If given, Vagrant will verify the box you're
adding is for the given provider. By default, Vagrant automatically
detects the proper provider to use.
# Box List
**Command: `vagrant box list`**
This command lists all the boxes that are installed into Vagrant.
# Box Remove
**Command: `vagrant box remove NAME PROVIDER`**
This command removes a box from Vagrant that matches the given name and
provider.
# Box Repackage
**Command: `vagrant box repackage NAME PROVIDER`**
This command repackages the given box and puts it in the current
directory so you can redistribute it.
When you add a box, Vagrant unpacks it and stores it internally. The
original `*.box` file is not preserved. This command is useful for
reclaiming a `*.box` file from an installed Vagrant box.

View File

@ -0,0 +1,19 @@
---
sidebar_current: "cli-destroy"
---
# Destroy
**Command: `vagrant destroy`**
This command stops the running machine Vagrant is managing and
destroys all resources that were created during the machine creation process.
After running this command, your computer should be left at a clean state,
as if you never created the guest machine in the first place.
This command usually asks for confirmation before destroying. This
confirmation can be skipped by passing in the `-f` or `--force` flag.
## Options
* `-f` or `--force` - Don't ask for confirmation before destroying.

View File

@ -0,0 +1,18 @@
---
sidebar_current: "cli-halt"
---
# Halt
**Command: `vagrant halt`**
This command shuts down the running machine Vagrant is managing.
Vagrant will first attempt to gracefully shut down the machine by running
the guest OS shutdown mechanism. If this fails, or if the `--force` flag is
specified, Vagrant will effectively just shut off power to the machine.
## Options
* `-f` or `--force` - Don't attempt to gracefully shut down the machine.
This effectively pulls the power on the guest machine.

View File

@ -0,0 +1,23 @@
---
sidebar_current: "cli"
---
# Command-Line Interface
Almost all interaction with Vagrant is done through the command-line
interface.
The interface is available using the `vagrant` command, and comes installed
with Vagrant automatically. The `vagrant` command in turn has many subcommands,
such as `vagrant up`, `vagrant destroy`, etc.
If you run `vagrant` by itself, help will be displayed showing all available
subcommands. In addition to this, you can run any Vagrant command with the
`-h` flag to output help about that specific command. For example, try
running `vagrant init -h`. The help will output a one sentence synopsis of
what the command does as well as a list of all the flags the command
accepts.
In depth documentation and use cases of various Vagrant commands is
available by reading the appropriate sub-section available in the left
navigational area of this site.

View File

@ -0,0 +1,17 @@
---
sidebar_current: "cli-init"
---
# Init
**Command: `vagrant init [box-name] [box-url]`**
This initializes the current directory to be a Vagrant environment
by creating an initial [Vagrantfile](/v2/vagrantfile/index.html) if
one doesn't already exist.
If a first argument is given, it will prepopulate the `config.vm.box`
setting in the created Vagrantfile.
If a second argument is given, it will prepopulate the `config.vm.box_url`
setting in the created Vagrantfile.

View File

@ -0,0 +1,42 @@
---
sidebar_current: "cli-package"
---
# Package
**Command: `vagrant package`**
This packages a currently running _VirtualBox_ environment into a
re-usable [box](/v2/boxes.html). This command cannot be used with
any other [provider](/v2/providers/index.html). A future version of Vagrant
will address packaging boxes for other providers. Until then, they must
be made by hand.
## Options
* `--base NAME` - Instead of packaging a VirtualBox machine that Vagrant
manages, this will package a VirtualBox machine that VirtualBox manages.
`NAME` should be the name or UUID of the machine from the VirtualBox GUI.
* `--output NAME` - The resulting package will be saved as `NAME`. By default,
it will be saved as `package.box`.
* `--include x,y,z` - Additional files will be packaged with the box. These
can be used by a packaged Vagrantfile (documented below) to perform additional
tasks.
* `--vagrantfile FILE` - Packages a Vagrantfile with the box, that is loaded
as part of the [Vagrantfile load order](/v2/vagrantfile/index.html#load-order)
when the resulting box is used.
<div class="alert alert-info">
<p>
<strong>A common misconception</strong> is that the <code>--vagrantfile</code>
option will package a Vagrantfile that is used when <code>vagrant init</code>
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
<a href="/v2/vagrantfile/index.html#load-order">Vagrantfile load order</a>.
</p>
</div>

View File

@ -0,0 +1,45 @@
---
sidebar_current: "cli-plugin"
---
# Plugin
**Command: `vagrant plugin`**
This is the command used to manage [plugins](/v2/plugins/index.html).
The main functionality of this command is exposed via another level
of subcommands:
* `install`
* `license`
* `list`
* `uninstall`
# Plugin Install
**Command: `vagrant plugin install <name>`**
This installs a plugin with the given name or file path. If the name
is not a path to a file, then the plugin is installed from remote
repositories, usually [RubyGems](http://rubygems.org).
# Plugin License
**Command: `vagrant plugin license <name> <license-file>`**
This command installs a license for a proprietary Vagrant plugin,
such as the [VMware Fusion provider](/v2/vmware/index.html).
# Plugin List
**Command: `vagrant plugin list`**
This lists all installed plugins and their respective versions.
# Plugin Uninstall
**Command: `vagrant plugin uninstall <name>`**
This uninstalls the plugin with the given name. Any dependencies of the
plugin will also be uninstalled assuming no other plugin needs them.

View File

@ -0,0 +1,23 @@
---
sidebar_current: "cli-provision"
---
# Provision
**Command: `vagrant provision`**
Runs any configured [provisioners](/v2/provisioning/index.html)
against the running Vagrant managed machine.
This command is a great way to quickly test any provisioners, and is especially
useful for incremental development of shell scripts, Chef cookbooks, or Puppet
modules. You can just make simple modifications to the provisioning scripts
on your machine, run a `vagrant provision`, and check for the desired results.
Rinse and repeat.
# Options
* `--provision-with x,y,z` - This will only run the given provisioners. For
example, if you have a `:shell` and `:chef_solo` provisioner and run
`vagrant provision --provision-with shell`, only the shell provisioner will
be run.

View File

@ -0,0 +1,23 @@
---
sidebar_current: "cli-reload"
---
# Reload
**Command: `vagrant reload`**
The equivalent of running a [halt](/v2/cli/halt.html) followed by an
[up](/v2/cli/up.html).
This command is usually required for changes made in the Vagrantfile to
take effect. After making any modifications to the Vagrantfile, a `reload`
should be called.
# Options
* `--no-provision` - The provisioners will not run.
* `--provision-with x,y,z` - This will only run the given provisioners. For
example, if you have a `:shell` and `:chef_solo` provisioner and run
`vagrant provision --provision-with shell`, only the shell provisioner will
be run.

View File

@ -0,0 +1,10 @@
---
sidebar_current: "cli-resume"
---
# Resume
**Command: `vagrant resume`**
This resumes a Vagrant managed machine that was previously suspended,
perhaps with the [suspend command](/v2/cli/suspend.html).

View File

@ -0,0 +1,22 @@
---
sidebar_current: "cli-ssh"
---
# SSH
**Command: `vagrant ssh`**
This will SSH into a running Vagrant machine and give you access to a shell.
If a `--` (two hyphens) are found on the command line, any arguments after
this are passed directly into the `ssh` executable. This allows you to pass
any abitrary commands to do things such as reverse tunneling down into the
`ssh` program.
## Options
* `-c COMMAND` or `--command COMMAND` - This executes a single SSH command, prints
out the stdout and stderr, and exits.
* `-p` or `--plain` - This does an SSH without authentication, leaving
authentication up to the user.

View File

@ -0,0 +1,15 @@
---
sidebar_current: "cli-ssh_config"
---
# SSH Config
**Command: `vagrant ssh-config`**
This will output valid configuration for an SSH config file to SSH
into the running Vagrant machine from `ssh` directly (instead of
using `vagrant ssh`).
## Options
* `--host NAME` - Name of the host for the outputted configuration.

View File

@ -0,0 +1,13 @@
---
sidebar_current: "cli-status"
---
# Status
**Command: `vagrant status`**
This will tell you the state of the machines Vagrant is managing.
It is quite easy, especially once you get comfortable with Vagrant, to
forget whether your Vagrant machine is running, suspended, not created, etc.
This command tells you the state of the underlying guest machine.

View File

@ -0,0 +1,18 @@
---
sidebar_current: "cli-suspend"
---
# Suspend
**Command: `vagrant suspend`**
This suspends the guest machine Vagrant is managing, rather than fully
[shutting it down](/v2/cli/halt.html) or [destroying it](/v2/cli/destroy.html).
A suspend effectively saves the _exact point-in-time state_ of the machine,
so that when you [resume](/v2/cli/resume.html) 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
RAM within your guest machine, but the machine no longer consumes the
RAM of your host machine or CPU cycles while it is suspended.

View File

@ -0,0 +1,14 @@
---
sidebar_current: "cli-up"
---
# Up
**Command: `vagrant up`**
This command creates and configures guest machines according to your
[Vagrantfile](/v2/vagrantfile/index.html).
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.

View File

@ -0,0 +1,41 @@
---
sidebar_current: "debugging"
---
# Debugging
As much as we try to keep Vagrant stable and bug free, it is inevitable
that issues will arise and Vagrant will behave in unexpected ways. In
these cases, Vagrant has amazing [support](http://www.vagrantup.com/support.html)
channels available to assist you.
When using these support channels, it is generally helpful to include
debugging logs along with any error reports. These logs can often help you
troubleshoot any problems you may be having.
To enable detailed logging, set the `VAGRANT_LOG` environmental variable
to the desired log level name, which is one of `debug` (loud), `info` (normal),
`warn` (quiet), and `error` (very quiet). When asking for support, please
set this to `debug`. When troubleshooting your own issues, you should start
with `info`, which is much quieter, but contains important information
about the behavior of Vagrant.
On Linux and Mac systems, this can be done by prepending the `vagrant`
command with an environmental variable declaration:
```
$ VAGRANT_LOG=info vagrant up
...
```
On Windows, multiple steps are required:
```
$ set VAGRANT_LOG=info
$ vagrant up
...
```
If you plan on submitting a bug report, please submit debug-level logs
along with the report using [gist](https://gist.github.com/) or
some other paste service.

View File

@ -0,0 +1,55 @@
---
sidebar_current: "gettingstarted-boxes"
---
# Boxes
Instead of building a virtual machine from scratch, which would be a
slow and tedious process, Vagrant uses a base image to quickly clone
a virtual machine. These base images are known as _boxes_ in Vagrant,
and specifying the box to use for your Vagrant environment is always
the first step after creating a new Vagrantfile.
## Installing a Box
If you ran the commands on the [getting started overview page](/v2/getting-started/index.html),
then you've already installed a box before, and you don't need to run
the commands below again. However, it is still worth reading this section
to learn more about how boxes are managed.
Boxes are added to Vagrant with `vagrant box add`. This stores the box
under a specific name so that multiple Vagrant environments can re-use it.
If you haven't added a box yet, you can do so now:
```
$ vagrant box add precise32 \
http://files.vagrantup.com/precise32.box
```
This will download the box from an HTTP source and save it as "precise32"
in a directory that Vagrant manages (away from your project). You can also
add boxes from a local file path.
Added boxes can be re-used by multiple projects. Each project uses a box
as an initial image to clone from, and never modifies the actual base
image. This means that if you have two projects both using the `precise32`
box we just added, adding files in one guest machine will have no effect
on the other machine.
## Using a Box
Now that the box has been added to Vagrant, we need to configure our
project to use it as a base. Open the `Vagrantfile` and change the
contents to the following:
```ruby
Vagrant.configure("2") do |config|
config.vm.box = "precise32"
end
```
The "precise32" in this case must match the name you used to add
the box above. This is how Vagrant knows what box to use.
In the next section, we'll bring up the guest machine and interact
with it a little bit.

View File

@ -0,0 +1,42 @@
---
sidebar_current: "gettingstarted"
---
# Getting Started
The Vagrant getting started guide will walk you through your first
Vagrant project, and show off the basics of the major features Vagrant
has to offer.
Before diving into your first project, please [install Vagrant](/v2/installation/index.html).
And if you're curious what benefits Vagrant has to offer, you
should also read the ["Why Vagrant?"](/v2/why-vagrant/index.html) page.
The getting started guide will use Vagrant with [VirtualBox](http://www.virtualbox.org),
since it is free, available on every major platform, and built-in to
Vagrant. After reading the guide though, don't forget that Vagrant
can work with [many other providers](/v2/getting-started/providers.html).
## Up and Running
```
$ vagrant init precise32 http://files.vagrantup.com/precise32.box
$ vagrant up
```
After running the above two commands, you'll have a fully running
virtual machine in [VirtualBox](http://virtualbox.org) running
Ubuntu 12.04 LTS 32-bit. You can SSH into this machine with
`vagrant ssh`, and when you're done playing around, you can remove
all traces of it with `vagrant destroy`.
Now imagine every project you've ever worked on being this easy to
set up.
With Vagrant, `vagrant up` is all you need to work on any project,
to install every dependency that project needs, and to setup any
networking and synced folders so you can continue working from the
comfort of your own machine.
The rest of this guide will walk you through setting up a more
complete project, covering more features of Vagrant.

View File

@ -0,0 +1,44 @@
---
sidebar_current: "gettingstarted-networking"
---
# Networking
At this point we have a web server up and running with the ability to
modify files from our host and have them automatically synced to the guest.
However, accessing the web pages simply from the terminal from inside
the machine is not very satisfying. In this step, we'll use Vagrant's
_networking_ features to give us additional options for accessing the
machine from our host machine.
## Port Forwarding
One option is to use _port forwarding_. Port forwarding allows you to
specify ports on the guest machine to share via a port on the host machine.
This allows you to access a port on your own machine, but actually have
all the network traffic forwarded to a specific port on the guest machine.
Let's setup a forwarded port so we can access Apache in our guest. Doing so
is a simple edit to the Vagrantfile, which now looks like this:
```ruby
Vagrant.configure("2") do |config|
config.vm.box = "precise32"
config.vm.provision :shell, :path => "bootstrap.sh"
config.vm.network :forwarded_port, host: 4567, guest: 80
end
```
Run a `vagrant reload` or `vagrant up` (depending on if the machine
is already running) so that these changes can take effect.
Once the machine is running again, load `http://127.0.0.1:4567` in
your browser. You should see a web page that is being served from
the virtual machine that was automatically setup by Vagrant.
## Other Networking
Vagrant also has other forms of networking, allowing you to assign
a static IP address to the guest machine, or to bridge the guest
machine onto an existing network. If you're interested in other options,
read the [networking](/v2/networking/index.html) page.

View File

@ -0,0 +1,37 @@
---
sidebar_current: "gettingstarted-projectsetup"
---
# Project Setup
The first step for any project to use Vagrant is to configure Vagrant
using a [Vagrantfile](/v2/vagrantfile/index.html). The purpose of the
Vagrantfile is twofold:
1. Mark the root directory of your project. A lot of the configuration
of Vagrant is relative to this root directory.
2. Describe the kind of machine and resources you need to run your project,
as well as what software to install and how you want to access it.
Vagrant has a built-in command for initializing a directory for usage
with Vagrant: `vagrant init`. For the purpose of this getting started guide,
please follow along in your terminal:
```
$ mkdir vagrant_getting_started
$ cd vagrant_getting_started
$ vagrant init
```
This will place a `Vagrantfile` in your current directory. You can
take a look at the Vagrantfile if you want, it is filled with comments
and examples. Don't be afraid if it looks intimidating, we'll modify it
soon enough.
You can also run `vagrant init` in a pre-existing directory to
setup Vagrant for an existing project.
The Vagrantfile is meant to be committed to version control with
your project, if you use version control. This way, every person working
with that project can benefit from Vagrant without any upfront work.

View File

@ -0,0 +1,36 @@
---
sidebar_current: "gettingstarted-providers"
---
# Providers
In this getting started guide, your project was always backed with
[VirtualBox](http://www.virtualbox.org). But Vagrant can work with
a wide variety of backend providers, such as [VMware Fusion](/v2/vmware-fusion/index.html),
[AWS](http://github.com/mitchellh/vagrant-aws), and more. Read the page
of each provider for more information on how to set them up.
Once you have a provider installed, you don't need to make any modifications
to your Vagrantfile, just `vagrant up` with the proper provider and
Vagrant will do the rest:
```
$ vagrant up --provider=vmware_fusion
...
```
Ready to move that to the cloud? Take it to AWS:
```
$ vagrant up --provider=aws
...
```
Once you run `vagrant up` with another provider, every other Vagrant
command doesn't need to be told what provider to use. Vagrant can automatically
figure it out. So when you're ready to SSH or destroy or anything else,
just run the commands like normal, such as `vagrant destroy`. No extra
flags necessary.
For more information on providers, read the full documentation on
[providers](/v2/providers/index.html).

View File

@ -0,0 +1,72 @@
---
sidebar_current: "gettingstarted-provisioning"
---
# Provisioning
Alright, so we have a virtual machine running a basic copy of Ubuntu and
we can edit files from our machine and have them synced into the virtual machine.
Let's now serve those files using a webserver.
We could just SSH in and install a webserver and be on our way, but then
every person who used Vagrant would have to do the same thing. Instead,
Vagrant has built-in support for _automated provisioning_. Using this
feature, Vagrant will automatically install software when you `vagrant up`
so that the guest machine can be repeatably created and ready-to-use.
## Installing Apache
We'll just setup [Apache](http://httpd.apache.org/) for our basic project,
and we'll do so using a shell script. Create the following shell script
and save it as `bootstrap.sh` in the same directory as your Vagrantfile:
```bash
#!/usr/bin/env bash
apt-get update
apt-get install -y apache2
rm -rf /var/www
ln -fs /vagrant /var/www
```
Next, we configure Vagrant to run this shell script when setting up
our machine. We do this by editing the Vagrantfile, which should now
look like this:
```ruby
Vagrant.configure("2") do |config|
config.vm.box = "precise32"
config.vm.provision :shell, :path => "bootstrap.sh"
end
```
The "provision" line is new, and tells Vagrant to use the `shell` provisioner
to setup the machine, with the `bootstrap.sh` file. The file path is relative
to the location of the project root (where the Vagrantfile is).
## Provision!
After everything is configured, just run `vagrant up` to create your
machine and Vagrant will automatically provision it. You should see
the output from the shell script appear in your terminal. If the guest
machine is already running from a previous step, run `vagrant reload`,
which will quickly restart your virtual machine, skipping the initial
import step.
After Vagrant completes running, the web server will be up and running.
You can't see the website from your own browser (yet), but you can verify
that the provisioning works by loading a file from SSH within the machine:
```
$ vagrant ssh
...
vagrant@precise32:~$ wget -qO- 127.0.0.1
```
This works because in the shell script above we installed Apache and
setup the default `DocumentRoot` of Apache to point to our `/vagrant`
directory, which is the default synced folder setup by Vagrant.
You can play around some more by creating some more files and viewing
them from the terminal, but in the next step we'll cover networking
options so that you can use your own browser to access the guest machine.

View File

@ -0,0 +1,16 @@
---
sidebar_current: "gettingstarted-rebuild"
---
# Rebuild
When you're ready to come back to your project, whether it is tomorrow,
a week from now, or a year from now, getting it up and running is easy:
```
$ vagrant up
```
That's it! Since the Vagrant environment is already all configured via
the Vagrantfile, you or any of your coworkers simply have to run a
`vagrant up` at any time and Vagrant will recreate your work environment.

View File

@ -0,0 +1,41 @@
---
sidebar_current: "gettingstarted-syncedfolders"
---
# Synced Folders
While it is cool to have a virtual machine so easily, not many people
want to edit files using just plain terminal-based editors over SSH.
Luckily with Vagrant you don't have to. By using _synced folders_, Vagrant
will automatically sync your files to and from the guest machine.
By default, Vagrant shares your project directory (remember, that is the
one with the Vagrantfile) to the `/vagrant` directory in your guest machine.
Run `vagrant up` again and SSH into your machine to see:
```
$ vagrant up
...
$ vagrant ssh
...
vagrant@precise32:~$ ls /vagrant
Vagrantfile
```
Believe it or not, that Vagrantfile you see inside the virtual machine
is actually the same Vagrantfile that is on your actual host machine.
Go ahead and touch a file to prove it to yourself:
```
vagrant@precise32:~$ touch /vagrant/foo
vagrant@precise32:~$ exit
$ ls
foo Vagrantfile
```
Whoa! "foo" is now on your host machine. As you can see, Vagrant kept
the folders in sync.
With [synced folders](/v2/synced-folders/index.html), you can continue
to use your own editor on your host machine and have the files sync
into the guest machine.

View File

@ -0,0 +1,40 @@
---
sidebar_current: "gettingstarted-teardown"
---
# Teardown
We now have a fully functional virtual machine we can use for basic
web development. But now let's say it is time to switch gears, maybe work
on another project, maybe go out to lunch, or maybe just time to go home.
How do we clean up our development environment?
With Vagrant, you _suspend_, _halt_, or _destroy_ the guest machine.
Each of these options have pros and cons. Choose the method that works
best for you.
**Suspending** the virtual machine by calling `vagrant suspend` will
save the current running state of the machine and stop it. When you're
ready to begin working again, just run `vagrant up`, and it will be
resumed from where you left off. The main benefit of this method is that it
is super fast, usually taking only 5 to 10 seconds to stop and start your
work. The downside is that the virtual machine still eats up your disk space,
and requires even more disk space to store all the state of the virtual
machine RAM on disk.
**Halting** the virtual machine will gracefully shut down the guest
operating system and power down the guest machine. You can use `vagrant up`
when you're ready to boot it again. The benefit of this method is that
it will cleanly shut down your machine, preserving the contents of disk,
and allowing it to be cleanly started again. The downside is that it'll
take some extra time to start from a cold boot, and the guest machine
still consumes disk space.
**Destroying** the virtual machine will remove all traces of the guest
machine from your system. It'll stop the guest machine, power it down,
and remove all of the guest hard disks. Again, when you're ready to work
again, just issue a `vagrant up`. The benefit of this is that _no cruft_
is left on your machine. The disk space and RAM consumed by the guest machine
is reclaimed and your host machine is left clean. The downside is that
`vagrant up` to get working again will take some extra time since it
has to reimport the machine and reprovision it.

View File

@ -0,0 +1,34 @@
---
sidebar_current: "gettingstarted-up"
---
# Up And SSH
It is time to boot your first guest machine. Run the following:
```
$ vagrant up
```
In less than a minute, this command will finish and you'll have a
virtual machine running Ubuntu. You won't actually _see_ anything though,
since Vagrant runs the virtual machine without a UI. To prove that it is
running, you can SSH into the machine:
```
$ vagrant ssh
```
This command will drop you into a full-fledged SSH session. Go ahead and
interact with the machine and do whatever you want. Although it may be tempting,
be careful about `rm -rf /`, since Vagrant shares a directory at `/vagrant`
with the directory on the host containing your Vagrantfile, and this can
delete all those files. Shared folders will be covered in the next section.
Take a moment to think what just happened: With just one line of configuration
and one command in your terminal, we brought up a fully functional, SSH accessible
virtual machine. Cool.
When you're done fiddling around with the machine, run `vagrant destroy`
back on your host machine, and Vagrant will remove all traces of the
virtual machine.

View File

@ -0,0 +1,10 @@
---
sidebar_current: "overview"
---
# Vagrant Documentation
Welcome to the Vagrant docs! This site documents Vagrant from top-to-bottom,
covering every feature of Vagrant in great detail. If you're just getting
started with Vagrant, it is highly recommended you start with the
[getting started guide](/v2/getting-started/index.html).

View File

@ -0,0 +1,34 @@
---
sidebar_current: "installation-backwards-compatibility"
---
# Backwards Compatibility
## For 1.0.x
Vagrant 1.1+ provides full backwards compatibility for valid Vagrant 1.0.x
Vagrantfiles which don't use plugins. After installing Vagrant 1.1, your 1.0.x environments should
continue working without modifications, and existing running machines will
continue to be managed properly.
If you use any Vagrant 1.0.x plugins, you must remove references to these from
your Vagrantfile prior to upgrading. Vagrant 1.1+ introduces a new plugin
format that will protect against this sort of incompatibility from ever
happening again.
If your Vagrantfile doesn't just work with 1.1 and doesn't use any plugins,
please [report a bug](https://github.com/mitchellh/vagrant/issues).
## For 1.x
Backwards compatibility between 1.x is not promised, and Vagrantfile
syntax stability isn't promised until 2.0 final. Any backwards incompatibilities
within 1.x will be clearly documented.
This is similar to how Vagrant 0.x was handled. In practice, Vagrant 0.x
only introduced a handful of backwards incompatibilities during the entire
development cycle, but the possibility of backwards incompatibilities
is made clear so people aren't surprised.
Vagrant 2.0 final will have a stable Vagrantfile format that will
remain backwards compatible, just as 1.0 is considered stable.

View File

@ -0,0 +1,27 @@
---
sidebar_current: "installation"
---
# Installing Vagrant
Installing Vagrant is extremely easy. Head over to the
[downloads page](http://downloads.vagrantup.com/) and get the appropriate
installer or package for your platform. Then install it using 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).
If you have an old version of Vagrant 1.0.x installed via [RubyGems](http://en.wikipedia.org/wiki/RubyGems),
please remove it prior to installing a newer version of Vagrant.
<div class="alert alert-info">
<h3>Gem Install?</h3>
<p>
Vagrant 1.0.x had the option to be installed as a
<a href="http://en.wikipedia.org/wiki/RubyGems">RubyGem</a>. This
installation method has been removed for installers and packages only.
</p>
</div>

View File

@ -0,0 +1,38 @@
---
sidebar_current: "installation-uninstallation"
---
# Uninstalling Vagrant
Uninstalling Vagrant is easy and straightforward. You can either uninstall
the Vagrant binary, the user data, or both. The sections below cover how to
do this on every platform.
## Removing the Vagrant Program
Removing the Vagrant program will remove the `vagrant` binary and all
dependencies from your machine. After uninstalling the program, you can
always [reinstall](/v2/installation/index.html) again using standard
methods.
On **Windows**, uninstall using the add/remove programs section of
the control panel.
On **Mac OS X**, remove the `/Applications/Vagrant` directory and
the `/usr/bin/vagrant` file.
On **Linux**, remove the `/opt/vagrant` directory and the `/usr/bin/vagrant`
file.
## Removing User Data
Removing the user data will remove all [boxes](/v2/boxes.html),
[plugins](/v2/plugins/index.html), and any stored state that may be used
by Vagrant. Removing the user data effectively makes Vagrant think it
is once again a fresh install.
On every platform, remove the `~/.vagrant.d` directory to delete the
user data.
Running Vagrant will automatically regenerate any data necessary to run,
so it is safe to remove the user data at any time.

View File

@ -0,0 +1,16 @@
---
sidebar_current: "installation-upgrading-1-0"
---
# Upgrading From Vagrant 1.0.x
The upgrade process from 1.0.x to 1.x is straightforward. Vagrant is quite
[backwards compatible](/v2/installation/backwards-compatibility.html)
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.
**However**, if your version of Vagrant was installed via RubyGems, then
you must `gem uninstall` the old version prior to installing the package for
the latest version of Vagrant. The RubyGems-based installation method has
been removed.

View File

@ -0,0 +1,19 @@
---
sidebar_current: "installation-upgrading"
---
# Upgrading Vagrant
If you're upgrading from Vagrant 1.0.x, please read the
[specific page dedicated to that](/v2/installation/upgrading-from-1-0.html).
This page covers upgrading Vagrant in general during the 1.x series.
Upgrades of Vagrant during the 1.x release series are straightforward:
download the new package, install it over the existing package. The installers
will properly remove old files, and Linux package managers should do the
same thing.
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](/v2/installation/backwards-compatibility.html),
newer Vagrantfiles may have backwards incompatible changes until 2.0 final.

View File

@ -0,0 +1,89 @@
---
sidebar_current: "multimachine"
---
# Multi-Machine
Vagrant is able to define and control multiple guest machines per
Vagrantfile. This is known as a "multi-machine" environment.
These machines are generally able to work together or are somehow associated
with each other. Here are some use-cases people are using multi-machine
environments for today:
* Accurately modeling a multi-server production topology, such as separating
a web and database server.
* Modeling a distributed system and how they interact with each other.
* Testing an interface, such as an API to a service component.
* Disaster-case testing: machines dying, network partitions, slow networks,
inconsistent world views, etc.
Historically, running complex environments such as these was done by
flattening them onto a single machine. The problem with that is that it is
an inaccurate model of the production setup, which can behave far differently.
Using the multi-machine feature of Vagrant, these environments can be modeled
in the context of a single Vagrant environment without losing any of the
benefits of Vagrant.
## Defining Multiple Machines
Multiple machines are defined within the same project [Vagrantfile](/v2/vagrantfile/index.html)
using the `config.vm.define` method call. This configuration directive
is a little funny, because it creates a Vagrant configuration within a
configuration. An example shows this best:
```ruby
Vagrant.configure("2") do |config|
config.vm.provision :shell, :inline => "echo Hello"
config.vm.define :web do |web|
web.vm.box = "apache"
end
config.vm.define :db do |db|
db.vm.box = "mysql"
end
end
```
As you can see, `config.vm.define` takes a block with another variable. This
variable, such as `web` above, is the _exact_ same as the `config` variable,
except any configuration of the inner variable applies only to the machine
being defined. Therefore, any configuration on `web` will only affect the
`:web` machine.
And importantly, you can continue to use the `config` object as well. The
configuration object is loaded and merged before the machine-specific configuration,
just like other Vagrantfiles within the
[Vagrantfile load order](/v2/vagrantfile/index.html#load-order).
If you're familiar with programming, this is similar to how languages have
different variable scopes.
## Controlling Multiple Machines
The moment more than one machine is defined within a Vagrantfile, the
usage of the various `vagrant` commands changes slightly. The change should
be mostly intuitive.
Most commands, such as `vagrant up`, begin requiring the name of the machine
to control. Using the example above, you could say `vagrant up web`, or
`vagrant up db`. If no name is specified, it is assumed you mean to perform
that operation on every machine. Therefore, `vagrant up` alone will bring
up both the web and DB machine.
Additionally, you can specify a regular expression for matching only
certain machines. This is useful in some cases where you specify many similar
machines, for example if you're testing a distributed service you may have
a `master` machine as well as a `slave0`, `slave1`, `slave2`, etc. If you
want to bring up all the slaves but not the master, you can just do
`vagrant up /slave[0-9]/`. If Vagrant sees a machine name within forward
slashes, it assumes you're using a regular expression.
## Communication Between Machines
In order to faciliate communication within machines in a multi-machine setup,
the various [networking](/v2/networking/index.html) options should be used.
In particular, the [private network](/v2/networking/private_network.html) can
be used to make a private network between multiple machines and the host.

View File

@ -0,0 +1,42 @@
---
sidebar_current: "networking-basic"
---
# Basic Usage of Networking
Vagrant offers multiple options for how you are able to connect your
guest machines to the network, but there is a standard usage pattern as
well as some points common to all network configurations that
are important to know.
## Configuration
All networks are configured within your [Vagrantfile](/v2/vagrantfile/index.html)
using the `config.vm.network` method call. For example, the Vagrantfile
below defines some port forwarding:
```ruby
Vagrant.configure("2") do |config|
# other config here
config.vm.network :forwarded_port, guest: 80, host: 8080
end
```
Every network type has an identifier such as `:forwarded_port` in the above
example. Following this is a set of configuration arguments that can differ
for each network type. In the case of forwarded ports, two numeric arguments
are expected: the port on the guest followed by the port on the host that
the guest port can be accessed by.
## Multiple Networks
Multiple networks can be defined by having multiple `config.vm.network`
calls within the Vagrantfile. The exact meaning of this can differ for
each [provider](/v2/providers/index.html), but in general the order specifies
the order in which the networks are enabled.
## Enabling Networks
Networks are automatically configured and enabled after they've been defined
in the Vagrantfile as part of the `vagrant up` or `vagrant reload` process.

View File

@ -0,0 +1,56 @@
---
sidebar_current: "networking-fp"
---
# Forwarded Ports
**Network identifier: `:forwarded_port`**
Forwarded ports allow you to access a port on your host machine and have
all data forwarded to a port on the guest machine, over either TCP or UDP.
For example: If the guest machine is running a web server listening on port 80,
you can make a forwarded port mapping to port 8080 (or anything) on your host
machine. You can then open your browser to `localhost:8080` and browse the
website, while all actual network data is being sent to the guest.
## Defining a Forwarded Port
The forwarded port configuration expects two parameters, the port on the
guest and the port on the host. Example:
```ruby
Vagrant.configure("2") do |config|
config.vm.network :forwarded_port, guest: 80, host: 8080
end
```
This will allow acessing port 80 on the guest via port 8080 on the host.
## Port Collisions and Correction
It is common when running multiple Vagrant machines to unknowingly create
forwarded port definitions that collide with each other (two separate
Vagrant projects forwarded to port 8080, for example). Vagrant includes
built-in mechanism to detect this and correct it, automatically.
Port collision detection is always done. Vagrant will not allow you to
define a forwarded port where the port on the host appears to be accepting
traffic or connections.
Port collision auto-correction must be manually enabled for each forwarded
port, since it is often surprising when it occurs and can lead the Vagrant
user to think that the port wasn't properly forwarded. Enabling auto correct
is easy:
```
Vagrant.configure("2") do |config|
config.vm.network :forwarded_port, guest: 80, host: 8080,
auto_correct: true
end
```
The final `:auto_correct` parameter set to true tells Vagrant to auto
correct any collisions. During a `vagrant up` or `vagrant reload`, Vagrant
will output information about any collisions detections and auto corrections
made, so you can take notice and act accordingly.

View File

@ -0,0 +1,39 @@
---
sidebar_current: "networking"
---
# Networking
In order to access the Vagrant environment created, Vagrant exposes
some high-level networking options for things such as forwarded ports,
connecting to a public network, or creating a private network.
The high-level networking options are meant to define an abstraction that
works across multiple [providers](/v2/providers/index.html). This means that
you can take your Vagrantfile you used to spin up a VirtualBox machine and
you can reasonably expect that Vagrantfile to behave the same with something
like VMware.
You should first read the [basic usage](/v2/networking/basic_usage.html) page
and then continue by reading the documentation for a specific networking
primitive by following the navigation to the left.
## Advanced Configuration
In some cases,
these options are _too_ high-level, and you may want to more finely tune
and configure the network interfaces of the underlying machine. Most
providers expose [provider-specific configuration](/v2/providers/configuration.html)
to do this, so please read the documentation for your specific provider
to see what options are available.
<div class="alert alert-info">
<p>
<strong>For beginners:</strong> It is strongly recommended you use
only the high-level networking options until you are comfortable
with the Vagrant workflow and have things working at a basic level.
Provider-specific network configuration can very quickly lock you out
of your guest machine if improperly done.
</p>
</div>

View File

@ -0,0 +1,47 @@
---
sidebar_current: "networking-private"
---
# Private Networks
**Network identifier: `:private_network`**
Private networks allow you to access your guest machine by some address
that is not publicly accessible from the global internet. In general, this
means your machine gets an address in the [private address space](http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces).
Multiple machines within the same private network (also usually with the
restriction that they're backed by the same [provider](/v2/providers/index.html))
can communicate with each other on private networks.
<div class="alert alert-info">
<p>
<strong>Guest operating system support.</strong> Private networks
generally require configuring the network adapters on the guest
machine. This process varies from OS to OS. Vagrant ships with
knowledge of how to configure networks on a variety of guest
operating systems, but it is possible if you're using a particularly
old or new operating system that private networks won't properly
configure.
</p>
</div>
## Static IP
The easiest way to use a private network is to assign a static IP to it.
This let's you access the Vagrant managed machine using a static, known
IP. The Vagrantfile for a static IP looks like this:
```ruby
Vagrant.configure("2") do |config|
config.vm.network :private_network, ip: "192.168.50.4"
end
```
It is up to the users to make sure that the static IP doesn't collide
with any other machines on the same network.
While you can choose any IP you'd like, you _should_ use an IP from
the [reserved private address space](http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces). These IPs are guaranteed to never be publicly routable,
and most routers actually block traffic from going to them from the
outside world.

View File

@ -0,0 +1,38 @@
---
sidebar_current: "networking-public"
---
# Public Networks
**Network identifier: `:public_network`**
Public networks are less private than private networks, and the exact
meaning actually varies from [provider to provider](/v2/providers/index.html),
hence the ambiguous definition. The idea is that while
[private networks](/v2/networking/private_network.html) should never allow the
general public access to your machine, public networks can.
<div class="alert alert-info">
<p>
<strong>Confused?</strong> We kind of are, too. It is likely that
public networks will be replaced by <code>:bridged</code> in a
future release, since that is in general what should be done with
public networks, and providers that don't support bridging generally
don't have any other features that map to public networks either.
</p>
</div>
## DHCP
The easiest way to use a public network is to allow the IP to be assigned
via DHCP. In this case, defining a public network is trivially easy:
```ruby
Vagrant.configure("2") do |config|
config.vm.network :public_network
end
```
When DHCP is used, the IP can be determined by using `vagrant ssh` to
SSH into the machine and using the appropriate command line tool to find
the IP, such as `ifconfig`.

View File

@ -0,0 +1,115 @@
---
sidebar_current: "plugins-commands"
---
# Plugin Development: Commands
This page documents how to add new commands to Vagrant, invokable
via `vagrant YOUR-COMMAND`. Prior to reading this, you should be familiar
with the [plugin development basics](/v2/plugins/development-basics.html).
<div class="alert alert-warn">
<p>
<strong>Warning: Advanced Topic!</strong> Developing plugins is an
advanced topic that only experienced Vagrant users who are reasonably
comfortable with Ruby should approach.
</p>
</div>
## Definition Component
Within the context of a plugin definition, new commands can be defined
like so:
```ruby
command "foo" do
require_relative "command"
Command
end
```
Commands are defined with the `command` method, which takes as an argument
the name of the command, in this case "foo." This means the command will be
invokable via `vagrant foo`. Then the block argument returns a class that
implements the `Vagrant.plugin(2, :command)` interface.
## Implementation
Implementations of commands should subclass `Vagrant.plugin(2, :command)`,
which is a Vagrant method that will return the proper superclass for
a version 2 command. The implementation itself is quite simple, since the
class needs to only implement a single method: `execute`. Example:
```ruby
class Command < Vagrant.plugin(2, :command)
def execute
puts "Hello!"
0
end
end
```
The `execute` method is called when the command is invoked, and it should
return the exit status (0 for success, anything else for error).
This is a command at its simplest form. Of course, the command superclass
gives you access to the Vagrant environment and provides some helpers to
do common tasks such as command line parsing.
## Parsing Command-Line Options
The `parse_options` method is available which will parse the command line
for you. It takes an [OptionParser](http://ruby-doc.org/stdlib-1.9.3/libdoc/optparse/rdoc/OptionParser.html)
as an argument, and adds some common elements to it such as the `--help` flag,
automatically showing help if requested. View the API docs directly for more
information.
This is recommended over raw parsing/manipulation of command line flags.
The following is an example of parsing command line flags pulled directly
from the built-in Vagrant `destroy` command:
```ruby
options = {}
options[:force] = false
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant destroy [vm-name]"
o.separator ""
o.on("-f", "--force", "Destroy without confirmation.") do |f|
options[:force] = f
end
end
# Parse the options
argv = parse_options(opts)
```
## Using Vagrant Machines
The `with_target_vms` method is a helper that helps you interact with
the machines that Vagrant manages in a standard Vagrant way. This method
automatically does the right thing in the case of multi-machine environments,
handling target machines on the command line (`vagrant foo my-vm`), etc.
If you need to do any manipulation of a Vagrant machine, including SSH
access, this helper should be used.
An example of using the helper, again pulled directly from the built-in
`destroy` command:
```ruby
with_target_vms(argv, :reverse => true) do |machine|
machine.action(:destroy)
end
```
In this case, it asks for the machines in reverse order and calls the
destroy action on each of them. If a user says `vagrant destroy foo`, then
the helper automatically only yields the `foo` machine. If no parameter
is given and it is a multi-machine environment, every machine in the environment
is yielded, and so on. It just does the right thing.
## Using the Raw Vagrant Environment
The raw loaded `Vagrant::Environment` object is available with the
'@env' instance variable.

View File

@ -0,0 +1,165 @@
---
sidebar_current: "plugins-configuration"
---
# Plugin Development: Configuration
This page documents how to add new configuration options to Vagrant,
settable with `config.YOURKEY` in Vagrantfiles. Prior to reading this, you should be familiar
with the [plugin development basics](/v2/plugins/development-basics.html).
<div class="alert alert-warn">
<p>
<strong>Warning: Advanced Topic!</strong> Developing plugins is an
advanced topic that only experienced Vagrant users who are reasonably
comfortable with Ruby should approach.
</p>
</div>
## Definition Component
Within the context of a plugin definition, new configuration keys can be defined
like so:
```ruby
config "foo" do
require_relative "config"
Config
end
```
Configuration keys are defined with the `config` method, which takes as an
argument the name of the configuration variable as the argument. This
means that the configuration object will be accessible via `config.foo`
in Vagrantfiles. Then, the block argument returns a class that implements
the `Vagrant.plugin(2, :config)` interface.
## Implementation
Implementations of configuration keys should subclass `Vagrant.plugin(2, :config)`,
which is a Vagrant method that will return the proper subclass for a version
2 configuration section. The implementation is very simple, and acts mostly
as a plain Ruby object. Here is an example:
```ruby
class Config < Vagrant.plugin(2, :config)
attr_accessor :widgets
def initialize
@widgets = UNSET_VALUE
end
def finalize!
@widgets = 0 if @widgets == UNSET_VALUE
end
end
```
When using this configuration class, it looks like the following:
```ruby
Vagrant.configure("2") do |config|
# ...
config.foo.widgets = 12
end
```
Easy. The only odd thing is the `UNSET_VALUE` bits above. This is actually
so that Vagrant can properly automatically merge multiple configurations.
Merging is covered in the next section, and `UNSET_VALUE` will be explained
there.
## Merging
Vagrant works by loading [multiple Vagrantfiles and merging them](/v2/vagrantfile/index.html#load-order).
This merge logic is built-in to configuration classes. When merging two
configuration objects, we'll call them "old" and "new", it'll by default
take all the instance variables defined on "new" that aren't `UNSET_VALUE`
and set them onto the merged result.
The reason `UNSET_VALUE` is used instead of Ruby's `nil` is because
it is possible that you want the default to be some value, and the user
actually wants to set the value to `nil`, and it is impossible for Vagrant
to automatically determine whether the user set the instance variable, or
if it was defaulted as nil.
This merge logic is what you want almost every time. Hence, in the example
above, `@widgets` is set to `UNSET_VALUE`. If we had two Vagrant configuration
objects in the same file, then Vagrant would properly merge the follows.
The example below shows this:
```ruby
Vagrant.configure("2") do |config|
config.widgets = 1
end
Vagrant.configure("2") do |config|
# ... other stuff
end
Vagrant.configure("2") do |config|
config.widgets = 2
end
```
If this were placed in a Vagrantfile, after merging, the value of widgets
would be "2".
The `finalize!` method is called only once ever on the final configuration
object in order to set defaults. If `finalize!` is called, that configuration
will never be merged again, it is final. This lets you detect any `UNSET_VALUE`
and set the proper default, as we do in the above example.
Of course, sometimes you want custom merge logic. Let's say we
wanted our widgets to be additive. We can override the `merge` method to
do this:
```ruby
class Config < Vagrant.config("2", :config)
attr_accessor :widgets
def initialize
@widgets = 0
end
def merge(other)
super.tap do |result|
result.widgets = @widgets + other.widgets
end
end
end
```
In this case, we didn't use `UNSET_VALUE` for widgets because we didn't
need that behavior. We default to 0 and always merge by summing the
two widgets. Now, if we ran the example above that had the 3 configuration
blocks, the final value of widgets would be "3".
## Validation
Configuration classes are also responsible for validating their own
values. Vagrant will call the `validate` method to do this. An example
validation method is shown below:
```ruby
class Config < Vagrant.plugin("2", :config)
# ...
def validate(machine)
if @widgets <= 5
return { "foo" => ["widgets must be greater than 5"] }
end
{}
end
end
```
The validation method is given a `machine` object, since validation is
done for each machine that Vagrant is managing. This allows you to
conditionally validate some keys based on the state of the machine and so on.
The return value is a Ruby Hash object, where the key is a section name,
and the value is a list of error messages. These will be displayed by
Vagrant. If there are no errors, an empty hash must be returned.

View File

@ -0,0 +1,138 @@
---
sidebar_current: "plugins-development-basics"
---
# Plugin Development Basics
Plugins are a great way to augment or change the behavior and functionality
of Vagrant. Since plugins introduce additional external dependencies for
users, they should be used as a last resort when attempting to
do something with Vagrant.
But if you need to introduce custom behaviors
into Vagrant, plugins are the best way, since they are safe against future
upgrades and use a stable API.
<div class="alert alert-warn">
<p>
<strong>Warning: Advanced Topic!</strong> Developing plugins is an
advanced topic that only experienced Vagrant users who are reasonably
comfortable with Ruby should approach.
</p>
</div>
Plugins are written using [Ruby](http://www.ruby-lang.org/en/) and are packaged
using [RubyGems](http://rubygems.org/). Familiarity with Ruby is required,
but the [packaging and distribution](#) section should help
guide you to packaging your plugin into a RubyGem.
## Plugin Definition
All plugins are required to have a definition. A definition contains details
about the plugin such as the name of it and what components it contains.
A definition at the bare minimum looks like the following:
```ruby
class MyPlugin < Vagrant.plugin("2")
name "My Plugin"
end
```
A definition is a class that inherits from `Vagrant.plugin("2")`. The "2"
there is the version that the plugin is valid for. API stability is only
promised for each major version of Vagrant, so this is important. (The
1.x series is working towards 2.0, so the API version is "2")
**The most critical feature of a plugin definition** is that it must _always_
load, no matter what version of Vagrant is running. Theoretically, Vagrant
version 87 (doesn't actually exist) would be able to load a version 2 plugin
definition. This is achieved through clever lazy loading of individual components
of the plugin, and is covered shortly.
## Plugin Components
Within the definition, a plugin advertises what components it adds to
Vagrant. An example is shown below where a command and provisioner are
added:
```
class MyPlugin < Vagrant.plugin("2")
name "My Plugin"
command "run-my-plugin" do
require_relative "command"
Command
end
provisioner "my-provisioner" do
require_relative "provisioner"
Provisioner
end
end
```
Let's go over the major pieces of what is going on here. Note from a general
Ruby language perspective the above _should_ be familiar. The syntax should
not scare you. If it does, then please familiarize with Ruby further before
attempting to write a plugin.
The first thing to note is that individual components are defined by
making a method call with the component name, such as `command` or
`provisioner`. These in turn take some parameters. In the case of our
example it is just the name of the command and the name of the provisioner.
All component definitions then take a block argument (a callback) that
must return the actual component implementation class.
The block argument is where the "clever lazy loading" (mentioned above)
comes into play. The component blocks should lazy load the actual file that
contains the implementation of the component, and then return that component.
This is done because the actual dependencies and APIs used when defining
components are not stable across major Vagrant versions. A command implementation
written for Vagrant 2.0 will not be compatible with Vagrant 3.0 and so on. But
the _definition_ is just plain Ruby that must always be forward compatible
to future Vagrant versions.
To repeat, **the lazy loading aspect of plugin components is critical**
to the way Vagrant plugins work. All components must be lazily loaded
and returned within their definition blocks.
Now, each component has a different API. Please visit the relevant section
using the navigation to the left under "Plugins" to learn more about developing
each type of component.
## Error Handling
One of Vagrant's biggest strength is gracefully handling errors and reporting
them in human-readable ways. Vagrant has always strongly believed that if
a user sees a stack trace, it is a bug. It is expected that plugins will behave
the same way, and Vagrant provides strong error handling mechanisms to
assist with this.
Error handling in Vagrant is done entirely by raising Ruby exceptions.
But Vagrant treats certain errors differently than others. If an error
is raised that inherits from `Vagrant::Errors::VagrantError`, then the
`vagrant` command will output the message of the error in nice red text
to the console and exit with an exit status of 1.
Otherwise, Vagrant reports an "unexpected error" that should be reported
as a bug, and shows a full stack trace and other ugliness. Any stack traces
should be considered bugs.
Therefore, to fit into Vagrant's error handling mechanisms, subclass
`VagrantError` and set a proper message on your exception. To see
examples of this, look at Vagrant's [built-in errors](https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/errors.rb).
## Console Input and Output
Most plugins are likely going to want to do some sort of input/output.
Plugins should _never_ use Ruby's built-in `puts` or `gets` style methods.
Instead, all input/output should go through some sort of Vagrant UI object.
The Vagrant UI object properly handles cases where there is no TTY, output
pipes are closed, there is no input pipe, etc.
A UI object is available on every `Vagrant::Environment` via the `ui` property
and is exposed within every middleware environment via the `:ui` key. UI
objects have [decent documentation](https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/ui.rb)
within the comments of their source.

View File

@ -0,0 +1,99 @@
---
sidebar_current: "plugins-guestcapabilities"
---
# Plugin Development: Guest Capabilities
This page documents how to add new capabilities for [guests](/v2/plugins/guests.html)
to Vagrant, allowing Vagrant to perform new actions on specific guest
operating systems.
Prior to reading this, you should be familiar
with the [plugin development basics](/v2/plugins/development-basics.html).
<div class="alert alert-warn">
<p>
<strong>Warning: Advanced Topic!</strong> Developing plugins is an
advanced topic that only experienced Vagrant users who are reasonably
comfortable with Ruby should approach.
</p>
</div>
Guest capabilities augment [guests](/v2/plugins/guests.html) by attaching
specific "capabilities" to the guest, which are actions that can be performed
in the context of that guest operating system.
The power of capabilities is that plugins can add new capabilities to
existing guest operating systems without modifying the core of Vagrant.
In earlier versions of Vagrant, all the guest logic was contained in the
core of Vagrant and wasn't easily augmented.
## Definition Component
Within the context of a plugin definition, guest capabilities can be
defined like so:
```ruby
guest_capability "ubuntu", "my_custom_capability" do
require_relative "cap/my_custom_capability"
Cap::MyCustomCapability
end
```
Guest capabilities are defined by calling the `guest_capability` method,
which takes two parameters: the guest to add the capability to, and the
name of the capability itself. Then, the block argument returns a class
that implements a method named the same as the capability. This is
coverd in more detail in the next section.
## Implementation
Implementations should be classes or modules that have a method with
the same name as the capability. The method must be immediately accessible
on the class returned from the `guest_capability` component, meaning that
if it is an instance method, an instance should be returned.
In general, class methods are used for capabilities. For example, here
is the imlementation for the capability above:
```ruby
module Cap
class MyCustomCapability
def self.my_custom_capability(machine)
# implementation
end
end
end
```
All capabilities get the Vagrant machine object as the first argument.
Additional arguments are deterined by the specific capability, so view the
documentation or usage of the capability you're trying to implement for more
information.
Some capabilities must also return values back to the caller, so be aware
of that when implementing a capability.
Capabilities always have access to communication channels such as SSH
on the machine, and the machine can generally be assumed to be booted.
## Calling Capabilities
Since you have access to the machine in every capability, capabilities can
also call _other_ capabilities. This is useful for using the inheritance
mechanism of capabilities to potentially ask helpers for more information.
For example, the "redhat" guest has a "network\_scripts\_dir" capability that
simply returns the directory where networking scripts go.
Capabilities on child guests of RedHat such as CentOS or Fedora use this
capability to determine where networking scripts go, while sometimes overriding
it themselves.
Capabilities can be called like so:
```ruby
machine.guest.capability(:capability_name)
```
Any additional arguments given to the method will be passed on to the
capability, and the capability will return the value that the actual
capability returned.

View File

@ -0,0 +1,98 @@
---
sidebar_current: "plugins-guests"
---
# Plugin Development: Guests
This page documents how to add new guest OS detection to Vagrant, allowing
Vagrant to properly configure new operating systems.
Prior to reading this, you should be familiar
with the [plugin development basics](/v2/plugins/development-basics.html).
<div class="alert alert-warn">
<p>
<strong>Warning: Advanced Topic!</strong> Developing plugins is an
advanced topic that only experienced Vagrant users who are reasonably
comfortable with Ruby should approach.
</p>
</div>
Vagrant has many features that requires doing guest OS-specific
actions, such as mounting folders, configuring networks, etc. These
tasks vary from operating system to operating system. If you find that
one of these doesn't work for your operating system, then maybe the
guest implementation is incomplete or incorrect.
## Definition Component
Within the context of a plugin definition, new guests can be defined
like so:
```ruby
guest "ubuntu" do
require_relative "guest"
Guest
end
```
Guests are defined with the `guest` method. The first argument is the
name of the guest. This name isn't actually used anywhere, but may in the
future, so choose something helpful. Then, the block argument returns a
class that implements the `Vagrant.plugin(2, :guest)` interface.
## Implementation
Implementations of guests subclass `Vagrant.plugin("2", "guest")`. Within
this implementation, only the `detect?` method needs to be implemented.
The `detect?` method is called by Vagrant at some point after the machine
is booted in order to determine what operating system the guest is running.
If you detect that it is your operating system, return `true` from `detect?`.
Otherwise, return `false`.
Communication channels to the machine are guranteed to be running at this
point, so the most common way to detect the operating system is to do
some basic testing:
```
class MyGuest < Vagrant.plugin("2", "guest")
def detect?(machine)
machine.communicate.test("cat /etc/myos-release")
end
end
```
After detecting an OS, that OS is used for various
[guest capabilities](/v2/plugins/guest_capabilities.html) that may be
required.
## Guest Inheritance
Vagrant also supports a form of inheritance for guests, since sometimes
operating systems stem from a common root. A good example of this is Linux
is the root of Debian, which further is the root of Ubuntu in many cases.
Inheritance allows guests to share a lot of common behavior while allowing
distro-specific overrides.
Inheritance is not done via standard Ruby class inheritance because Vagrant
uses a custom [capability-based](/v2/plugins/guest_capabilities.html) system.
Vagrant handles inheritance dispatch for you.
To subclass another guest, specify that guest's name as a second parameter
in the guest definition:
```ruby
guest "ubuntu", "debian" do
require_relative "guest"
Guest
end
```
With the above component, the "ubuntu" guest inherits from "debian." When
a capability is looked up for "ubuntu", all capabilities from "debian" are
also available, and any capabilities in "ubuntu" override parent capabilities.
When detecting operating systems with `detect?`, Vagrant always does a
depth-first search by searching the children operating systems before
checking their parents. Therefore, it is guaranteed in the above example
that the `detect?` method on "ubuntu" will be called before "debian."

View File

@ -0,0 +1,45 @@
---
sidebar_current: "plugins-hosts"
---
# Plugin Development: Hosts
This page documents how to add new host OS implementations to Vagrant,
allowing Vagrant to properly configure new host operating systems
for features such as NFS shared folders. Prior to reading this, you should be familiar
with the [plugin development basics](/v2/plugins/development-basics.html).
<div class="alert alert-warn">
<p>
<strong>Warning: Advanced Topic!</strong> Developing plugins is an
advanced topic that only experienced Vagrant users who are reasonably
comfortable with Ruby should approach.
</p>
</div>
## Definition Component
Within the context of a plugin definition, new hosts can be defined
like so:
```ruby
host "some_os" do
require_relative "host"
Host
end
```
Guests are defined with the `host` method. The first argument is th
name of the host. This name isn't actually used anywhere, but may in
the future, so choose something helpful. Then, the block argument returns a
class that implements the `Vagrant.plugin(2, :host)` interface.
## Implementation
Implementations of hosts subclass `Vagrant.plugin(2, :host)`. Within
this implementation, various methods for different tasks must be implemented.
Instead of going over each task, the easiest example would be to take a
look at an existing host implementation.
There are [many host implementations](https://github.com/mitchellh/vagrant/tree/master/plugins/hosts),
but you can view the [BSD host implementation](https://github.com/mitchellh/vagrant/blob/master/plugins/hosts/bsd/host.rb) as a starting point.

View File

@ -0,0 +1,20 @@
---
sidebar_current: "plugins"
---
# Plugins
Vagrant comes with many great features out of the box to get your environments up
and running. Sometimes, however, you want to change the way Vagrant does something
or add additional functionality to Vagrant. This can be done via Vagrant
_plugins_.
Plugins are powerful, first-class citizens that extend Vagrant using a
well-documented, stable API that can withstand major version upgrades.
In fact, most of the core of Vagrant is [implemented using plugins](https://github.com/mitchellh/vagrant/tree/master/plugins).
Since Vagrant [dogfoods](http://en.wikipedia.org/wiki/Eating_your_own_dog_food) its own
plugin API, you can be confident that the interface is stable and well supported.
Use the navigation on the left below the "Plugins" section to learn more
about how to use and build your own plugins.

View File

@ -0,0 +1,101 @@
---
sidebar_current: "plugins-packaging"
---
# Plugin Development: Packaging & Distribution
This page documents how to add new commands to Vagrant, invokable.
This page documents how to organize the file structure of your plugin
and distribute it so that it is installable using
[standard installation methods](/v2/plugins/usage.html).
Prior to reading this, you should be familiar
with the [plugin development basics](/v2/plugins/development-basics.html).
<div class="alert alert-warn">
<p>
<strong>Warning: Advanced Topic!</strong> Developing plugins is an
advanced topic that only experienced Vagrant users who are reasonably
comfortable with Ruby should approach.
</p>
</div>
## Example Plugin
The best way to describe packaging and distribution is to look at
how another plugin does it. The best example plugin available for this
is [vagrant-aws](https://github.com/mitchellh/vagrant-aws).
By using [Bundler](http://gembundler.com) and Rake, building a new
vagrant-aws package is easy. By simply calling `rake package`, a
`gem` file is dropped into the directory. By calling `rake release`,
the gem is built and it is uploaded to the central [RubyGems](http://rubygems.org)
repository so that it can be installed using `vagrant plugin install`.
Your plugin can and should be this easy, too, since you basically
get this for free by using Bundler.
## Setting Up Your Project
To setup your project, run `bundle gem vagrant-my-plugin`. This will create a
`vagrant-my-plugin` directory that has the initial layout to be a RubyGem.
You should modify the `vagrant-my-plugin.gemspec` file to add any
dependencies and change any metadata. View the [vagrant-aws.gemspec](https://github.com/mitchellh/vagrant-aws/blob/master/vagrant-aws.gemspec)
for a good example.
<div class="alert alert-warn">
<p>
<strong>Do not depend on Vagrant</strong> for your gem. Vagrant
is no longer distributed as a gem, and you can assume that it will
always be available when your plugin is installed.
</p>
</div>
Next, create a `Rakefile` that has at the very least, the following
contents:
```ruby
require 'rubygems'
require 'bundler/setup'
Bundler::GemHelper.install_tasks
```
If you run `rake -T` now, which lists all the available rake tasks,
you should see that you have the `package` and `release` tasks. You
can now develop your plugin and build it!
You can view the [vagrant-aws Rakefile](https://github.com/mitchellh/vagrant-aws/blob/master/Rakefile)
for a more comprehensive example that includes testing.
## Testing Your Plugin
You have a couple options for testing your plugin. First, you can run
`rake package`, then `vagrant plugin install` the resulting file to
test it. The downside of this is that there is a pretty slow feedback
loop every time you want to test the plugin.
Alternatively, you can depend on Vagrant from your Gemfile for development
purposes only. Then you can use `bundle exec vagrant` and a Vagrantfile
in your own directory to test it. This has a fast feedback loop, but requires
that Vagrant has all the dependencies it needs installed on your system.
vagrant-aws uses the second option. You can see the dependency in the
[Gemfile](https://github.com/mitchellh/vagrant-aws/blob/master/Gemfile).
The Vagrantfile is gitignored so that sensitive and volatile test
information can be put into it. The important bit is that the Vagrantfile
must have a `Vagrant.require_plugin` call so that it is loaded, since
Vagrant doesn't automatically know about plugins not installed using
`vagrant plugin`.
For example, a vagrant-aws development Vagrantfile might look like this:
```ruby
Vagrant.require_plugin "vagrant-aws"
Vagrant.configure("2") do |config|
config.vm.box = "test"
end
```
Then you can run `bundle exec vagrant up` to test it. Note the "bundle exec"
is required so that Bundler uses the proper Vagrant installation.

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