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

support imaging bookworm vm #791

Draft
wants to merge 3 commits into
base: production
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 38 additions & 0 deletions lib/puppet/functions/generate_mac.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require "digest"

# generates a deterministic pseudorandom mac address, using hostname as seed
#
# prefix validated to follow the following parameters:
# - must contain exactly 6 hex digits
# - second digit must be one of [2,6,a,e] (per RFC7042 §2.1, see "Local bit")
# - case is ignored
# - may contain unlimited number of non-alphanumerics as delimeters
#
# generated address contains
# - 3 byte fixed OUI (prefix)
# - 3 "random" byte (seeded from hostname)
# - XOR with up to 3 bits (index) for additonal interfaces
Puppet::Functions.create_function(:generate_mac) do
dispatch :generate_mac do
param "String", :prefix
param "String", :hostname
optional_param "Integer", :index
end

def generate_mac(prefix, hostname, index = 0)
unless index.between?(0, 7)
raise(ArgumentError, "#{index} must be between 0 and 7, I can only generate 8 mac addresses per host!")
end

oui = prefix.downcase.gsub(/[^0-9a-z]/, "")
unless /^[a-f0-9][26ae][a-f0-9]{4}$/.match?(oui)
raise(ArgumentError, "invalid mac prefix!")
end

integer_id = Digest::SHA256.hexdigest(hostname)[0, 6].to_i(16) ^ index
hex_id = sprintf("%06x", integer_id)
"#{oui}#{hex_id}".each_char.each_slice(2).map { |x| x.join }.join(":")
end
end
73 changes: 38 additions & 35 deletions manifests/virtual_machine.pp
Original file line number Diff line number Diff line change
Expand Up @@ -103,43 +103,46 @@
}
} else {
# If the VM does not already exist, create it.
if $build == 'bullseye' {
file { "${tmpdir}/preseed.cfg":
content => template("nebula/virtual_machine/${build}.cfg.erb"),
}
case $build {
'bullseye': {
file { "${tmpdir}/preseed.cfg":
content => template("nebula/virtual_machine/${build}.cfg.erb"),
}

$initrd_inject = "--initrd-inject '${tmpdir}/preseed.cfg'"
}
$initrd_inject = "--initrd-inject '${tmpdir}/preseed.cfg'"

exec { "${prefix}::virt-install":
require => [
Package['libvirt-clients'],
Package['virtinst'],
File["${tmpdir}/preseed.cfg"],
],
creates => $full_image_path,
timeout => $timeout,
path => [
'/usr/bin',
'/usr/sbin',
'/bin',
'/sbin',
],
command => @("VIRT_INSTALL_EOF")
/usr/bin/virt-install \
-n '${title}' \
-r ${ram_in_mb} \
--vcpus ${cpus} \
--location ${location} \
--os-type=linux \
--disk '${full_image_path},size=${disk}' \
--network bridge=${internet_bridge},model=virtio \
--network bridge=${lan_bridge},model=virtio \
--console pty,target_type=virtio \
--virt-type kvm \
--graphics vnc ${initrd_inject} \
--extra-args 'auto netcfg/disable_dhcp=true'
| VIRT_INSTALL_EOF
exec { "${prefix}::virt-install":
require => [
Package['libvirt-clients'],
Package['virtinst'],
File["${tmpdir}/preseed.cfg"],
],
creates => $full_image_path,
timeout => $timeout,
path => [
'/usr/bin',
'/usr/sbin',
'/bin',
'/sbin',
],
command => @("VIRT_INSTALL_EOF")
/usr/bin/virt-install \
-n '${title}' \
-r ${ram_in_mb} \
--vcpus ${cpus} \
--location ${location} \
--os-type=linux \
--disk '${full_image_path},size=${disk}' \
--network bridge=${internet_bridge},model=virtio \
--network bridge=${lan_bridge},model=virtio \
--console pty,target_type=virtio \
--virt-type kvm \
--graphics vnc ${initrd_inject} \
--extra-args 'auto netcfg/disable_dhcp=true'
| VIRT_INSTALL_EOF
}
}
default: { fail("${build} is not a supported build type.") }
}
}

Expand Down
28 changes: 28 additions & 0 deletions spec/functions/generate_mac_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

# Copyright (c) 2020 The Regents of the University of Michigan.
# All Rights Reserved. Licensed according to the terms of the Revised
# BSD License. See LICENSE.txt for details.
require "spec_helper"

describe "generate_mac" do
it "generates simple addresses" do
is_expected.to run.with_params("02:00:00", "example.com").and_return("02:00:00:a3:79:a6")
is_expected.to run.with_params("12-0f-00", "example.com", 2).and_return("12:0f:00:a3:79:a4")
end
it "fails on invalid chars" do
is_expected.to run.with_params("g2:00:00", "example.com", 0).and_raise_error(ArgumentError)
end
it "correctly masks final 3 bits" do
is_expected.to run.with_params("06 12 34", "my.host.name", 0).and_return("06:12:34:3b:d9:9a")
is_expected.to run.with_params("5a.67.89", "my.host.name", 3).and_return("5a:67:89:3b:d9:99")
is_expected.to run.with_params("AE:BC:DE", "my.host.name", 7).and_return("ae:bc:de:3b:d9:9d")
end
it "fails on non-private oui" do
is_expected.to run.with_params("03:00:00", "example.com", 0).and_raise_error(ArgumentError)
end
it "fails on out of range index" do
is_expected.to run.with_params("02:00:00", "example.com", 11).and_raise_error(ArgumentError)
is_expected.to run.with_params("02:00:00", "example.com", -1).and_raise_error(ArgumentError)
end
end
Loading