Documentation reorg for v4.6.0

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
Jonathon Anderson
2025-02-18 16:26:05 -07:00
parent 98695cbbff
commit 9e41378e1c
65 changed files with 3493 additions and 4654 deletions

View File

@@ -2,154 +2,47 @@
Contributing
============
Warewulf is an open source project, meaning we have the challenge of
limited resources. We are grateful for any support that you can
offer. Helping other users, raising issues, helping write
documentation, or contributing code are all ways to help!
Warewulf is an open source project, and we are grateful for any support or
contributions. Helping other users, raising issues, writing documentation, and
contributing code are all ways to help!
Join the community
==================
This is a huge endeavor, and your help would be greatly appreciated!
Post to online communities about Warewulf, and request that your
distribution vendor, service provider, and system administrators
include Warewulf for you!
Whether you develop Warewulf or use it to deploy clusters, we hope ypu'll spread
the word! Share your experiences online. Ask your distribution to include
support for Warewulf. Consider giving a talk at a conference or meetup!
Warewulf on Slack
-----------------
Many members of the Warewulf community, including developers, communicate via Slack.
It's a great place to get help with an issue or talk about how you're using Warewulf.
Many members of the Warewulf community, including its developers, communicate
via Slack. It's a great place to get help with an issue or talk about your
deployment.
An invite link is available at `https://warewulf.org/help/ <https://warewulf.org/help/>`.
OpenHPC
-------
OpenHPC includes Warewulf v4 (and Warewulf 3 before it) as a supported cluster
management system and deployment strategy. Participating in the OpenHPC
community is also a great way to support Warewulf!
Raise an Issue
==============
For general bugs/issues, you can open an issue `at the GitHub repo
<https://github.com/warewulf/warewulf/issues/new>`_.
Contribute to the code
Contribute to the Code
======================
We use the traditional `GitHub Flow
<https://guides.github.com/introduction/flow>`_ to develop. This means
that you fork the main repo, create a new branch to make changes, and
submit a pull request (PR) to the master branch.
<https://guides.github.com/introduction/flow>`_ to develop. This means that you
fork the main repo, create a new branch to make changes, and `submit a pull
request (PR) <https://help.github.com/articles/creating-a-pull-request>`_ to the
main branch.
Check out our official `CONTRIBUTING.md
<https://github.com/warewulf/warewulf/blob/master/CONTRIBUTING.md>`_
document, which also includes a `code of conduct
<https://github.com/warewulf/warewulf/blob/master/CONTRIBUTING.md#code-of-conduct>`_.
Step 1. Fork the repo
---------------------
To contribute to Warewulf, you should obtain a GitHub account and fork
the `Warewulf <https://github.com/warewulf/warewulf>`_ repository. Once
forked, clone your fork of the repo to your computer. (Obviously, you
should replace ``your-username`` with your GitHub username.)
.. code-block:: bash
git clone https://github.com/your-username/warewulf.git
cd warewulf
Step 2. Checkout a new branch
-----------------------------
`Branches <https://guides.github.com/introduction/flow>`_ are a way
of isolating your features from the main branch. Given that we’ve just
cloned the repo, we will probably want to make a new branch from
master in which to work on our new feature. Lets call that branch
``new-feature``:
.. code-block:: bash
git checkout master
git checkout -b new-feature
.. note::
You can always check which branch you are in by running ``git
branch``.
Step 3. Make your changes
-------------------------
On your new branch, go nuts! Make changes, test them, and when you are
happy commit the changes to the branch:
.. code-block:: bash
git add file-changed1 file-changed2...
git commit -m "what changed?"
This commit message is important - it should describe exactly the
changes that you have made. Good commit messages read like so:
.. code-block:: bash
git commit -m "changed function getConfig in functions.go to output csv to fix #2"
git commit -m "updated docs about shell to close #10"
The tags ``close #10`` and ``fix #2`` are referencing issues that are
posted on the upstream repo where you will direct your pull
request. When your PR is merged into the master branch, these messages
will automatically close the issues, and further, they will link your
commits directly to the issues they intend to fix. This will help
future maintainers understand your contribution, or (hopefully not)
revert the code back to a previous version if necessary.
Step 4. Push your branch to your fork
-------------------------------------
When you are done with your commits, you should push your branch to
your fork (and you can also continuously push commits here as you
work):
.. code-block:: bash
git push origin new-feature
Note that you should always check the status of your branches to see
what has been pushed (or not):
.. code-block:: bash
git status
Step 5. Submit a Pull Request
-----------------------------
Once you have pushed your branch, then you can go to your fork (in the
web GUI on GitHub) and `submit a Pull Request
<https://help.github.com/articles/creating-a-pull-request>`_. Regardless
of the name of your branch, your PR should be submitted to the
``main`` branch. Submitting your PR will open a conversation thread
for the maintainers of Warewulf to discuss your contribution. At this
time, the continuous integration that is linked with the code base
will also be executed. If there is an issue, or if the maintainers
suggest changes, you can continue to push commits to your branch and
they will update the Pull Request.
Step 6. Keep your branch in sync
--------------------------------
Cloning the repo will create an exact copy of the Warewulf repository
at that moment. As you work, your branch may become out of date as
others merge changesinto the upstream master. In the event that you
need to update a branch, you will need to follow the next steps:
.. code-block:: bash
# add a new remote named "upstream"
git remote add upstream https://github.com/warewulf/warewulf.git
# or another branch to be updated
git checkout master
git pull upstream master
# to update your fork
git push origin master
git checkout new-feature
git merge master
<https://github.com/warewulf/warewulf/blob/main/CONTRIBUTING.md>`_ document.

