从字面上来看,provision是准备,实现的功能是在原生镜像的基础上,进行一些附加的操作,以改变虚拟机的环境,比如安装应用,发布程序等。
在vagrant的 Vagrant.configure(2) do |config| 节点内,加入如下代码:
config.vm.provision "shell", inline: "echo hello provisio."
还有一种格式:
config.vm.provision "shell" do |s|
s.inline = "echo hello provision."
end
测试一下:
如果vm已经启动,直接运行
vagrant provision
就可以看到控制台显示的信息了。或者:
vagrant reload --provision
重启vm,并自动执行provision操作。
Tips: 运行后可能会提示:default: stdin: is not a tty 错误,不影响执行效果,想要去除,在配置文件增加一行即可。
config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"
provision任务是预先设置的一些操作指令,格式:
config.vm.provision 命令字 json格式参数
config.vm.provion 命令字 do |s|
s.参数名 = 参数值
end
每一个 config.vm.provision 命令字
代码段,我们称之为一个provisioner。
根据任务操作的对象,provisioner可以分为:
根据vagrantfile的层次,分为:
Vagrant.configure("2")
的下一层次,形如: config.vm.provision ...
config.vm.define "web" do |web|
的下一层次,web.vm.provision ...
执行的顺序是先执行configure级任务,再执行vm级任务,即便configure级任务在vm定义的下面才定义。例如:
Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: "echo foo"
config.vm.define "web" do |web|
web.vm.provision "shell", inline: "echo bar"
end
config.vm.provision "shell", inline: "echo baz"
end
输出结果:
==> default: "foo"
==> default: "baz"
==> default: "bar"
尝试了helloword,我们来了解一下provision任务是怎么运行的。
run:"always"
属性--provision
参数,适用于 vagrant up
和 vagrant reload
vagrant provision
命令。在编写provision任务时,可能同时存在几种类型的任务,但执行时可能只执行一种,如,我只执行shell类型的任务。可以如下操作:
vagrant provision --provision-with shell
类型名 | 范例 |
---|---|
string | “arg1” |
hash | {key1:value1,key2:value2} |
array | [“arg1”,”arg2”] |
boolean | true,false |
必选:inline 或者 path
可选:
参数名 | 类型 | 说明 |
---|---|---|
args | string or array | 传递给shell或path的参数 |
env | hash | 传递给脚本的环境变量 |
binary | boolean | 是否替换windows的行结束符,这个参数名有点奇怪 |
privileged | boolean | 是否提权运行,如sudo执行,缺省为true |
upload_path | boolean | 上传到vm中的路径,缺省是/tmp/vagrant-shell |
keep_color | boolean | 设置是否脚本自身控制颜色,缺省为false,表示使用绿色和红色来显示输出到stdout和stderr的消息 |
name | string | 给当前执行的脚本命名,与provisioner名称无关 |
powershell_args | string | windows相关,略 |
powershell_elevated_interactive | boolean | windows相关,略 |
在有些情况下,vagrant会帮你处理引号,但建议,都匹配好双引号,可读性也好一些。
helloword只是一个开始,对于inline模式,命令只能在写在一行中。一个以上的命令,可以写在同一行,用分号分隔,这属于shell编程的范畴,在这里不多解释。
单行脚本使用的基本格式:
config.vm.provision "shell", inline: "echo foo"
shell命令的参数还可以写入do ... end
代码块中,如下:
config.vm.provision "shell" do |s|
s.inline = "echo hello provision."
end
其他,如后面提到的path参数也是一样的。
一个shell代码段,在1.7.0+版本,这个provisioner是可以命名的,如:
config.vm.provision "myshell,type:"shell" do |s| s.inline = "echo hello provision." end
Tips: provisioner命名块如果重名,会有覆盖问题。
一个shell节点内,如果连续写一条以上s.inline,则只有最后一条有效,前面的会被后面的覆盖掉。
如果要执行脚本较多,可以在Vagrantfile中指定内联脚本,在Vagrant.configure节点外面,写入命名内联脚本:
$script = <