Bạn cần một plugin Vagrant trong Vagrantfile?


80

Việc thực thi giả sử Vagrantfileyêu cầu phải cài đặt một plugin Vagrant cụ thể. Vì vậy, về cơ bản những gì bạn cần làm là

$ vagrant plugin install foobar-plugin
$ vagrant up

Nếu bạn bỏ qua bước đầu tiên, vagrant upkhông thành công.

Có tùy chọn nào trong Vagrant để làm cho nó cài đặt plugin tự động không? Nói cách khác: Có thể chỉ định Vagrantfileplugin nào được cài đặt tự động trước khi tạo và khởi động máy không?

Câu trả lời:


24

Cập nhật 2019: Vagrant hiện có chức năng yêu cầu plugin thông Vagrantfilequa:

Vagrant.configure("2") do |config|
  config.vagrant.plugins = "vagrant-some-plugin"

  # or as array:
  config.vagrant.plugins = ["vagrant-some-plugin", "vagrant-some-other-plugin"]

  # or as hash
  config.vagrant.plugins = {"vagrant-some-plugin" => {"version" => "1.0.0"}}
end

Nếu Vagrant phát hiện có plugin chưa được cài đặt, nó sẽ nhắc người dùng tự cài đặt chúng:

$ vagrant up
Vagrant has detected project local plugins configured for this
project which are not installed.

  vagrant-some-plugin
Install local plugins (Y/N) [N]: y
Installing the 'vagrant-some-plugin' plugin. This can take a few minutes...
Fetching vagrant-some-plugin-1.0.0.gem
Installed the plugin 'vagrant-some-plugin (1.0.0)'!


Vagrant has completed installing local plugins for the current Vagrant
project directory. Please run the requested command again.

Xem https://www.vagrantup.com/docs/vagrantfile/vagrant_settings.html


Điều gì sẽ xảy ra nếu tôi muốn bỏ qua lời nhắc và tự động cài đặt tất cả các plugin bắt buộc?
pihentagy

67

CẬP NHẬT ngày 31 tháng 8 năm 2018: Xem bản sửa lỗi của @ Starx bên dưới để biết các phiên bản sau của Vagrant (1.8 trở lên)

Đây là phiên bản dựa trên giải pháp của Louis St.

required_plugins = %w(vagrant-share vagrant-vbguest...)

plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
if not plugins_to_install.empty?
  puts "Installing plugins: #{plugins_to_install.join(' ')}"
  if system "vagrant plugin install #{plugins_to_install.join(' ')}"
    exec "vagrant #{ARGV.join(' ')}"
  else
    abort "Installation of one or more plugins has failed. Aborting."
  end
end

5
Chắc chắn là giải pháp tốt nhất vào lúc này
Anis

1
Tôi đã cập nhật giải pháp vào ngày 20 tháng 4 để chỉ sử dụng một lệnh gọi "hệ thống" để cài đặt tất cả các plugin bị thiếu.
Amos Shapira

4
Điều này đã không hoạt động. Nó đã đi vào một vòng lặp vô hạn của việc cài đặt các plugin. Bằng cách nào đó quá trình lang thang mới không thể nhấc các plugin mới được cài đặt trong quá trình lang thang mẹ
Arif Akram Khan

1
Cảm ơn các cập nhật. Tôi thực sự đã thực hiện theo giải pháp do mkuzmin đề xuất tại đây: github.com/mitchellh/vagrant/issues/4347 . Nó liên quan đến việc sử dụng một plugin có tên là các plugin vagrant và sau đó sử dụng một số mã (rất giống với bạn) trong Vagrantfile.
Arif Akram Khan,

1
@SteveHenty Tôi thông cảm với nhận xét của bạn nhưng việc chuyển nó thành một plugin sẽ làm mất đi mục đích của mã (chỉ có thể xuất hiện git clone...; cd ...; vagrant uplần đầu).
Amos Shapira

51

Vì tôi là một nhà phát triển Ruby và Bindler không còn được duy trì, tôi thấy điều tự nhiên nhất là chỉ cần viết một số mã ở đầu Vagrantfile của mình để cài đặt các plugin cần thiết nếu thiếu (ví dụ: trước Vagrant.configuredòng)

Những điều sau đây phù hợp với tôi:

required_plugins = %w( vagrant-hostmanager vagrant-someotherplugin )
required_plugins.each do |plugin|
  system "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
end