View File

@@ -2,309 +2,37 @@
Debugging
=========
Whether developing a new feature or fixing a bug, using the automated
test suite together with a debugger is a potent combination. This
guide here can't substitute for full documentation on a given
debugger; but it might help you get started debugging Warewulf.
Whether developing a new feature or fixing a bug, using the automated test suite
together with a debugger is a potent combination. This guide here can't
substitute for full documentation on a given debugger; but it might help you get
started debugging Warewulf.
Validating the code with vet
============================
The Warewulf ``Makefile`` includes a ``vet`` target which runs ``go
vet`` on the full codebase.
The Warewulf ``Makefile`` includes a ``vet`` target which runs ``go vet`` on the
full codebase.
.. code-block:: console
.. code-block:: shell
$ make vet
make vet
Running the full test suite
Running the Full Test Suite
===========================
The Warewulf ``Makefile`` includes a ``test`` target which runs the
full test suite.
The Warewulf ``Makefile`` includes a ``test`` target which runs the full test
suite.
.. code-block:: console
.. code-block:: shell
$ make test
make test
Using delve
===========
If you have a failing test but you're having trouble tracking down
why, try using a debugger to step through the test. These instructions
use delve.
Installing delve
----------------
You can install delve as a regular user directly with Go.
Individual test cases are particularly useful when coupled with a debugger. For
example, you can install delve as a regular user directly with Go.
.. code-block:: console
$ go install github.com/go-delve/delve/cmd/dlv@latest
The ``dlv`` binary will be installed by default at
``$HOME/go/bin/dlv``. You can, of course, add ``$HOME/go/bin`` to your
path if you prefer.
.. code-block:: console
$ PATH=$HOME/go/bin:$PATH
Running delve against a specific test
-------------------------------------
You can use delve to specifically run the test suite and, even more
specifically, a single failing test. In this example delve is
instructed to run the tests for Warewulf's ``node`` package, and
specifically the ``Test_GetAllNodeInfoDefaults`` test.
.. code-block:: console
$ dlv test github.com/warewulf/warewulf/internal/pkg/node -- -test.v -test.run Test_GetAllNodeInfoDefaults
Type 'help' for list of commands.
(dlv) break node.Test_GetAllNodeInfoDefaults
Breakpoint 1 set at 0x26c0d0 for github.com/warewulf/warewulf/internal/pkg/node.Test_GetAllNodeInfoDefaults() ./internal/pkg/node/nodeyaml_test.go:51
Setting a breakpoint at ``node.Test_GetAllNodeInfoDefaults`` pauses
execution once the test starts, and allows us to ``continue`` through
all the setup prior to that point.
.. code-block:: console
(dlv) continue
=== RUN Test_GetAllNodeInfoDefaults
> github.com/warewulf/warewulf/internal/pkg/node.Test_GetAllNodeInfoDefaults() ./internal/pkg/node/nodeyaml_test.go:51 (hits goroutine(35):1 total:1) (PC: 0x26c0d0)
46: assert.Contains(t, nodeYaml.Nodes, "test_node")
47: assert.Equal(t, "A single node", nodeYaml.Nodes["test_node"].Comment)
48: }
49:
50:
=> 51: func Test_GetAllNodeInfoDefaults(t *testing.T) {
52: file, writeErr := writeTestConfigFile(`
53: nodes:
54: test_node: {}`)
55: if file != nil {
56: defer os.Remove(file.Name())
Helpful commands from here include
``next``
Execute the current line (marked by ``=>``) and proceed to the next
line.
``step``
Execute the current line (marked by ``=>``) and proceed to the next
line, potentially moving into a function call.
``list``
Display a contextual Go code listing, marking the next instruction.
``locals``
Display all local variables in the current scope.
``print``
Display (in detail) the value of a single variable from the current
scope.
Read about other commands available within delve using the ``help``
command.
Example debugging session
-------------------------
.. code-block:: console
$ ~/go/bin/dlv test github.com/warewulf/warewulf/internal/pkg/node -- -test.v -test.run Test_GetAllNodeInfoDefaults
Type 'help' for list of commands.
(dlv) break node.Test_GetAllNodeInfoDefaults
Breakpoint 1 set at 0x26c0d0 for github.com/warewulf/warewulf/internal/pkg/node.Test_GetAllNodeInfoDefaults() ./internal/pkg/node/nodeyaml_test.go:51
(dlv) break nodeinfo.go:417
Breakpoint 2 set at 0x267f18 for github.com/warewulf/warewulf/internal/pkg/node.NewNodeInfo() ./internal/pkg/node/nodeinfo.go:417
(dlv) continue
=== RUN Test_GetAllNodeInfoDefaults
> github.com/warewulf/warewulf/internal/pkg/node.Test_GetAllNodeInfoDefaults() ./internal/pkg/node/nodeyaml_test.go:51 (hits goroutine(19):1 total:1) (PC: 0x26c0d0)
46: assert.Contains(t, nodeYaml.Nodes, "test_node")
47: assert.Equal(t, "A single node", nodeYaml.Nodes["test_node"].Comment)
48: }
49:
50:
=> 51: func Test_GetAllNodeInfoDefaults(t *testing.T) {
52: file, writeErr := writeTestConfigFile(`
53: nodes:
54: test_node: {}`)
55: if file != nil {
56: defer os.Remove(file.Name())
(dlv) continue
WARN : Error reading UNDEF/warewulf/defaults.conf: open UNDEF/warewulf/defaults.conf: no such file or directory
> github.com/warewulf/warewulf/internal/pkg/node.NewNodeInfo() ./internal/pkg/node/nodeinfo.go:417 (hits goroutine(19):1 total:1) (PC: 0x267f18)
412: defaultNodeConf.NetDevs = nil
413: nodeInfo.SetDefFrom(defaultNodeConf)
414: }
415:
416: // Load normal attributes
=> 417: if nodeConf != nil {
418: // If no profiles are included, automatically include the
419: // default profile.
420: if len(nodeConf.Profiles) == 0 {
421: nodeInfo.Profiles.SetSlice([]string{"default"})
422: } else {
(dlv) next
> github.com/warewulf/warewulf/internal/pkg/node.NewNodeInfo() ./internal/pkg/node/nodeinfo.go:420 (PC: 0x267f24)
415:
416: // Load normal attributes
417: if nodeConf != nil {
418: // If no profiles are included, automatically include the
419: // default profile.
=> 420: if len(nodeConf.Profiles) == 0 {
421: nodeInfo.Profiles.SetSlice([]string{"default"})
422: } else {
423: nodeInfo.Profiles.SetSlice(nodeConf.Profiles)
424: }
425:
(dlv) next
> github.com/warewulf/warewulf/internal/pkg/node.NewNodeInfo() ./internal/pkg/node/nodeinfo.go:421 (PC: 0x267f3c)
416: // Load normal attributes
417: if nodeConf != nil {
418: // If no profiles are included, automatically include the
419: // default profile.
420: if len(nodeConf.Profiles) == 0 {
=> 421: nodeInfo.Profiles.SetSlice([]string{"default"})
422: } else {
423: nodeInfo.Profiles.SetSlice(nodeConf.Profiles)
424: }
425:
426: nodeInfo.SetFrom(nodeConf)
(dlv) next
> github.com/warewulf/warewulf/internal/pkg/node.NewNodeInfo() ./internal/pkg/node/nodeinfo.go:426 (PC: 0x267fec)
421: nodeInfo.Profiles.SetSlice([]string{"default"})
422: } else {
423: nodeInfo.Profiles.SetSlice(nodeConf.Profiles)
424: }
425:
=> 426: nodeInfo.SetFrom(nodeConf)
427: }
428:
429: // Load default attributes for each NetDev
430: if defaultNetDevConf != nil {
431: for _, netdev := range nodeInfo.NetDevs {
(dlv) next
> github.com/warewulf/warewulf/internal/pkg/node.NewNodeInfo() ./internal/pkg/node/nodeinfo.go:430 (PC: 0x268000)
425:
426: nodeInfo.SetFrom(nodeConf)
427: }
428:
429: // Load default attributes for each NetDev
=> 430: if defaultNetDevConf != nil {
431: for _, netdev := range nodeInfo.NetDevs {
432: netdev.SetDefFrom(defaultNetDevConf)
433: }
434: }
435:
(dlv) print nodeInfo
github.com/warewulf/warewulf/internal/pkg/node.NodeInfo {
Id: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 1, cap: 1, [
"test_node",
],
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 0, cap: 0, nil,},
Comment: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 0, cap: 0, nil,},
ClusterName: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 0, cap: 0, nil,},
ImageName: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 0, cap: 0, nil,},
Ipxe: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 1, cap: 1, ["default"],},
RuntimeOverlay: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 1, cap: 1, ["generic"],},
SystemOverlay: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 1, cap: 1, ["wwinit"],},
Root: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 1, cap: 1, [
"initramfs",
],},
Discoverable: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 0, cap: 0, nil,},
Init: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 1, cap: 1, [
"/sbin/init",
],},
AssetKey: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 0, cap: 0, nil,},
Kernel: *github.com/warewulf/warewulf/internal/pkg/node.KernelEntry {
Override: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x4000158370),
Args: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001583c8),},
Ipmi: *github.com/warewulf/warewulf/internal/pkg/node.IpmiEntry {
Ipaddr: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001b6600),
Netmask: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001b6658),
Port: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001b66b0),
Gateway: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001b6708),
UserName: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001b6760),
Password: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001b67b8),
Interface: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001b6810),
Write: (*"github.com/warewulf/warewulf/internal/pkg/node.Entry")(0x40001b6868),
Tags: map[string]*github.com/warewulf/warewulf/internal/pkg/node.Entry [],},
Profiles: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 1, cap: 1, ["default"],
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 1, cap: 1, ["default"],},
PrimaryNetDev: github.com/warewulf/warewulf/internal/pkg/node.Entry {
value: []string len: 0, cap: 0, nil,
altvalue: []string len: 0, cap: 0, nil,
from: "",
def: []string len: 0, cap: 0, nil,},
NetDevs: map[string]*github.com/warewulf/warewulf/internal/pkg/node.NetDevEntry [],
Tags: map[string]*github.com/warewulf/warewulf/internal/pkg/node.Entry [],}
Visual Studio Code also includes a full-featured golang debugger that includes
testsuite integration.

