Merge pull request #14 from ctrliq/various_fixups
Very minor fixes and readme updates I want to get out there.
This commit is contained in:
199
README.md
199
README.md
@@ -1,190 +1,29 @@
|
|||||||
# warewulf v4 (work in progress)
|
# warewulf v4
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
In a nutshell, to install and start provisioning nodes, do the following:
|
#### Quick Links:
|
||||||
|
|
||||||
#### Build Warewulf and dependencies:
|
* [Documentation](docs/README.md)
|
||||||
|
* [GitHub](http://github.com/ctrliq/warewulf)
|
||||||
|
|
||||||
Warewulf is programmed in GoLang, so you will need to also install a Go compiler
|
## About Warewulf
|
||||||
on your system. The easiest way to do this on RHEL and CentOS is by using the Go
|
|
||||||
packages that are included in EPEL. In addition there are some dependencies that
|
|
||||||
Warewulf will require to operate properly and because this is a quick HOWTO, we
|
|
||||||
disable the firewall so any provisioning issues we have won't be caused by
|
|
||||||
packets being dropped.
|
|
||||||
|
|
||||||
To install these and compile Warewulf, do the following:
|
For over two decades, Warewulf has powered HPC systems around the world. From simple “under the desk” clusters to large
|
||||||
|
institutional systems at HPC centers as well as enterprises who rely on performance critical computing.
|
||||||
|
|
||||||
```
|
Through the evolution of Warewulf, we have seen various iterations provisioning models starting from CDROM / ISO images
|
||||||
sudo yum install epel-release
|
to Etherboot (predecessor to PXE), then PXE, and more recently iPXE, but even during these different bootloaders,
|
||||||
sudo yum install --tolerant golang tftp-server dhcp dhcp-server
|
Warewulf in it’s heart, has always been first and foremost a stateless provisioning system (e.g. the operating system
|
||||||
|
node image is not written to any persistent storage and rather it boots from the network directly into a runtime
|
||||||
|
system).
|
||||||
|
|
||||||
sudo systemctl stop firewalld
|
Warewulf v3 has been in production for over 6 years now as it has stabilized into a very solid and full featured
|
||||||
sudo systemctl disable firewalld
|
solution. But over the last few years, there have been many innovations in Enterprise technologies which can (and
|
||||||
|
should) be leveraged as part of Warewulf. Additionally, some of the lessons learned from Warewulf v3 architecture
|
||||||
|
should be rolled into an updated architecture for provisioning management.
|
||||||
|
|
||||||
make all
|
At the core, Warewulf focuses on what has made Warewulf so widely utilized: simplicity, ultra scalable, lightweight,
|
||||||
```
|
and easy to manage solution built for entry level system administrators to be able to design a highly functional and
|
||||||
|
easy to maintain cluster no matter how big or small it is.
|
||||||
#### Install Warewulf onto your host system:
|
|
||||||
|
|
||||||
The following command will install some of the Warewulf shared components into your
|
|
||||||
host system. The locations of these paths and files are not yet configurable, so
|
|
||||||
it can't be installed anywhere else.
|
|
||||||
|
|
||||||
The default install locations are:
|
|
||||||
|
|
||||||
* `/var/warewulf`: State data
|
|
||||||
* `/etc/warewulf`: Configuration data
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo make install
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Configure the controller:
|
|
||||||
|
|
||||||
Edit the file `/etc/warewulf/warewulf.conf` and ensure that you've set the
|
|
||||||
appropriate configuration paramaters. Here are some of the defaults for reference:
|
|
||||||
|
|
||||||
```
|
|
||||||
ipaddr: 192.168.1.1
|
|
||||||
netmask: 255.255.255.0
|
|
||||||
warewulf:
|
|
||||||
port: 9873
|
|
||||||
secure: true
|
|
||||||
update interval: 60
|
|
||||||
dhcp:
|
|
||||||
enabled: true
|
|
||||||
range start: 192.168.1.150
|
|
||||||
range end: 192.168.1.200
|
|
||||||
template: default
|
|
||||||
systemd name: dhcpd
|
|
||||||
tftp:
|
|
||||||
enabled: true
|
|
||||||
tftproot: /var/lib/tftpboot
|
|
||||||
systemd name: tftp
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: You may need to change the systemd service names for your distribution.
|
|
||||||
|
|
||||||
Once it has been configured, you can have Warewulf configure the services:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo ./wwctl configure -a
|
|
||||||
```
|
|
||||||
|
|
||||||
note, at the time of this writing, there are additional services which are not included
|
|
||||||
in the `-a` option. Please do a `wwctl configure --help` to see all configurable services.
|
|
||||||
|
|
||||||
#### Pull and build the VNFS container and kernel:
|
|
||||||
|
|
||||||
Once you have added the node, you can start building the needed bootable components.
|
|
||||||
There are three major groups of data to provision:
|
|
||||||
|
|
||||||
1. Kernel: This is the boot kernel and driver overlay pair. The `wwctl kernel build`
|
|
||||||
command will create these files. The `-a` option will scan your configuration looking
|
|
||||||
for all needed kernel images and then go through and build them all. The caveat is
|
|
||||||
that all these kernels must be installed to your host controller node.
|
|
||||||
|
|
||||||
1. Container/VNFS: The "VNFS" is the "Virtual Node File System", and that is the template that
|
|
||||||
nodes will be provisioned to boot into. Warewulf v4 can support standard "chroot"
|
|
||||||
style VNFS formats (e.g. same as Warewulf 3 and/or Singularity Sandboxes) as well as
|
|
||||||
OCI (Open Container Initiative) formats which include Docker containers and containers
|
|
||||||
in Docker Hub. As you can see in the above `wwctl profile set` command, we configured
|
|
||||||
the VNFS to be a container hosted in Docker Hub. This can also be a local path or a
|
|
||||||
container in a `docker-daemon`.
|
|
||||||
|
|
||||||
1. Overlays: There are two types of overlays, "system" and "runtime". The difference is
|
|
||||||
that the system overlay is provisioned before `/sbin/init` is called and the runtime
|
|
||||||
overlay is provisioned after `/sbin/init` is called and is done from the booted operating
|
|
||||||
system at periodic intervals (the time of this writing, it is ever 30 seconds).
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo ./wwctl container pull docker://warewulf/centos-7 centos-7 --setdefault
|
|
||||||
sudo ./wwctl kernel build $(uname -r) --setdefault
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Set up the default node profile
|
|
||||||
|
|
||||||
The `--setdefault` arguments above will automatically set those entries in the default
|
|
||||||
profile, but if you wanted to set them by hand to something different, you can do the
|
|
||||||
following:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo ./wwctl profile set default -K $(uname -r) -C centos-7
|
|
||||||
```
|
|
||||||
|
|
||||||
Next we set some default networking configurations for the first ethernet device. On
|
|
||||||
modern Linux distributions, the name of the device is not critical, as it will be setup
|
|
||||||
according to the HW address. Because all nodes will share the netmask and gateway, we
|
|
||||||
can configure them in the default profile as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo ./wwctl profile set default --netdev eth0 -M 255.255.255.0 -G 192.168.1.1
|
|
||||||
sudo ./wwctl profile list
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Add a node and build node specific overlays
|
|
||||||
|
|
||||||
Adding nodes can be done while setting configurations in one command. Here we are setting
|
|
||||||
the IP address of `eth0` and setting this node to be discoverable, which will then
|
|
||||||
automatically have the HW address added to the configuration as the node boots.
|
|
||||||
|
|
||||||
Node names must be unique. If you have node groups and/or multiple clusters, designate
|
|
||||||
them using dot notation.
|
|
||||||
|
|
||||||
Note that the full node configuration comes from both cascading profiles and node
|
|
||||||
configurations which always supersede profile configurations.
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo ./wwctl node add n0000.cluster --netdev eth0 -I 192.168.1.100 --discoverable
|
|
||||||
sudo ./wwctl node list -a n0000
|
|
||||||
```
|
|
||||||
|
|
||||||
### Warewulf Overlays
|
|
||||||
|
|
||||||
There are two types of overlays: system and runtime overlays.
|
|
||||||
|
|
||||||
System overlays are provisioned to the node before `/sbin/init` is called. This enables us
|
|
||||||
to prepopulate node configurations with content that is node specific like networking and
|
|
||||||
service configurations. When using the overlay subsystem, system overlays are never shown
|
|
||||||
by default. So when running `overlay` commands, you are always looking at runtime overlays
|
|
||||||
unless the `-s` option is passed.
|
|
||||||
|
|
||||||
Runtime overlays are provisioned after the node has booted and periodically during the
|
|
||||||
normal runtime of the node. Runtime overlays are also obtained using privileged source
|
|
||||||
ports such that non-root users can not obtain this from the Warewulf service (note: there
|
|
||||||
are other ways to secure the provisioned files like a provisioning VLan). Because these
|
|
||||||
overlays are provisioned at periodic intervals, they are very useful for content that
|
|
||||||
changes, like users and groups.
|
|
||||||
|
|
||||||
Overlays are generated from a template structure that is viewed using the `wwctl overlay`
|
|
||||||
commands. Files that end in the `.ww` suffix are templates and abide by standard
|
|
||||||
text/template rules. This supports loops, arrays, variables, and functions making overlays
|
|
||||||
extremely flexible.
|
|
||||||
|
|
||||||
All overlays are compiled before being provisioned. This accelerates the provisioning
|
|
||||||
process because there is less to do when nodes are being managed at scale.
|
|
||||||
|
|
||||||
Here are some of the common `overlay` commands:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo ./wwctl overlay list -l
|
|
||||||
sudo ./wwctl overlay list -ls
|
|
||||||
sudo EDITOR=vim ./wwctl overlay edit default /etc/hello_world.ww
|
|
||||||
sudo ./wwctl overlay build -a
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Start the Warewulf daemon:
|
|
||||||
|
|
||||||
Once the above provisioning images are built, you can check the provisioning "rediness"
|
|
||||||
and then begin booting nodes.
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo ./wwctl ready
|
|
||||||
sudo ./wwctl server start
|
|
||||||
sudo ./wwctl server status
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Boot your compute node and watch it boot
|
|
||||||
|
|
||||||
|
|||||||
7
docs/README.md
Normal file
7
docs/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Documentation for Warewulf
|
||||||
|
|
||||||
|
### Quickstarts
|
||||||
|
|
||||||
|
* [RHEL-7 quickstart](rhel7-quickstart.md)
|
||||||
|
* [RHEL-8 quickstart](rhel8-quickstart.md)
|
||||||
|
|
||||||
146
docs/rhel7-quickstart.md
Normal file
146
docs/rhel7-quickstart.md
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
## Quick Start for RHEL, CentOS, and Rocky Linux version 7
|
||||||
|
|
||||||
|
#### Install Warewulf and dependencies
|
||||||
|
```
|
||||||
|
sudo yum install epel-release
|
||||||
|
sudo yum install golang tftp-server dhcp nfs-utils
|
||||||
|
|
||||||
|
sudo systemctl stop firewalld
|
||||||
|
sudo systemctl disable firewalld
|
||||||
|
|
||||||
|
git clone https://github.com/ctrliq/warewulf.git
|
||||||
|
cd warewulf
|
||||||
|
make all
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Configure the controller:
|
||||||
|
|
||||||
|
Edit the file `/etc/warewulf/warewulf.conf` and ensure that you've set the
|
||||||
|
appropriate configuration paramaters. Here are some of the defaults for reference:
|
||||||
|
|
||||||
|
```
|
||||||
|
ipaddr: 192.168.1.1
|
||||||
|
netmask: 255.255.255.0
|
||||||
|
warewulf:
|
||||||
|
port: 9873
|
||||||
|
secure: true
|
||||||
|
update interval: 60
|
||||||
|
dhcp:
|
||||||
|
enabled: true
|
||||||
|
range start: 192.168.1.150
|
||||||
|
range end: 192.168.1.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 services 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 the exports and create an fstab in the default system overlay
|
||||||
|
sudo ./wwctl configure ssh # Build the basic ssh keys to be included by the default system overlay
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Pull and build the VNFS container and kernel:
|
||||||
|
This will pull a basic VNFS container from Docker Hub and import the default running
|
||||||
|
kernel from the controller node and set both in the "default" node profile.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl container pull docker://warewulf/centos-7 centos-7 --setdefault
|
||||||
|
sudo ./wwctl kernel build $(uname -r) --setdefault
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Set up the default node profile
|
||||||
|
|
||||||
|
The `--setdefault` arguments above will automatically set those entries in the default
|
||||||
|
profile, but if you wanted to set them by hand to something different, you can do the
|
||||||
|
following:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl profile set default -K $(uname -r) -C centos-7
|
||||||
|
```
|
||||||
|
|
||||||
|
Next we set some default networking configurations for the first ethernet device. On
|
||||||
|
modern Linux distributions, the name of the device is not critical, as it will be setup
|
||||||
|
according to the HW address. Because all nodes will share the netmask and gateway
|
||||||
|
configuration, we can set them in the default profile as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl profile set default --netdev eth0 -M 255.255.255.0 -G 192.168.1.1
|
||||||
|
sudo ./wwctl profile list
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Add a node and build node specific overlays
|
||||||
|
|
||||||
|
Adding nodes can be done while setting configurations in one command. Here we are setting
|
||||||
|
the IP address of `eth0` and setting this node to be discoverable, which will then
|
||||||
|
automatically have the HW address added to the configuration as the node boots.
|
||||||
|
|
||||||
|
Node names must be unique. If you have node groups and/or multiple clusters, designate
|
||||||
|
them using dot notation.
|
||||||
|
|
||||||
|
Note that the full node configuration comes from both cascading profiles and node
|
||||||
|
configurations which always supersede profile configurations.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl node add n0000.cluster --netdev eth0 -I 192.168.1.100 --discoverable
|
||||||
|
sudo ./wwctl node list -a n0000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Warewulf Overlays
|
||||||
|
|
||||||
|
There are two types of overlays: system and runtime overlays.
|
||||||
|
|
||||||
|
System overlays are provisioned to the node before `/sbin/init` is called. This enables us
|
||||||
|
to prepopulate node configurations with content that is node specific like networking and
|
||||||
|
service configurations.
|
||||||
|
|
||||||
|
Runtime overlays are provisioned after the node has booted and periodically during the
|
||||||
|
normal runtime of the node. Because these overlays are provisioned at periodic intervals,
|
||||||
|
they are very useful for content that changes, like users and groups.
|
||||||
|
|
||||||
|
Overlays are generated from a template structure that is viewed using the `wwctl overlay`
|
||||||
|
commands. Files that end in the `.ww` suffix are templates and abide by standard
|
||||||
|
text/template rules. This supports loops, arrays, variables, and functions making overlays
|
||||||
|
extremely flexible.
|
||||||
|
|
||||||
|
*note: When using the overlay subsystem, system overlays are never shown by default. So
|
||||||
|
when running `overlay` commands, you are always looking at runtime overlays unless the
|
||||||
|
`-s` option is passed.*
|
||||||
|
|
||||||
|
All overlays are compiled before being provisioned. This accelerates the provisioning
|
||||||
|
process because there is less to do when nodes are being managed at scale.
|
||||||
|
|
||||||
|
Here are some of the common `overlay` commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl overlay list -l
|
||||||
|
sudo ./wwctl overlay list -ls
|
||||||
|
sudo EDITOR=vim ./wwctl overlay edit default /etc/hello_world.ww
|
||||||
|
sudo ./wwctl overlay build -a
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Start the Warewulf daemon:
|
||||||
|
|
||||||
|
Once the above provisioning images are built, you can check the provisioning "rediness"
|
||||||
|
and then begin booting nodes.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl ready
|
||||||
|
sudo ./wwctl server start
|
||||||
|
sudo ./wwctl server status
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Boot your compute node and watch it boot
|
||||||
147
docs/rhel8-quickstart.md
Normal file
147
docs/rhel8-quickstart.md
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
## Quick Start for RHEL, CentOS, and Rocky Linux version 8
|
||||||
|
|
||||||
|
#### Install Warewulf and dependencies
|
||||||
|
```
|
||||||
|
sudo yum groupinstall "Development Tools"
|
||||||
|
sudo yum install epel-release
|
||||||
|
sudo yum install golang tftp-server dhcp-server nfs-utils
|
||||||
|
|
||||||
|
sudo systemctl stop firewalld
|
||||||
|
sudo systemctl disable firewalld
|
||||||
|
|
||||||
|
git clone https://github.com/ctrliq/warewulf.git
|
||||||
|
cd warewulf
|
||||||
|
make all
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Configure the controller:
|
||||||
|
|
||||||
|
Edit the file `/etc/warewulf/warewulf.conf` and ensure that you've set the
|
||||||
|
appropriate configuration paramaters. Here are some of the defaults for reference:
|
||||||
|
|
||||||
|
```
|
||||||
|
ipaddr: 192.168.1.1
|
||||||
|
netmask: 255.255.255.0
|
||||||
|
warewulf:
|
||||||
|
port: 9873
|
||||||
|
secure: true
|
||||||
|
update interval: 60
|
||||||
|
dhcp:
|
||||||
|
enabled: true
|
||||||
|
range start: 192.168.1.150
|
||||||
|
range end: 192.168.1.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 services 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 the exports and create an fstab in the default system overlay
|
||||||
|
sudo ./wwctl configure ssh # Build the basic ssh keys to be included by the default system overlay
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Pull and build the VNFS container and kernel:
|
||||||
|
This will pull a basic VNFS container from Docker Hub and import the default running
|
||||||
|
kernel from the controller node and set both in the "default" node profile.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl container pull docker://warewulf/centos-8 centos-8 --setdefault
|
||||||
|
sudo ./wwctl kernel build $(uname -r) --setdefault
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Set up the default node profile
|
||||||
|
|
||||||
|
The `--setdefault` arguments above will automatically set those entries in the default
|
||||||
|
profile, but if you wanted to set them by hand to something different, you can do the
|
||||||
|
following:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl profile set default -K $(uname -r) -C centos-7
|
||||||
|
```
|
||||||
|
|
||||||
|
Next we set some default networking configurations for the first ethernet device. On
|
||||||
|
modern Linux distributions, the name of the device is not critical, as it will be setup
|
||||||
|
according to the HW address. Because all nodes will share the netmask and gateway
|
||||||
|
configuration, we can set them in the default profile as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl profile set default --netdev eth0 -M 255.255.255.0 -G 192.168.1.1
|
||||||
|
sudo ./wwctl profile list
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Add a node and build node specific overlays
|
||||||
|
|
||||||
|
Adding nodes can be done while setting configurations in one command. Here we are setting
|
||||||
|
the IP address of `eth0` and setting this node to be discoverable, which will then
|
||||||
|
automatically have the HW address added to the configuration as the node boots.
|
||||||
|
|
||||||
|
Node names must be unique. If you have node groups and/or multiple clusters, designate
|
||||||
|
them using dot notation.
|
||||||
|
|
||||||
|
Note that the full node configuration comes from both cascading profiles and node
|
||||||
|
configurations which always supersede profile configurations.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl node add n0000.cluster --netdev eth0 -I 192.168.1.100 --discoverable
|
||||||
|
sudo ./wwctl node list -a n0000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Warewulf Overlays
|
||||||
|
|
||||||
|
There are two types of overlays: system and runtime overlays.
|
||||||
|
|
||||||
|
System overlays are provisioned to the node before `/sbin/init` is called. This enables us
|
||||||
|
to prepopulate node configurations with content that is node specific like networking and
|
||||||
|
service configurations.
|
||||||
|
|
||||||
|
Runtime overlays are provisioned after the node has booted and periodically during the
|
||||||
|
normal runtime of the node. Because these overlays are provisioned at periodic intervals,
|
||||||
|
they are very useful for content that changes, like users and groups.
|
||||||
|
|
||||||
|
Overlays are generated from a template structure that is viewed using the `wwctl overlay`
|
||||||
|
commands. Files that end in the `.ww` suffix are templates and abide by standard
|
||||||
|
text/template rules. This supports loops, arrays, variables, and functions making overlays
|
||||||
|
extremely flexible.
|
||||||
|
|
||||||
|
*note: When using the overlay subsystem, system overlays are never shown by default. So
|
||||||
|
when running `overlay` commands, you are always looking at runtime overlays unless the
|
||||||
|
`-s` option is passed.*
|
||||||
|
|
||||||
|
All overlays are compiled before being provisioned. This accelerates the provisioning
|
||||||
|
process because there is less to do when nodes are being managed at scale.
|
||||||
|
|
||||||
|
Here are some of the common `overlay` commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl overlay list -l
|
||||||
|
sudo ./wwctl overlay list -ls
|
||||||
|
sudo EDITOR=vim ./wwctl overlay edit default /etc/hello_world.ww
|
||||||
|
sudo ./wwctl overlay build -a
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Start the Warewulf daemon:
|
||||||
|
|
||||||
|
Once the above provisioning images are built, you can check the provisioning "rediness"
|
||||||
|
and then begin booting nodes.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ./wwctl ready
|
||||||
|
sudo ./wwctl server start
|
||||||
|
sudo ./wwctl server status
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Boot your compute node and watch it boot
|
||||||
@@ -6,42 +6,67 @@ import (
|
|||||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
err := os.MkdirAll("/etc/warewulf/keys", 0755)
|
if os.Getuid() == 0 {
|
||||||
|
fmt.Printf("Updating system keys\n")
|
||||||
|
|
||||||
|
err := os.MkdirAll("/etc/warewulf/keys", 0755)
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Could not create base directory: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if util.IsFile("/etc/warewulf/keys/ssh_host_rsa_key") == false {
|
||||||
|
fmt.Printf("Setting up key: ssh_host_rsa_key\n")
|
||||||
|
util.ExecInteractive("ssh-keygen", "-q", "-t", "rsa", "-f", "/etc/warewulf/keys/ssh_host_rsa_key", "-C", "", "-N", "")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Skipping, key already exists: ssh_host_rsa_key\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if util.IsFile("/etc/warewulf/keys/ssh_host_dsa_key") == false {
|
||||||
|
fmt.Printf("Setting up key: ssh_host_dsa_key\n")
|
||||||
|
util.ExecInteractive("ssh-keygen", "-q", "-t", "dsa", "-f", "/etc/warewulf/keys/ssh_host_dsa_key", "-C", "", "-N", "")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Skipping, key already exists: ssh_host_dsa_key\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if util.IsFile("/etc/warewulf/keys/ssh_host_ecdsa_key") == false {
|
||||||
|
fmt.Printf("Setting up key: ssh_host_ecdsa_key\n")
|
||||||
|
util.ExecInteractive("ssh-keygen", "-q", "-t", "ecdsa", "-f", "/etc/warewulf/keys/ssh_host_ecdsa_key", "-C", "", "-N", "")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Skipping, key already exists: ssh_host_ecdsa_key\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if util.IsFile("/etc/warewulf/keys/ssh_host_ed25519_key") == false {
|
||||||
|
fmt.Printf("Setting up key: ssh_host_ed25519_key\n")
|
||||||
|
util.ExecInteractive("ssh-keygen", "-q", "-t", "ed25519", "-f", "/etc/warewulf/keys/ssh_host_ed25519_key", "-C", "", "-N", "")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Skipping, key already exists: ssh_host_ed25519_key\n")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Updating user's keys\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
homeDir, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
wwlog.Printf(wwlog.ERROR, "Could not create base directory: %s\n", err)
|
wwlog.Printf(wwlog.ERROR, "Could not obtain the user's home directory: %s\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if util.IsFile("/etc/warewulf/keys/ssh_host_rsa_key") == false {
|
authorizedKeys := path.Join(homeDir, "/.ssh/authorized_keys")
|
||||||
fmt.Printf("Setting up key: ssh_host_rsa_key\n")
|
rsaPriv := path.Join(homeDir, "/.ssh/id_rsa")
|
||||||
util.ExecInteractive("ssh-keygen", "-q", "-t", "rsa", "-f", "/etc/warewulf/keys/ssh_host_rsa_key", "-C", "", "-N", "")
|
rsaPub := path.Join(homeDir, "/.ssh/id_rsa.pub")
|
||||||
} else {
|
|
||||||
fmt.Printf("Skipping, key already exists: ssh_host_rsa_key\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if util.IsFile("/etc/warewulf/keys/ssh_host_dsa_key") == false {
|
if util.IsFile(authorizedKeys) == false {
|
||||||
fmt.Printf("Setting up key: ssh_host_dsa_key\n")
|
fmt.Printf("Setting up: %s\n", authorizedKeys)
|
||||||
util.ExecInteractive("ssh-keygen", "-q", "-t", "dsa", "-f", "/etc/warewulf/keys/ssh_host_dsa_key", "-C", "", "-N", "")
|
util.ExecInteractive("ssh-keygen", "-q", "-t", "rsa", "-f", rsaPriv, "-C", "", "-N", "")
|
||||||
|
util.CopyFile(rsaPub, authorizedKeys)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Skipping, key already exists: ssh_host_dsa_key\n")
|
fmt.Printf("Skipping, authorized_keys already exists: %s\n", authorizedKeys)
|
||||||
}
|
|
||||||
|
|
||||||
if util.IsFile("/etc/warewulf/keys/ssh_host_ecdsa_key") == false {
|
|
||||||
fmt.Printf("Setting up key: ssh_host_ecdsa_key\n")
|
|
||||||
util.ExecInteractive("ssh-keygen", "-q", "-t", "ecdsa", "-f", "/etc/warewulf/keys/ssh_host_ecdsa_key", "-C", "", "-N", "")
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Skipping, key already exists: ssh_host_ecdsa_key\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if util.IsFile("/etc/warewulf/keys/ssh_host_ed25519_key") == false {
|
|
||||||
fmt.Printf("Setting up key: ssh_host_ed25519_key\n")
|
|
||||||
util.ExecInteractive("ssh-keygen", "-q", "-t", "ed25519", "-f", "/etc/warewulf/keys/ssh_host_ed25519_key", "-C", "", "-N", "")
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Skipping, key already exists: ssh_host_ed25519_key\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -114,6 +114,17 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if SetKernelArgs != "" {
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel args to: %s\n", n.Id.Get(), SetKernelArgs)
|
||||||
|
|
||||||
|
n.KernelArgs.Set(SetKernelArgs)
|
||||||
|
err := nodeDB.NodeUpdate(n)
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if SetClusterName != "" {
|
if SetClusterName != "" {
|
||||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting cluster name to: %s\n", n.Id.Get(), SetClusterName)
|
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting cluster name to: %s\n", n.Id.Get(), SetClusterName)
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ var (
|
|||||||
SetComment string
|
SetComment string
|
||||||
SetContainer string
|
SetContainer string
|
||||||
SetKernel string
|
SetKernel string
|
||||||
|
SetKernelArgs string
|
||||||
SetNetDev string
|
SetNetDev string
|
||||||
SetIpaddr string
|
SetIpaddr string
|
||||||
SetNetmask string
|
SetNetmask string
|
||||||
@@ -42,6 +43,7 @@ func init() {
|
|||||||
baseCmd.PersistentFlags().StringVar(&SetComment, "comment", "", "Set a comment for this node")
|
baseCmd.PersistentFlags().StringVar(&SetComment, "comment", "", "Set a comment for this node")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetContainer, "container", "C", "", "Set the container (VNFS) for this node")
|
baseCmd.PersistentFlags().StringVarP(&SetContainer, "container", "C", "", "Set the container (VNFS) for this node")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes")
|
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes")
|
||||||
|
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernelargs", "A", "", "Set Kernel argument for nodes")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
|
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
|
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container")
|
baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container")
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if SetKernel != "" {
|
if SetKernel != "" {
|
||||||
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel version to: %s\n", p.Id, SetKernel)
|
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel to: %s\n", p.Id, SetKernel)
|
||||||
|
|
||||||
p.KernelVersion.Set(SetKernel)
|
p.KernelVersion.Set(SetKernel)
|
||||||
err := nodeDB.ProfileUpdate(p)
|
err := nodeDB.ProfileUpdate(p)
|
||||||
@@ -129,6 +129,17 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if SetKernelArgs != "" {
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel args to: %s\n", p.Id, SetKernelArgs)
|
||||||
|
|
||||||
|
p.KernelArgs.Set(SetKernelArgs)
|
||||||
|
err := nodeDB.ProfileUpdate(p)
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if SetIpxe != "" {
|
if SetIpxe != "" {
|
||||||
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting iPXE template to: %s\n", p.Id, SetIpxe)
|
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting iPXE template to: %s\n", p.Id, SetIpxe)
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ var (
|
|||||||
SetComment string
|
SetComment string
|
||||||
SetContainer string
|
SetContainer string
|
||||||
SetKernel string
|
SetKernel string
|
||||||
|
SetKernelArgs string
|
||||||
SetClusterName string
|
SetClusterName string
|
||||||
SetIpxe string
|
SetIpxe string
|
||||||
SetRuntimeOverlay string
|
SetRuntimeOverlay string
|
||||||
@@ -36,6 +37,7 @@ func init() {
|
|||||||
baseCmd.PersistentFlags().StringVar(&SetComment, "comment", "", "Set a comment for this node")
|
baseCmd.PersistentFlags().StringVar(&SetComment, "comment", "", "Set a comment for this node")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetContainer, "container", "C", "", "Set the container (VNFS) for this node")
|
baseCmd.PersistentFlags().StringVarP(&SetContainer, "container", "C", "", "Set the container (VNFS) for this node")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes")
|
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes")
|
||||||
|
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernelargs", "A", "", "Set Kernel argument for nodes")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
|
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
|
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container")
|
baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container")
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
|||||||
n.RuntimeOverlay.SetDefault("default")
|
n.RuntimeOverlay.SetDefault("default")
|
||||||
n.Ipxe.SetDefault("default")
|
n.Ipxe.SetDefault("default")
|
||||||
n.Init.SetDefault("/sbin/init")
|
n.Init.SetDefault("/sbin/init")
|
||||||
n.Root.SetDefault("tmpfs")
|
n.Root.SetDefault("initramfs")
|
||||||
n.KernelArgs.SetDefault("rootfstype=ramfs crashkernel=no vga=791 quiet")
|
n.KernelArgs.SetDefault("quiet crashkernel=no vga=791 rootfstype=tmpfs")
|
||||||
|
|
||||||
fullname := strings.SplitN(nodename, ".", 2)
|
fullname := strings.SplitN(nodename, ".", 2)
|
||||||
if len(fullname) > 1 {
|
if len(fullname) > 1 {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ echo "Checking Rootfs type"
|
|||||||
ROOTFSTYPE=`stat -f -c "%T" /`
|
ROOTFSTYPE=`stat -f -c "%T" /`
|
||||||
|
|
||||||
if test "$WWROOT" == "initramfs"; then
|
if test "$WWROOT" == "initramfs"; then
|
||||||
echo "Provisioned to Rootfs type: $ROOTFSTYPE"
|
echo "Provisioned to default initramfs file system: $ROOTFSTYPE"
|
||||||
echo "Calling WW Init"
|
echo "Calling WW Init"
|
||||||
exec /warewulf/wwinit
|
exec /warewulf/wwinit
|
||||||
elif test "$WWROOT" == "tmpfs"; then
|
elif test "$WWROOT" == "tmpfs"; then
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ for i in /warewulf/init.d/*; do
|
|||||||
sh "$i"
|
sh "$i"
|
||||||
done
|
done
|
||||||
|
|
||||||
/bin/bash
|
|
||||||
|
|
||||||
|
|
||||||
echo "Calling $WWINIT..."
|
echo "Calling $WWINIT..."
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user