system, không giống như sử dụng backticks, sẽ lặp lại lệnh tới stdout, giống như việc bạn tự chạy lệnh. Và theo cách này, tôi không cần một plugin hoặc hệ thống có tên lạ nào khác để theo dõi các plugin bắt buộc mà Vagrant có thể cập nhật.


8
Bạn sẽ cần phải 'thực thi' vagrant # {ARGV.join ''} "'để khởi động lại quá trình vagrant khi đã cài đặt plugin.
Rob Kinyon

1
Điểm tốt. Trong trường hợp của tôi, tôi đã gặp lỗi, nhưng hãy xem đầu ra của plugin cài đặt và biết để chạy lại lệnh. Để nó tự động chạy lại sẽ là một cải tiến thậm chí còn tốt hơn. Nếu viết lại, có lẽ tôi sẽ kiểm tra xem có plugin nào chưa được cài đặt hay không, và nếu có, hãy cài đặt plugin trước rồi chạy lại script thay vì kiểm tra và cài đặt từng plugin một ...
Louis St -Ngày

2
Sẽ thật tuyệt nếu có Vagrant.has_plugin?lệnh ở cấp shell hoặc chỉ cần vagrant plugin installkiểm tra xem plugin đã ở đó chưa.
sakovias

1
Chà, bạn luôn có thể làm điều gì đó như thế if [ $(vagrant plugin list | egrep 'vagrant-hostsupdater|vagrant-share' -c) == 2 ] ; then echo "All plugins installed." ; else echo "Missing plugin"; finhưng có một lý do không ai viết các tập lệnh bash nếu họ có thể giúp nó ;-) Có thể thử nghiệm thêm với lệnh plugin vagrant?
Louis St-Amour

48

Như tôi đã chỉ ra trong câu trả lời của tôi cho câu hỏi khác của bạn , bạn có thể sử dụng bindler để cài đặt một tập hợp các plugin cụ thể cho một dự án bằng một lệnh duy nhất.

Nếu bindler được cài đặt và plugin được yêu cầu không được cài đặt, bindler sẽ gặp lỗi và sẽ hủy bỏ quá trình. Ngoài ra còn có một vấn đề mở liên quan đến việc tự động cài đặt các plugin trên vagrant ups nhưng cho đến nay vẫn chưa có ai đăng ký.

Nếu bạn không muốn sử dụng bindler, bạn có thể sử dụng Vagrant.has_plugin?(có sẵn trên 1.3.0+) ở đầu của bạn Vagrantfilevà báo lỗi nếu plugin cần thiết chưa được cài đặt.

Cái gì đó như:

unless Vagrant.has_plugin?("vagrant-some-plugin")
  raise 'some-plugin is not installed!'
end

Vagrant.configure("2") do |config|
  config.vm.box = "box-name"
end

CẬP NHẬT : Bindler không còn được hỗ trợ và không có tính năng tương đương nào được cung cấp bởi lõi Vagrant kể từ ngày 11 tháng 5 năm 2015


14
Đối với những nhân viên Google trong tương lai, xin lưu ý rằng câu trả lời này hơi lỗi thời. Giờ đây, bạn có thể chỉ định các thành phần phụ thuộc của mình Gemfiletrong :pluginsnhóm mà Vagrant sẽ kiểm tra. Xem câu trả lời của tôi bên dưới để biết thêm chi tiết.
Jonathan Bender

2
Gemfiledành cho phát triển plugin Vagrant. Xem github.com/mitchellh/vagrant/issues/8370
mixel

10

Xin lưu ý rằng kể từ Vagrant 1.5, bạn có thể chỉ định các phụ thuộc của mình trong của bạn Gemfile. Theo bài đăng trên blog về bản cập nhật :

Bây giờ, Vagrant 1.5 sẽ tự động tải bất kỳ viên ngọc nào trong nhóm "plugin" trong Gemfile của bạn. Ví dụ, đây là Gemfile cho một plugin "vagrant-bar":

source "https://rubygems.org"

group :development do
  gem "vagrant",
    git: "https://github.com/mitchellh/vagrant.git"
end

group :plugins do
  gem "vagrant-foo",
  gem "vagrant-bar", path: "."
end

8
Đó không phải là bài đăng trên blog đề cập đến việc phát triển plugin Vagrant ? Hộp Vagrant thường không có Gemfiles, họ sử dụng Vagrantfiles.
Don McCurdy