View File

@@ -1,8 +0,0 @@
=============================
Development Environment (Dev Container/VSC)
=============================
Using a Dev Container for development
=====================================================
Visual Studio Code (VSC) can utilize a Dev Container for a self-contained environment that has all the necessary tools and dependencies to build and test Warewulf. The Dev Container is based on the Rocky 9 image and is built using the `devcontainer.json` file in the `.devcontainer` directory of the Warewulf repository. To use this working Docker/Podman and VSC installations are required. To use the Dev Container, click the "Open a Remote Window" button on the bottom left of the editor (`><` icon) and select "Reopen in Container". This will build the container and open a new VSC window with the container as the development environment.

View File

@@ -1,125 +0,0 @@
=============================
Development Environment (KVM)
=============================
Create CentOS 7 development virtual machine under KVM
=====================================================
.. code-block:: bash
# KVM is running on server called master1 which is not my desktop
ssh -X master1
# On master1 server
wget -P /global/downloads/centos http://mirror.mobap.edu/centos/7.8.2003/isos/x86_64/CentOS-7-x86_64-Everything-2003.iso
qemu-img create -o preallocation=metadata -f qcow2 /global/images/centos-7.qcow2 32G
# install wwdev Centos 7 development VM
sudo virt-install --virt-type kvm --name centos7-wwdev --ram 8192 \
--disk /global/images/centos-7.qcow2,format=qcow2 \
--network network=default \
--graphics vnc,listen=0.0.0.0 --noautoconsole \
--os-type=linux --os-variant=rhel7.0 \
--location=/global/downloads/centos/CentOS-7-x86_64-Everything-2003.iso
# Complete installation using virt-manager
# To start virt-manager on non-local server
ssh -X master1
sudo -E virt-manager
# Login to VM and install @development group and go language
ssh root@wwdev
# Disable selinux by modifying /etc/sysconfig/selinux
vi /etc/sysconfig/selinux
SELINUX=disabled
# disable firewall
systemctl stop firewalld
systemctl disable firewalld
Turn off default network dhcp on server master1
===============================================
.. code-block:: bash
# shutdown all VMs
sudo virsh net-destroy default
sudo virsh net-edit default
# remove dhcp lines from XML
sudo virsh net-start default
Build and install Warewulf on wwdev
===================================
.. code-block::
ssh wwdev
# Fedora prerequisites
sudo dnf -y install tftp-server tftp
sudo dnf -y install dhcp
sudo dnf -y install ipmitool
sudo dnf install singularity
sudo dnf install gpgme-devel
sudo dnf install libassuan.x86_64 libassuan-devel.x86_64
sudo dnf golang
sudo dnf nfs-utils
# Centos prerequisites
sudo yum -y install tftp-server tftp
sudo yum -y install dhcp
sudo yum -y install ipmitool
sudo yum install http://repo.ctrliq.com/packages/rhel7/ctrl-release.rpm
sudo yum install singularityplus
sudo yum install gpgme-devel
sudo yum install libassuan.x86_64 libassuan-devel.x86_64
sudo yum install https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.7-1.x86_64.rpm
sudo yum install golang
sudo yum install nfs-utils
# Install Warewulf and dependencies
git clone https://github.com/warewulf/warewulf.git
cd warewulf
make all
sudo make install
# Configure the controller
Edit the file /etc/warewulf/warewulf.conf and ensure that you've ser the approprite configuration parameters
# Configure system service automatically
sudo wwctl configure dhcp # Create the default dhcpd.conf file and start/enable service
sudo wwctl configure tftp # Install the base tftp/PXE boot files and start/enable service
sudo wwctl configure nfs # Configure NFS exports
sudo wwctl configure ssh # Build the basic ssh keys to be included by the ssh overlays
# Pull and build the image
sudo wwctl image import docker://ghcr.io/warewulf/warewulf-centos:7 centos-7 --setdefault
# Set up the default node profile
sudo wwctl profile set default -K $(uname -r) -C centos-7
sudo wwctl profile set default --netdev eth0 -M WW_server_subnet_mask -G WW_server_ip
sudo wwctl profile list
# Add a node and build node specific overlays
sudo wwctl node add n0000.cluster --netdev eth0 -I n0000_ip --discoverable
sudo wwctl node list -a n0000
# Review Warewulf overlays
sudo wwctl overlay list -l
sudo wwctl overlay list -ls
sudo wwctl overlay edit default /etc/hello_world.ww
sudo wwctl overlay build -a
# Start the Warewulf daemon
sudo wwctl server &
Boot your node and watch the bash and the output of the Warewulfd process

