Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Housekeeping #13

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,12 @@ and provision Proxmox virtual machines.
Install using standard Vagrant plugin method:

```
$ vagrant plugin install vagrant-proxmox
$ vagrant plugin install vagrant-proxmox-0.2.0.gem
```

This will install the plugin from [RubGems.org](http://rubygems.org/).

## Usage

First install the provided dummy vagrant box:

```
$ vagrant box add dummy dummy_box/dummy.box
```

Then for an openvz container create a Vagrantfile that looks like the following (note that you might have to add "@pam" to your username if you're getting a "401 Unauthorized" error):
For an openvz container create a Vagrantfile that looks like the following (note that you might have to add "@pam" to your username if you're getting a "401 Unauthorized" error):

```
Vagrant.configure('2') do |config|
Expand Down Expand Up @@ -110,8 +102,14 @@ You can download an example Ubuntu based template [here](https://www.dropbox.com

Finally run `vagrant up --provider=proxmox` to create and start the new OpenVZ container.

## Options
To make proxmox the default provider, add the following line at top level of the Vagrantfile.

```ruby
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'proxmox'
```

## Options
* `dry` Dont actually send data to the server.
* `endpoint` URL of the JSON API endpoint of your Proxmox installation
* `user_name` The name of the Proxmox user that Vagrant should use
* `password` The password of the above user
Expand Down Expand Up @@ -141,8 +139,13 @@ Finally run `vagrant up --provider=proxmox` to create and start the new OpenVZ c
* `qemu_sockets` The number of CPU sockets available to the VM
* `qemu_nic_model` which model of network interface card to use, default 'e1000'
* `qemu_bridge` connect automatically to this bridge, default 'vmbr0'
* `qemu_agent` whether to enable to qemu agent endpoint.
* `selected_node` If specified, only this specific node is used to create machines
* `disable_adjust_forwarded_port` If true, no ssh manipulations will be done.
* `pool` Resource pool to use.
* `hostname_append_id` Appends guest ID to its' hostname. Note that this effectively sets the hostname to ID, if it was empty beforehand.
* `full_clone` Creates full clone, instead of a linked one.
* `lxc_ssh_public_keys` public keys to be added to the authorized keys file of the machine, one key per line.

## Debug RestClient Communication with Proxmox-Node

Expand All @@ -165,6 +168,21 @@ Build the plugin gem with
$ rake build
```

For non-ruby folks. Needs `ruby` and `zlib` development headers (on Debian: `apt-get install ruby-dev zlib1g-dev`).

Use e.g. rvm to manage ruby versions. Do `rvm install "ruby-2.5.7"` to install the appropiate ruby version. Run `rvm use` then and check with `ruby --version` if it was properly activated. (If ruby complains about not using a login shell run `source ~/.rvm/scripts/rvm`)

You may then install dependencies and build with:
```bash
$ gem install bundler rake
$ bundle install
$ rake build
```

You can install the vagrant plugin then with `vagrant plugin install ./vagrant-proxmox-0.2.2.gem` (you might run into problems if you run it on a shell where you ran `rvm use` previously).

Optionally run the rspec tests with `rake spec`. (Make sure, that vagrant is installed in the ruby env you are using.)

Optionally run the rspec tests with


Expand Down
11 changes: 6 additions & 5 deletions lib/vagrant-proxmox/action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def self.action_up
b1.use GetNodeList
b1.use SelectNode
b1.use Provision
b1.use SetHostname
if env1[:machine].provider_config.vm_type == :openvz
b1.use Call, UploadTemplateFile do |env2, b2|
if env2[:result] == :ok
Expand Down Expand Up @@ -122,7 +123,7 @@ def self.action_halt
b2.use MessageAlreadyStopped
else
b2.use ConnectProxmox
b2.use ShutdownVm
b2.use env2[:force_halt] ? StopVm : ShutdownVm
end
end
else
Expand All @@ -142,7 +143,7 @@ def self.action_destroy
b1.use Call, ::Vagrant::Action::Builtin::DestroyConfirm do |env2, b2|
if env2[:result]
b2.use Call, IsStopped do |env3, b3|
b3.use ShutdownVm unless env3[:result]
b3.use StopVm unless env3[:result]
b3.use DestroyVm
b3.use ::Vagrant::Action::Builtin::ProvisionerCleanup
# b3.use CleanupAfterDestroy
Expand Down Expand Up @@ -194,9 +195,9 @@ def self.action_ssh_run
b.use Call, IsCreated do |env1, b1|
if env1[:result]
b1.use Call, IsStopped do |env2, b2|
if env2[:result]
if env2[:result]
b2.use MessageNotRunning
else
else
b2.use SSHRun
end
end
Expand Down Expand Up @@ -235,6 +236,6 @@ def self.action_ssh_run
autoload :UploadTemplateFile, action_root.join('upload_template_file')
autoload :UploadIsoFile, action_root.join('upload_iso_file')

end
end
end
end
34 changes: 18 additions & 16 deletions lib/vagrant-proxmox/action/adjust_forwarded_port_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,29 @@ def initialize app, env
end

def call env
if env[:machine].provider_config.disable_adjust_forwarded_port == true
next_action env
return
end

env[:ui].info I18n.t('vagrant_proxmox.adjust_forwarded_port_params')
config = env[:machine].provider_config
node = env[:proxmox_selected_node]
vm_id = nil

begin
if env[:machine].provider_config.disable_adjust_forwarded_port == false
vm_id = env[:machine].id.split("/").last
node_ip = env[:proxmox_connection].get_node_ip(node, 'vmbr0')
env[:machine].config.vm.networks.each do |type, options|
next if type != :forwarded_port
if options[:id] == "ssh"
# Provisioning and vagrant ssh will use this
# high port of the selected proxmox node
options[:auto_correct] = false
options[:host_ip] = node_ip
options[:host] = sprintf("22%03d", vm_id.to_i).to_i
env[:machine].config.ssh.host = node_ip
env[:machine].config.ssh.port = sprintf("22%03d", vm_id.to_i).to_s
break
end
vm_id = env[:machine].id.split("/").last
node_ip = env[:proxmox_connection].get_node_ip(node, 'vmbr0')
env[:machine].config.vm.networks.each do |type, options|
next if type != :forwarded_port
if options[:id] == "ssh"
# Provisioning and vagrant ssh will use this
# high port of the selected proxmox node
options[:auto_correct] = false
options[:host_ip] = node_ip
options[:host] = sprintf("22%03d", vm_id.to_i).to_i
env[:machine].config.ssh.host = node_ip
env[:machine].config.ssh.port = sprintf("22%03d", vm_id.to_i).to_s
break
end
end
end
Expand Down
19 changes: 13 additions & 6 deletions lib/vagrant-proxmox/action/clone_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ def call env
rescue StandardError => e
raise VagrantPlugins::Proxmox::Errors::VMCloneError, proxmox_exit_status: e.message
end

begin
vm_id = connection(env).get_free_vm_id
if config.hostname_append_id
hostname = env[:machine].config.vm.hostname
env[:machine].config.vm.hostname = "#{hostname}#{vm_id}"
end
params = create_params_qemu(config, env, vm_id, template_vm_id)
exit_status = connection(env).clone_vm node: node, vm_type: config.vm_type, params: params
exit_status == 'OK' ? exit_status : raise(VagrantPlugins::Proxmox::Errors::ProxmoxTaskFailed, proxmox_exit_status: exit_status)
Expand All @@ -36,17 +40,20 @@ def call env

env[:machine].id = "#{node}/#{vm_id}"

env[:ui].info I18n.t('vagrant_proxmox.done')
next_action env
end

private
def create_params_qemu(config, env, vm_id, template_vm_id)
# without network, which will added in ConfigClonedVm
{vmid: template_vm_id,
newid: vm_id,
name: env[:machine].config.vm.hostname || env[:machine].name.to_s,
description: "#{config.vm_name_prefix}#{env[:machine].name}"}
{
vmid: template_vm_id,
newid: vm_id,
name: env[:machine].config.vm.hostname || env[:machine].name.to_s,
description: "#{config.vm_name_prefix}#{env[:machine].name}",
pool: config.pool,
full: get_rest_boolean(config.full_clone),
}
end

end
Expand Down
80 changes: 19 additions & 61 deletions lib/vagrant-proxmox/action/config_clone.rb
Original file line number Diff line number Diff line change
@@ -1,94 +1,52 @@
module VagrantPlugins
module Proxmox
module Action

# This action modifies the configuration of a cloned vm
# Basically it creates a user network interface with hostfwd for the provisioning
# and an interface for every public or private interface defined in the Vagrantfile
# It applies only a subset of the whole configuration, excluding storage
# and network options, which are inherited from the base template.
class ConfigClone < ProxmoxAction

def initialize app, env
@app = app
@logger = Log4r::Logger.new 'vagrant_proxmox::action::config_clone'
@node_ip = nil
@guest_port = nil
end

def call env
env[:ui].info I18n.t('vagrant_proxmox.configuring_vm')
config = env[:machine].provider_config
node = env[:proxmox_selected_node]
vm_id = nil
vm_id = env[:machine].id.split("/").last

params = create_params_qemu(config, env, vm_id)
begin
vm_id = env[:machine].id.split("/").last
@node_ip = connection(env).get_node_ip(node, 'vmbr0') if config.vm_type == :qemu
@guest_port = sprintf("22%03d", vm_id.to_i).to_s
rescue StandardError => e
raise VagrantPlugins::Proxmox::Errors::VMConfigError, proxmox_exit_status: e.message
end

begin
template_config = connection(env).get_vm_config node: node, vm_id: vm_id, vm_type: config.vm_type
params = create_params_qemu(config, env, vm_id, template_config)
exit_status = connection(env).config_clone node: node, vm_type: config.vm_type, params: params
exit_status == 'OK' ? exit_status : raise(VagrantPlugins::Proxmox::Errors::ProxmoxTaskFailed, proxmox_exit_status: exit_status)
rescue StandardError => e
raise VagrantPlugins::Proxmox::Errors::VMConfigError, proxmox_exit_status: e.message
raise VagrantPlugins::Proxmox::Errors::VMConfigError, error_msg: e.message
end

env[:ui].info I18n.t('vagrant_proxmox.done')
next_action env
end

private
def create_params_qemu(provider_config, env, vm_id, template_config)
vm_config = env[:machine].config.vm
def create_params_qemu(config, env, vm_id)
desc = if config.use_plain_description
config.description
else
"#{config.vm_name_prefix}#{env[:machine].name}:#{config.description}"
end
params = {
vmid: vm_id,
description: "#{provider_config.vm_name_prefix}#{env[:machine].name}",
name: env[:machine].config.vm.hostname || env[:machine].name.to_s,
sockets: config.qemu_sockets,
cores: config.qemu_cores,
memory: config.vm_memory,
agent: get_rest_boolean(config.qemu_agent),
description: desc
}
# delete existing network interfaces from template
to_delete = template_config.keys.select{|key| key.to_s.match(/^net/) }
params[:delete] = to_delete.join(",") if not to_delete.empty?
# net0 is the provisioning network, derived from forwarded_port
net_num = 0
hostname = vm_config.hostname || env[:machine].name
netdev0 = [
"type=user",
"id=net0",
"hostname=#{hostname}",
"hostfwd=tcp:#{@node_ip}:#{@guest_port}-:22", # selected_node's primary ip and port (22000 + vm_id)
]
device0 = [
"#{provider_config.qemu_nic_model}",
"netdev=net0",
"bus=pci.0",
"addr=0x12", # starting point for network interfaces
"id=net0",
"bootindex=299"
]
params[:args] = "-netdev " + netdev0.join(",") + " -device " + device0.join(",")
# now add a network device for every public_network or private_network
# ip addresses are ignored here, as we can't configure anything inside the qemu vm.
# at least we can set the predefined mac address and a bridge
net_num += 1
vm_config.networks.each do |type, options|
next if not type.match(/^p.*_network$/)
nic = provider_config.qemu_nic_model
nic += "=#{options[:macaddress]}" if options[:macaddress]
nic += ",bridge=#{options[:bridge]}" if options[:bridge]
net = 'net' + net_num.to_s
params[net] = nic
net_num += 1
if config.qemu_iso
params[:ide2] = "#{config.qemu_iso},media=cdrom"
end

# some more individual settings
params[:ide2] = "#{provider_config.qemu_iso},media=cdrom" if provider_config.qemu_iso
params[:sockets] = "#{provider_config.qemu_sockets}".to_i if provider_config.qemu_sockets
params[:cores] = "#{provider_config.qemu_cores}".to_i if provider_config.qemu_cores
params[:balloon] = "#{provider_config.vm_memory}".to_i if provider_config.vm_memory and provider_config.vm_memory < template_config[:balloon]
params[:memory] = "#{provider_config.vm_memory}".to_i if provider_config.vm_memory
params
end

Expand Down
1 change: 1 addition & 0 deletions lib/vagrant-proxmox/action/connect_proxmox.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def initialize app, env

def call env
begin
@logger.debug 'connecting proxmox'
config = env[:machine].provider_config
connection = Connection.new config.endpoint,
vm_id_range: config.vm_id_range,
Expand Down
8 changes: 7 additions & 1 deletion lib/vagrant-proxmox/action/create_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def call(env)

begin
vm_id = connection(env).get_free_vm_id
if config.hostname_append_id
hostname = env[:machine].config.vm.hostname
env[:machine].config.vm.hostname = "#{hostname}#{vm_id}"
end
params = create_params_openvz(config, env, vm_id) if config.vm_type == :openvz
params = create_params_lxc(config, env, vm_id) if config.vm_type == :lxc
params = create_params_qemu(config, env, vm_id) if config.vm_type == :qemu
Expand Down Expand Up @@ -60,7 +64,9 @@ def create_params_qemu(config, env, vm_id)
cores: config.qemu_cores,
memory: config.vm_memory,
net0: network,
description: desc
description: desc,
agent: get_rest_boolean(config.qemu_agent),
pool: config.pool
}
end

Expand Down
2 changes: 0 additions & 2 deletions lib/vagrant-proxmox/action/destroy_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ def call env
raise VagrantPlugins::Proxmox::Errors::VMDestroyError, proxmox_exit_status: e.message
end

env[:ui].info I18n.t('vagrant_proxmox.done')

next_action env
end

Expand Down
11 changes: 9 additions & 2 deletions lib/vagrant-proxmox/action/proxmox_action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@ def next_action(env)
def get_machine_ip_address(env)
config = env[:machine].provider_config
if config.vm_type == :qemu
env[:machine].config.vm.networks.select \
{ |type, _| type == :forwarded_port }.first[1][:host_ip] || nil
ips = env[:machine].config.vm.networks.select {
|type, iface| type == :forwarded_port and iface[:host_ip] != "127.0.0.1"
}
return ips.first[1][:host_ip] if not ips.empty?

node = env[:proxmox_selected_node]
vm_id = env[:machine].id.split("/").last

connection(env).qemu_agent_get_vm_ip(node, vm_id)
else
env[:machine].config.vm.networks.select \
{ |type, _| type == :public_network }.first[1][:ip] || nil
Expand Down
2 changes: 0 additions & 2 deletions lib/vagrant-proxmox/action/read_ssh_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ def call env
env[:ui].detail "Using #{ip_address}:#{ssh_port} to connect to VM"
{host: ip_address, port: ssh_port}
end
env[:ui].detail "Found machine_ssh_info #{env[:machine_ssh_info]}"
env[:machine_ssh_info]
next_action env
end

Expand Down
1 change: 0 additions & 1 deletion lib/vagrant-proxmox/action/shutdown_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def call env
rescue StandardError => e
raise VagrantPlugins::Proxmox::Errors::VMShutdownError, proxmox_exit_status: e.message
end
env[:ui].info I18n.t('vagrant_proxmox.done')

next_action env
end
Expand Down
Loading