1
Bạn nói đúng rằng các hộp Vagrant không có Gemfiles (bạn có thể có một Vagrantfile không yêu cầu bất kỳ plugin nào), nhưng nếu bạn đang sử dụng plugin (bối cảnh của blog là phụ thuộc cho plugin của riêng bạn, nhưng vẫn giữ nguyên true cho Vagrantfiles), bạn nên sử dụng Gemfile để chỉ định các yêu cầu đó.
Jonathan Bender

7
Cảm ơn, điều đó hữu ích. Vì nhiều người dùng Vagrant không phải là nhà phát triển ruby ​​và sẽ chưa có Gemfile, bạn có vui lòng giải thích cách bạn thiết lập điều đó không? Tôi đã tạo một cái tương tự như ví dụ của bạn, nhưng vagrant upkhông tự động tải bất cứ thứ gì. Đã thử bundle installnhưng điều đó đưa ra lời nhắc về quyền của Rubygems hệ thống, điều này có vẻ không đúng.
Don McCurdy

1
Tôi đoán rằng bạn đang làm việc trong OSX bằng cách sử dụng cài đặt ruby ​​stock và gặp phải sự cố này: stackoverflow.com/questions/14607193 ?
Jonathan Bender

1
Trong thế giới của sách dạy nấu ăn đầu bếp, rất ít sẽ có một gemfile
mr.buttons

6

Không thể thêm nhận xét vào câu trả lời của Louis St-Amour, nhưng tôi muốn đăng điều này đề phòng bất kỳ ai cần trợ giúp mở rộng giải pháp của mình.

# Check for missing plugins
required_plugins = %w(vagrant-list)
plugin_installed = false
required_plugins.each do |plugin|
  unless Vagrant.has_plugin?(plugin)
    system "vagrant plugin install #{plugin}"
    plugin_installed = true
  end
end

# If new plugins installed, restart Vagrant process
if plugin_installed === true
  exec "vagrant #{ARGV.join' '}"
end

//, Lưu ý rằng vagrant-listở trên là một ví dụ về plugin, không phải là một phần cần thiết của mã. Bạn có thể xem các plugin khác của Vagrant tại đây: vagrant-lists.github.io
Nathan Basanese

3

Trên phiên bản mới của Vagrant, câu trả lời của @Amos Shapira bị mắc kẹt trong một vòng lặp vô hạn. Lý do cho điều đó là mỗi lệnh gọi vagrant plugin installcũng xử lý Vagrantfilevà khi được xử lý sẽ thực thi mã liên quan đến cài đặt plugin lặp đi lặp lại, v.v.

Đây là giải pháp của tôi để tránh vòng lặp.

# Plugins
#
# Check if the first argument to the vagrant
# command is plugin or not to avoid the loop
if ARGV[0] != 'plugin'

  # Define the plugins in an array format
  required_plugins = [
    'vagrant-vbguest', 'vagrant-hostmanager', 
    'vagrant-disksize'
  ]         
  plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
  if not plugins_to_install.empty?

    puts "Installing plugins: #{plugins_to_install.join(' ')}"
    if system "vagrant plugin install #{plugins_to_install.join(' ')}"
      exec "vagrant #{ARGV.join(' ')}"
    else
      abort "Installation of one or more plugins has failed. Aborting."
    end

  end
end

1

Tôi vừa nhận thấy ở đây http://docs.vagrantup.com/v2/plugins/packaging.html một hướng dẫn

Vagrant.require_plugin "vagrant-aws"

điều này thực hiện chính xác những gì giống như những gì descibed fgrehm: phát sinh lỗi nhanh chóng nếu plugin không được cài đặt.

Theo như tôi biết, không có cách nào để tự động cài đặt plugin


6
Vagrant.require_plugin đã bị phản đối trên 1.5 +
EIS

1
Đây là bài đăng trên blog chính thức về việc ngừng sử dụng: vagrantup.com/blog/vagrant-1-5-plugin-improvements.html Theo hiểu biết hạn chế của tôi, nó không được dùng nữa vì không còn cần thiết nữa, Vagrant giờ đây sẽ tự động kiểm tra sự phụ thuộc của plugin. Không hoàn toàn tự tin rằng mình hiểu được bài viết trên blog mặc dù ...
Jeff Widman

Bài đăng nói về việc tự động kiểm tra các phụ thuộc của plugin , nhưng tôi chưa thấy gì về các phụ thuộc của chính hộp Vagrant.
Don McCurdy