View File

@@ -1,270 +0,0 @@
=================================
Development Environment (Vagrant)
=================================
Create Rocky Linux 9 virtual machine for Warewulf testbed using Vagrant
Host system requirements
========================
#. CPU supports H/W virtualization.
#. KVM kernel module available and loaded.
CPU H/W Virtualization support
------------------------------
Check CPU virtualization capability using following command.
If your system has Intel CPU, you will see :code:`Intel VT` here, and if your system has AMD CPU, you will see :code:`AMD-V` here.
.. code-block:: bash
lscpu | grep Virtualization
Virtualization: AMD-V
Virtualization type: full
KVM kernel module
-----------------
.. code-block:: bash
lsmod | grep kvm
ccp 118784 1 kvm_amd
kvm 1105920 1 kvm_amd
irqbypass 16384 1 kvm
Setup development environment on Rocky Linux 9
==============================================
Install QEMU, libvirt
---------------------
.. code-block:: bash
# Install packages
sudo dnf install -y libvirt qemu-kvm \
libguestfs virtio-win guestfs-tools libguestfs-inspect-icons virt-win-reg \
virt-install virt-top
# Enable and start libvirtd
sudo systemctl enable --now libvirtd
# Add user to libvirt group
sudo usermod -aG libvirt rocky
Install Cockpit (Optional)
--------------------------
.. code-block:: bash
# Install packages
sudo dnf install -y cockpit cockpit-machines
# Enable and start cockpit (http://localhost:9090)
sudo systemctl enable --now cockpit.socket
Install Vagrant, vagrant-libvirt plug-in and vagrant-reload plug-in
-------------------------------------------------------------------
.. code-block:: bash
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo dnf install -y vagrant
sudo dnf group install -y "Development tools"
sudo dnf config-manager --set-enabled crb
sudo dnf install -y libvirt-devel
vagrant plugin install vagrant-libvirt
vagrant plugin install vagrant-reload
Vagrant box and Vagrantfile for Warewulf sandbox
================================================
Create Rocky Linux 9.2 vagrant box
----------------------------------
.. code-block:: bash
cat << 'EOF' > box-metadata.json
{
"name" : "rockylinux/9",
"description" : "Rocky Linux 9 2.0.0",
"versions" : [
{
"version" : "2.0.0-20230513.0",
"providers" : [
{
"name" : "libvirt",
"url" : "https://dl.rockylinux.org/pub/rocky/9.2/images/x86_64/Rocky-9-Vagrant-Libvirt-9.2-20230513.0.x86_64.box"
}
]
}
]
}
EOF
vagrant box add box-metadata.json
Vagrantfile
-----------
.. code-block:: bash
mkdir -p ~/warewulf-sandbox
cd ~/warewulf-sandbox
cat << 'EOF' > Vagrantfile
Vagrant.configure("2") do |config|
number_of_node = ENV["NODES"] || 2
branch = ENV["BRANCH"] || "v4.6.0rc3"
config.vm.define :head do |head|
head.vm.box = "rockylinux/9"
head.vm.box_version = "2.0.0-20230513.0"
head.vm.hostname = "warewulf"
head.vm.network "private_network",
ip: "192.168.200.254",
netmask: "255.255.255.0",
libvirt__network_name: "pxe",
libvirt__dhcp_enabled: false
head.vm.synced_folder ".", "/vagrant", type: "nfs", nfs_version: 4, nfs_udp: false
head.vm.provider :libvirt do |libvirt|
libvirt.cpu_mode = "host-passthrough"
libvirt.memory = '8192'
libvirt.cpus = '2'
libvirt.machine_virtual_size = 40
end
head.vm.provision "shell", inline: <<-SHELL
dnf install -y cloud-utils-growpart
growpart /dev/vda 5
xfs_growfs /dev/vda5
SHELL
head.vm.provision "shell", inline: <<-SHELL
dnf groupinstall -y "Development Tools"
dnf install -y epel-release
dnf config-manager --set-enabled crb
dnf install -y golang tftp-server dhcp-server nfs-utils gpgme-devel libassuan-devel
cd /tmp
git clone https://github.com/warewulf/warewulf.git
cd warewulf
git checkout v4.6.0rc3
make clean defaults \
PREFIX=/usr \
BINDIR=/usr/bin \
SYSCONFDIR=/etc \
DATADIR=/usr/share \
LOCALSTATEDIR=/var/lib \
SHAREDSTATEDIR=/var/lib \
MANDIR=/usr/share/man \
INFODIR=/usr/share/info \
DOCDIR=/usr/share/doc \
SRVDIR=/var/lib \
TFTPDIR=/var/lib/tftpboot \
SYSTEMDDIR=/usr/lib/systemd/system \
BASHCOMPDIR=/etc/bash_completion.d/ \
FIREWALLDDIR=/usr/lib/firewalld/services \
WWCLIENTDIR=/warewulf
make all
make install
systemctl disable --now firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
SHELL
head.vm.provision "reload"
head.vm.provision "shell", inline: <<-SHELL
cat << 'CONF' | sudo tee /etc/warewulf/warewulf.conf
ipaddr: 192.168.200.254
netmask: 255.255.255.0
network: 192.168.200.0
warewulf:
port: 9873
secure: false
update interval: 60
autobuild overlays: true
host overlay: true
dhcp:
enabled: true
range start: 192.168.200.50
range end: 192.168.200.99
systemd name: dhcpd
tftp:
enabled: true
systemd name: tftp
nfs:
enabled: true
export paths:
- path: /home
export options: rw,sync
- path: /opt
export options: ro,sync,no_root_squash
systemd name: nfs-server
CONF
sed -i 's@ExecStart=/usr/bin/wwctl server@ExecStart=/usr/bin/wwctl server -d -v@' /usr/lib/systemd/system/warewulfd.service
systemctl enable --now warewulfd
wwctl configure --all
wwctl image import docker://ghcr.io/warewulf/warewulf-rockylinux:9 rocky-9
wwctl profile set --yes --image rocky-9 "default"
wwctl profile set --yes --netdev eth1 --netmask 255.255.255.0 --gateway 192.168.200.254 "default"
wwctl node add n0001.cluster -I 192.168.200.101 --discoverable true
wwctl node add n0002.cluster -I 192.168.200.102 --discoverable true
SHELL
end
(1..number_of_node).each do |i|
config.vm.define :"n000#{i}", autostart: false do |node|
node.vm.hostname = "n000#{i}"
node.vm.network "private_network",
libvirt__network_name: "pxe"
node.vm.provider :libvirt do |compute|
compute.cpu_mode = 'host-passthrough'
compute.memory = '8192'
compute.cpus = '2'
boot_network = {'network' => 'pxe'}
compute.boot boot_network
end
end
end
end
EOF
Spin up head node
=================
.. code-block:: bash
vagrant up
Spin up compute nodes
=====================
.. code-block:: bash
vagrant up n0001
# Wait until n0001 becomes ready
vagrant up n0002

