-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* triggers working * Split out classes. Add script provsioner * Package installer, host file setup * commentsd * quit on empty package list * Refactor to support bridging * Bridged network for VB * Renaname library code * RAM check * Edit comment * Improving hosts file update * Rename script * Handle multiple IF with same IP (WMware) * git attributes * updated * WMware bridge * fix * Restructure * Use bento/centos9 for arm * Chomp ip output * Fix * Support pre-provision e.g. on bento centos we need EPEL On boxomatic it is already present * Preinstall JQ/YQ * Fix amd64 yq * Update comment * Update README * adjust * Update provision instructions
- Loading branch information
1 parent
dbb8c2e
commit acb5c4d
Showing
9 changed files
with
822 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.rb text eol=lf | ||
*.sh text eol=lf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
*.docx | ||
*.tmp | ||
*/**/*.hidden.* | ||
.vagrant/ | ||
.vagrant/ | ||
temp/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Generic Vagrant Template | ||
|
||
This is a generic template for building cross-platform Vagrant VM builds. It is intended to be copied to a specific project, then edited there for that project's requirements. | ||
|
||
It should be very simple affair to customize this for a given project and more or less limited to | ||
|
||
1. Define the network type by editing [NETWORK_SETTINGS](./Vagrantfile#L9). | ||
* `NAT` - run VMs in a private network with the given [IP prefix](./Vagrantfile#L11) (the default is known to work with all 3 platforms) and [IP of the first machine](./Vagrantfile#L12) in the VM list. Subsequent machines will have contiguous IP addresses. | ||
* `BRIDGE` - run VMs on host machine's LAN. Useful for Kubernetes deployments as it's not necessary to port-forward nodeports. | ||
1. Define the VMs required by editing the [VIRTUAL_MACHINES](./Vagrantfile#L16) list and setting the properties for each machine in the list. | ||
* All VMs will have `jq` and `yq` installed by default. Additional packages can be added by populating the [packages](./Vagrantfile#L22) list for each VM. Package names are specific to the VM's package manager (CentOS - `yum`, Ubuntu - `apt`). | ||
1. Additional customizations such as port-forwards or shell provision steps can be added inside the [Hypervisor block](./Vagrantfile#L42-L45), using Hypervisor class's methods: | ||
|
||
* `port_forward` | ||
|
||
Forward 8080 on host to 80 on guest | ||
|
||
```ruby | ||
hv.port_forward host: 8080, guest: 80 | ||
``` | ||
|
||
Note that the SSH port is automatically forwarded by Vagrant so you don't have to. | ||
* `provision_script` | ||
Run the given script which should be placed in the [linux](./linux/) subdirectory in the guest. The shell script can be passed optional arguments. Note that the same script will be run on *all* guests, so ensure it is [distro aware](./linux/setup_host.sh#L11-L13) and idempotent. Host name should be set already as long as the script comes after `hv.deploy` so that can also be switched on | ||
```ruby | ||
hv.provision_script [arg1 , arg2, ...argn,] script: "my_script.sh" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# -*- mode: ruby -*- | ||
# vi: set ft=ruby : | ||
|
||
require_relative "./utils" | ||
require_relative "./hypervisor" | ||
require_relative "./host" | ||
|
||
# Define network that the virtual machines will join. | ||
NETWORK_SETTINGS = { | ||
network_type: "BRIDGE", # NAT = use a private network; BRIDGE = use addresses from your broadband router's network. | ||
private_network: "192.168.56.", # Network prefix for VM network if using NAT mode. Ignored for BRIDGE. | ||
ip_start: 11, # First IP to use for VMs on private network if using NAT mode. Ignored for BRIDGE. | ||
} | ||
|
||
# Define list of virtual machines to be created here. | ||
VIRTUAL_MACHINES = [ | ||
{ | ||
name: "controller", # Name (and hostname) for the VM | ||
cpu: 4, # Number of vCPUs to assign it | ||
memory: 2048, # RAM in MB to assign it | ||
box: Hypervisor.centos, # Operating system to run (centos or ubuntu) | ||
#packages: ["some-package"], # Packages to be installed by OS's package manager | ||
}, | ||
{ | ||
name: "target1", | ||
cpu: 2, | ||
memory: 2048, | ||
box: Hypervisor.ubuntu, | ||
}, | ||
] | ||
|
||
# Deploy the VMs | ||
Vagrant.configure("2") do |config| | ||
config.vm.box_check_update = false | ||
|
||
# For each machine defined in VIRTUAL_MACHINES above | ||
VIRTUAL_MACHINES.each_with_index do |vm, index| | ||
config.vm.define vm[:name] do |node| | ||
# Set the "box", i.e. operating system for guest | ||
node.vm.box = vm[:box].box | ||
# Get hypervisor support for the host OS | ||
Hypervisor.get node: node do |hv| | ||
# Deploy the VM | ||
hv.deploy vm: vm, network: NETWORK_SETTINGS, index: index | ||
end | ||
end | ||
end | ||
|
||
# Tasks to perform before any VMs are created | ||
config_shown = false | ||
config.trigger.before :up do |trigger| | ||
trigger.info = "Pre-start trigger" | ||
trigger.ruby do |env, machine| | ||
if !config_shown | ||
host = Host.get() | ||
show_system_info(trigger, host) | ||
validate_configuration(trigger, host, VIRTUAL_MACHINES) | ||
config_shown = true | ||
end | ||
end | ||
end | ||
|
||
# Tasks to perform after all VMs are created | ||
vm_count = 0 | ||
config.trigger.after :up do |trigger| | ||
trigger.info = "Post-provision" | ||
trigger.ruby do |env, machine| | ||
vm_count += 1 | ||
if vm_count == env.machine_names.length() | ||
post_provision(env) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,261 @@ | ||
########################################################################## | ||
# | ||
# Host is an abstraction for the host system we are building VMs on. | ||
# | ||
########################################################################## | ||
class Host | ||
CPU_NAME = 0 | ||
CPU_COUNT = 1 | ||
RAM = 2 | ||
OS_NAME = 3 | ||
HV_EXISTS = 4 | ||
|
||
@@specs = nil | ||
|
||
def self.get() | ||
if OS.apple_silicon? | ||
return AppleSiliconHost.new | ||
elsif OS.mac? | ||
return IntelMacHost.new | ||
elsif OS.windows? | ||
return WindowsHost.new | ||
elsif OS.linux_arm? | ||
return ArmLinuxHost.new | ||
elsif OS.linux? | ||
return IntelLinuxHost.new | ||
else | ||
raise DetectionError.new "FATAL - Cannot determine your operating system" | ||
end | ||
end | ||
|
||
def get_system_name() | ||
return "" | ||
end | ||
|
||
def gateway_addresses() | ||
"" | ||
end | ||
end | ||
|
||
class WindowsHost < Host | ||
include Powershell | ||
|
||
def physical_ram_gb() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[RAM].to_i | ||
end | ||
|
||
def cpu_count() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[CPU_COUNT].to_i | ||
end | ||
|
||
def cpu_name() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[CPU_NAME] | ||
end | ||
|
||
def os_name() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[OS_NAME] | ||
end | ||
|
||
def hypervisor_name() | ||
return "VirtualBox" | ||
end | ||
|
||
def hypervisor_exists? | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
@@specs[HV_EXISTS] == "1" | ||
end | ||
|
||
private | ||
|
||
def get_sysinfo() | ||
ps = <<~PS | ||
$p = Get-CimInstance Win32_Processor | Select-Object NumberOfLogicalProcessors, Name | ||
$m = (Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB | ||
$o = (Get-CimInstance Win32_OperatingSystem | select -ExpandProperty Name).split('|') | Select-Object -First 1 | ||
$hv = 0 | ||
try { | ||
$d = Get-ItemProperty hklm:Software/Oracle/VirtualBox -PSProperty InstallDir -ErrorAction Stop | ||
if (Test-Path (Join-Path $d.InstallDir vboxmanage.exe)) { | ||
$hv = 1 | ||
} | ||
} | ||
catch {} | ||
Write-Host "$($p.Name)/$($p.NumberOfLogicalProcessors)/$m/$o/$hv" | ||
PS | ||
@@specs = self.powershell(ps).split("/") | ||
end | ||
end | ||
|
||
class MacHost < Host | ||
def physical_ram_gb() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[RAM].to_i / 1073741824 | ||
end | ||
|
||
def cpu_count() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[CPU_COUNT].to_i | ||
end | ||
|
||
def cpu_name() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[CPU_NAME] | ||
end | ||
|
||
def os_name() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[OS_NAME] | ||
end | ||
|
||
def get_system_name() | ||
return "Mac" | ||
end | ||
|
||
def gateway_addresses() | ||
cmd = "netstat -rn -f inet | egrep '^default.*UGS' | awk '{print $2}' | xargs echo | tr ' ' ','" | ||
%x{ #{cmd} }.chomp() | ||
end | ||
|
||
private | ||
|
||
def get_sysinfo() | ||
sh = <<~SHEL | ||
pc=$(sysctl -n "hw.ncpu") | ||
m=$(sysctl -n "hw.memsize") | ||
pn=$(sysctl -n "machdep.cpu.brand_string") | ||
os_name=$(awk '/SOFTWARE LICENSE AGREEMENT FOR macOS/' '/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf' | awk -F 'macOS ' '{print $NF}' | awk '{print substr($0, 0, length($0)-1)}') | ||
os_ver=$(sw_vers | awk '/ProductVersion/ { print $2 }') | ||
echo "${pn}/${pc}/${m}/${os_name} ${os_ver}" | ||
SHEL | ||
@@specs = %x{ #{sh} }.chomp().split("/") | ||
end | ||
end | ||
|
||
class IntelMacHost < MacHost | ||
def hypervisor_name() | ||
return "VirtualBox" | ||
end | ||
|
||
def hypervisor_exists? | ||
Dir.exists?("/Applications/VirtualBox.app") | ||
end | ||
end | ||
|
||
class AppleSiliconHost < MacHost | ||
def hypervisor_name() | ||
return "VMware Fusion" | ||
end | ||
|
||
def hypervisor_exists? | ||
Dir.exists?("/Applications/VMware Fusion.app") | ||
end | ||
end | ||
|
||
class LinuxHost < Host | ||
def physical_ram_gb() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[RAM].to_i / 1048576 | ||
end | ||
|
||
def cpu_count() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[CPU_COUNT].to_i | ||
end | ||
|
||
def cpu_name() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[CPU_NAME] | ||
end | ||
|
||
def os_name() | ||
if not @@specs | ||
self.get_sysinfo() | ||
end | ||
return @@specs[OS_NAME] | ||
end | ||
|
||
private | ||
|
||
def get_sysinfo | ||
sh = <<~SHEL | ||
m=$(awk '/MemTotal/ {print $2}' /proc/meminfo) | ||
pc=$(nproc) | ||
pn=$(cat /proc/cpuinfo | grep "model name" | uniq | cut -d ':' -f 2 | sed "s/^[ ]*//") | ||
o=$(source /etc/os-release && echo -n "$NAME $VERSION") | ||
echo "${pn}/${pc}/${m}/${o}" | ||
SHEL | ||
@@specs = %x{ #{sh} }.chomp().split("/") | ||
end | ||
end | ||
|
||
class IntelLinuxHost < LinuxHost | ||
def hypervisor_name() | ||
return "VirtualBox" | ||
end | ||
|
||
def hypervisor_exists? | ||
sh = <<~SHEL | ||
if command -v VBoxManage > /dev/null | ||
then | ||
echo -n "1" | ||
else | ||
echo -n "0" | ||
fi | ||
SHEL | ||
%x{ #{sh} }.chomp() == "1" | ||
end | ||
|
||
def get_system_name() | ||
return "Intel" | ||
end | ||
end | ||
|
||
class ArmLinuxHost < LinuxHost | ||
def hypervisor_name() | ||
return "VMware Workstation" | ||
end | ||
|
||
def hypervisor_exists? | ||
sh = <<~SHEL | ||
if command -v vmrun > /dev/null | ||
then | ||
echo -n "1" | ||
else | ||
echo -n "0" | ||
fi | ||
SHEL | ||
%x{ #{sh} }.chomp() == "1" | ||
end | ||
|
||
def get_system_name() | ||
return "ARM" | ||
end | ||
end |
Oops, something went wrong.