Vagrant.require_pluginkhông được dùng nữa. Đã kiểm tra bằng Vagrant 1.7.4.
czerasz

1

Câu trả lời của tôi rất gần với câu trả lời của Louis St-Amour , nhưng thay vì cài đặt plugin tự động, nó chỉ xuất hiện thông báo lỗi, do đó người dùng phải cài đặt plugin theo cách thủ công.

Tôi muốn người dùng biết về bất kỳ plugin nào được cài đặt, bởi vì chúng áp dụng trên toàn cầu cho tất cả các phiên bản Vagrant, không chỉ cho Vagrantfile hiện tại.

Đặt ở phía trên cùng của Vagrantfilemột dòng như thế này cho mỗi plugin, trong ví dụ này, vagrant-vbguest:

 raise "vagrant-vbguest plugin must be installed" unless Vagrant.has_plugin? "vagrant-vbguest"

1

Bạn có thể sử dụng dự án này (tôi là tác giả): https://github.com/DevNIX/Vagrant-dependency-manager

Nó dựa trên những câu trả lời tương tự nhưng cố gắng hoàn thiện và ổn định hơn. Ưu điểm lớn của ý tưởng này là, bạn có thể phân phối Vagrantfile của mình và nó sẽ chạy trên mọi máy tính bất kể các plugin được cài đặt trên môi trường đó.

Nó rất dễ dàng để sử dụng:

  1. Sao chép dependency_manager.rb bên cạnh Vagrantfile của bạn
  2. Bao gồm nó và gọi check_pluginschuyển các phần phụ thuộc của bạn dưới dạng một mảng

    Thí dụ:

    # -*- mode: ruby -*-
    # vi: set ft=ruby :
    
    require File.dirname(__FILE__)+"./dependency_manager"
    
    check_plugins ["vagrant-exec", "vagrant-hostsupdater", "vagrant-cachier", "vagrant-triggers"]
    
    Vagrant.configure(2) do |config|
    
      config.vm.box = "base"
    
    end
    
  3. ???

  4. Lợi nhuận!

Tôi rất thích hợp nhất các yêu cầu kéo, khắc phục bất kỳ vấn đề nào bạn có thể gặp phải và lấy ý tưởng về các tính năng mới. Hiện tại tôi đang nghĩ đến việc cập nhật chính trình quản lý phụ thuộc và yêu cầu các phiên bản plugin cụ thể: D

Trân trọng!


0

Tôi gặp sự cố với bản cài đặt mới của Vagrant, trong đó thư mục .vagrant.d chưa được tạo. Tôi đã có thể làm cho đoạn trích từ Luis St. Amour hoạt động bằng cách tìm ra ngoại lệ.

required_plugins = %w(vagrant-share vagrant-vbguest)

begin
    plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
    if not plugins_to_install.empty?
        puts "Installing plugins: #{plugins_to_install.join(' ')}"
        if system "vagrant plugin install #{plugins_to_install.join(' ')}"
            exec "vagrant #{ARGV.join(' ')}"
        else
            abort "Installation of one or more plugins has failed. Aborting."
        end
    end
rescue
    exec "vagrant #{ARGV.join(' ')}"
end

Trên Windows, điều này mang lại cho tôi lỗi "Đưa máy 'mặc định' lên với nhà cung cấp 'hộp ảo' ... nhưng một quá trình khác đã thực hiện một hành động trên máy" vì upđang được chạy up. Có cách nào để tránh điều này mà không cần chạy vagrant uphai lần không?
Tom B

0

Đây là những gì tôi đang sử dụng trên Vagrant 1.8 và nó đang hoạt động tốt. Đặt cái này ở đâu đó trước khối cấu hình trong Vagrantfile của bạn.

# install required plugins if necessary
if ARGV[0] == 'up'
    # add required plugins here
    required_plugins = %w( plugin1 plugin2 plugin3 )
    missing_plugins = []
    required_plugins.each do |plugin|
        missing_plugins.push(plugin) unless Vagrant.has_plugin? plugin
    end

    if ! missing_plugins.empty?
        install_these = missing_plugins.join(' ')
        puts "Found missing plugins: #{install_these}.  Installing using sudo..."
        exec "sudo vagrant plugin install #{install_these}; vagrant up"
    end
end

Có vẻ như đó không phải là đa nền tảng.
thorr18
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.