View File

@@ -1,158 +0,0 @@
====================================
Development Environment (VirtualBox)
====================================
I have VirtualBox running on my desktop.
1. Create a NAT Network (a private vlan) to be used for the Warewlf
Server and compute nodes inside the VirtualBox. Make sure to
turnoff DHCP service within this NAT Network.
.. code-block:: console
# On the host with VirtualBox execute below. In my example using 10.0.8.0/24 as the private vlan for my experiment with Warewulf
VBoxManage natnetwork add --netname wwnatnetwork --network "10.0.8.0/24" --enable --dhcp off
2. Create a Centos 7 development Virtual machine (wwdev) to be used as
the Warewulf Server. Enable two Network adapters one with a
standard NAT and SSH port mapping such that you can access this VM
from the host machine. Assign the second network adapter to the NAT
Network created in step #1. Assign sufficient memory (e.g: 4GB) to
the VM.
.. code-block:: console
# Download a Centos7 or SL7 ISO and mount it to the optical drive to boot and install OS for the wwdev VM.
# Attach Network adapter #1 of the wwdev VM to the standard NAT via VM Settings -> Network option.
# By default VirtualBox puts the Network Adapter into 10.0.2.0/24 network and assigns 10.0.2.15 IP address.
# Also add a rule to the port forwarding table under the standard NAT configuration to allow SSH
# from localhost (127.0.0.1) some high port e.g 2222 to the guest IP 10.0.2.15 port 22 such that
# you can SSH from your host/desktop to the wwdev VM.
# Next attach the second Network adapter #2 to the NAT Network and you should be able to choose
# the 'wwnatnetwork' created above in step #1 from the drop down list.
3. Build and install Warewulf on wwdev
.. code-block::
# Login to wwdev VM and install @development group and go language
ssh localhost -p 2222 #(should prompt for a user account password on wwdev VM)
# Disable selinux by modifying /etc/sysconfig/selinux
vi /etc/sysconfig/selinux
SELINUX=disabled
# Disable firewall
systemctl stop firewalld
systemctl disable firewalld
# Centos prerequisites
sudo yum -y install tftp-server tftp
sudo yum -y install dhcp
sudo yum -y install ipmitool
sudo yum install http://repo.ctrliq.com/packages/rhel7/ctrl-release.rpm
sudo yum install singularityplus
sudo yum install gpgme-devel
sudo yum install libassuan.x86_64 libassuan-devel.x86_64
# Upgrade git to v2+
sudo yum install https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.7-1.x86_64.rpm
sudo yum install git
sudo yum install golang
sudo yum install nfs-utils
# Install Warewulf and dependencies
git clone https://github.com/warewulf/warewulf.git
cd warewulf
make all
sudo make install
# Static assign an IP to adapter #2 which is in the wwnatnetwork.
$ Edit the file /etc/sysconfig/networking-scripts/ifcfg-enp0s9 # adapter name at the end might be different for you
# Add lines like to below to assign an ip in 10.0.8.0/24 wwnatnetwork, I choose 10.0.8.4
BOOTPROTO=static
ONBOOT=yes
NAME=enp0s9
DEVICE=enp0s9
IPADDR=10.0.8.4
NETMASK=255.255.255.0
GATEWAY=10.0.8.1
# Bring the enp0s9 interface online and verify ip assignment
# Configure the Warewulf controller
$ Edit the file /etc/warewulf/warewulf.conf and ensure that you've set the approprite configuration parameters.
# My conf file looks like below:
ipaddr: 10.0.8.4
netmask: 255.255.255.0
warewulf:
port: 9873
secure: true
update interval: 60
dhcp:
enabled: true
range start: 10.0.8.150
range end: 10.0.8.200
template: default
systemd name: dhcpd
tftp:
enabled: true
tftproot: /var/lib/tftpboot
systemd name: tftp
nfs:
systemd name: nfs-server
exports:
- /home
- /var/warewulf
# Configure system service automatically
sudo wwctl configure dhcp --persist # Create the default dhcpd.conf file and start/enable service
sudo wwctl configure tftp --persist # Install the base tftp/PXE boot files and start/enable service
sudo wwctl configure nfs --persist # Configure the NFS exports
sudo wwctl configure ssh --persist # Build the basic ssh keys to be included by the SSH overlay
# Pull and build the image
sudo wwctl image import docker://ghcr.io/warewulf/warewulf-centos:7 centos-7 --setdefault
# Set up the default node profile
sudo wwctl profile set default -K $(uname -r) -C centos-7
sudo wwctl profile set default --netdev eth0 -M 255.255.255.0 -G 10.0.8.4
sudo wwctl profile list
# Add a node and build node specific overlays
# IP address of my nodes start from 150 as set in the warewulf.conf file above
sudo wwctl node add n0000.cluster --netdev eth0 -I 10.0.8.150 --discoverable
sudo wwctl node list -a n0000
# Review Warewulf overlays
sudo wwctl overlay list -l
sudo wwctl overlay list -ls
sudo wwctl overlay edit default /etc/hello_world.ww
sudo wwctl overlay build -a
# Start the Warewulf daemon
sudo wwctl server &
4. Create a new guest VM instance inside the VirtualBox to be the
Warewulf client/compute node. Under the system configuration make
sure to select the optical and network options only for the boot
order. The default iPXE used by VirtualBox does not come with
bzImage capability which is needed for Warewulf. Download the
ipxe.iso available at ipxe.org and mount the ipxe.iso to the
optical drive. Enable one Network adapter for this VM and assign it
to the NAT Network created in step #1 above.
.. code-block:: console
# Download ipxe.so available at http://boot.ipxe.org/ipxe.iso
# VM Settings -> System disable Floppy, Hard Disk from Boot order. Enable Optical and Network options.
# VM Settings -> Storage and mount the above download ipxe.so to the Optical Drive.
# VM Settings -> Network Enable adapter #1, attach to 'Nat Network' and choose 'wwnatnetwork' from the drop down list.
Boot your node and watch the console and the output of the Warewulfd
process.

View File

@@ -0,0 +1,97 @@
=======================
Development Environment
=======================
To develop and test the Warewulf server, you need a single system (typically a
virtual machine) to serve as a test server deployment. To actually test
provisioning your development server also needs a dedicated network that it can
run DHCP on. This can typically be provisioned as a virtual network bridge in
virtual machine software.
Options include:
* KVM / Libvirt
* VirtualBox
* VMWare
* UTM
A Warewulf development environment should likely use Rocky Linux 9 or openSUSE
LEAP 15, though there are ongoing development efforts using Debian and Ubuntu as
well.)
Compiling Warewulf for a Development Server
===========================================
.. code-block:: shell
# Rocky Linux 9
dnf -y install git epel-release golang {libassuan,gpgme}-devel unzip tftp-server dhcp-server nfs-utils ipxe-bootimgs-{x86,aarch64}
git clone https://github.com/warewulf/warewulf.git
cd warewulf
env \
PREFIX=/opt/warewulf \
SYSCONFDIR=/etc \
IPXESOURCE=/usr/share/ipxe \
WWPROVISIONDIR=/opt/warewulf/provision \
WWOVERLAYDIR=/opt/warewulf/overlays \
WWCHROOTDIR=/opt/warewulf/chroots \
make all
make install
These paths balance isolation (e.g., installing binaries in
``/opt/warewulf/bin/``) with integration (e.g., storing configuration in
``/etc/warewulf/`` and using local Dracut and iPXE paths).
After making changes to the source, simply running ``make install`` should be
enough to update installed binaries.
You should likely also disable any local firewall. Otherwise, consult the
general installation guide for configuration details.
.. code-block:: shell
systemctl disable --now firewalld
Running the Test Suite
======================
Warewulf includes an ever-growing test suite. Alias targets in the ``Makefile``
support running it quickly, easily, and consistently.
.. code-block:: shell
make test
Additional tests exist as well to perform various checks on the golang source.
These checks are run automatically by GitHub as part of the Warewulf CI process;
but it is a good idea to run them locally before submitting a new PR.
.. code-block:: shell
make vet
make staticcheck
make lint
New code, and code changes, should often be accompanied by updates to the test
suite.
More information:
* `The golang testing package <https://pkg.go.dev/testing>`_
* `Table Driven Tests <https://go.dev/wiki/TableDrivenTests>`_
* `Testift assert <https://pkg.go.dev/github.com/stretchr/testify/assert>`_
* `Warewulf testenv <https://pkg.go.dev/github.com/warewulf/warewulf/internal/pkg/testenv>`_
Using a Dev Container
=====================
Visual Studio Code (VSC) can utilize a Dev Container for a self-contained
environment that has all the necessary tools and dependencies to build and test
Warewulf. The Dev Container is based on the Rocky 9 image and is built using the
`devcontainer.json` file in the `.devcontainer` directory of the Warewulf
repository. To use this working Docker/Podman and VSC installations are
required. To use the Dev Container, click the "Open a Remote Window" button on
the bottom left of the editor (`><` icon) and select "Reopen in Container".
This will build the container and open a new VSC window with the container as
the development environment.

View File

@@ -2,16 +2,10 @@
Documentation
=============
We (like almost all open source software providers) have a
documentation dilemma… We tend to focus on the code features and
functionality before working on documentation. And there is very good
reason for this: we want to share the love so nobody feels left out!
You can contribute to the documentation by `raising an issue to
suggest an improvement
<https://github.com/warewulf/warewulf/issues/new>`_ or by sending a
`pull request <https://github.com/warewulf/warewulf/compare>`_ on
`our repository <https://github.com/warewulf/warewulf>`_.
You can contribute to the documentation by `raising an issue to suggest an
improvement <https://github.com/warewulf/warewulf/issues/new>`_ or by sending a
`pull request <https://github.com/warewulf/warewulf/compare>`_ on `our GitHub
repository <https://github.com/warewulf/warewulf>`_.
The current documentation is generated with `Sphinx
<https://www.sphinx-doc.org/>`_.
@@ -19,4 +13,4 @@ The current documentation is generated with `Sphinx
For more information on using Git and GitHub to create a pull request
suggesting additions and edits to the docs, see the `section on
contributing to the code <contributing>`_. The procedure is identical
for contributions to the documentation and the code base.
for contributions to documentation and code.