Compare commits

...

6 Commits

Author SHA1 Message Date
5c2ec9ce78 Standardize names and lock config 2022-10-25 19:25:38 +00:00
f2a6a4ac1f Add locking to git commands
Avoids conflicting attempts when multiple hosts check in at once.
2022-10-25 19:25:38 +00:00
Joshua Boniface
31c7c2522f Add additional detail for status diagram 2022-10-24 10:11:09 -04:00
Joshua Boniface
35a5052e2b Add additional details on detect strings 2022-10-24 10:09:43 -04:00
Joshua Boniface
390b0c6257 Update second reference too 2022-10-24 09:55:45 -04:00
Joshua Boniface
3b5b1f258d Mention webhook system in readme 2022-10-24 09:54:04 -04:00
7 changed files with 71 additions and 54 deletions

View File

@@ -60,7 +60,7 @@ The PVC Bootstrap system is designed to heavily leverage Redfish in its automati
1. Connect power to the servers, but do not manually power on the servers - Redfish will handle this aspect after characterizing each host, as well as manage boot, RAID array creation (as documented in `bootstrap.yml`), BIOS configuration, etc.
1. Wait for the cluster bootstrapping to complete; you can watch the output of the `pvcbootstrapd` and `pvcbootstrapd-worker` services on the Bootstrap host to see progress. If supported, the indicator LEDs of the nodes will be lit during setup and will be disabled upon completion to provide a physical indication of the process.
1. Wait for the cluster bootstrapping to complete; you can watch the output of the `pvcbootstrapd` and `pvcbootstrapd-worker` services on the Bootstrap host to see progress, or configure the system to send webhooks to a remote target (e.g. Slack/Mattermost messages). If supported, the indicator LEDs of the nodes will be lit during setup and will be disabled upon completion to provide a physical indication of the process.
1. Verify and power off the servers and put them into production; you may need to complete several post-install tasks (for instance setting the production BMC networking via `sudo ifup ipmi` on each node) before the cluster is completely finished.
@@ -84,7 +84,7 @@ The PVC Bootstrap system can still handle nodes without Redfish support, for ins
1. Power on the servers and set them to boot temporarily (one time) from PXE.
1. Wait for the cluster bootstrapping to complete; you can watch the output of the `pvcbootstrapd` and `pvcbootstrapd-worker` services on the Bootstrap host to see progress. If supported, the indicator LEDs of the nodes will be lit during setup and will be disabled upon completion to provide a physical indication of the process.
1. Wait for the cluster bootstrapping to complete; you can watch the output of the `pvcbootstrapd` and `pvcbootstrapd-worker` services on the Bootstrap host to see progress, or configure the system to send webhooks to a remote target (e.g. Slack/Mattermost messages). If supported, the indicator LEDs of the nodes will be lit during setup and will be disabled upon completion to provide a physical indication of the process.
1. Verify and power off the servers and put them into production; you may need to complete several post-install tasks (for instance setting the production BMC networking via `sudo ifup ipmi` on each node) before the cluster is completely finished.
@@ -150,13 +150,22 @@ filesystem="ext4"
# The hostname of the system (set per-run)
target_hostname="hv1.example.tld"
# The target system disk path
# The target system disk path; must be a single disk (mdadm/software RAID is not supported)
# This will usually use a `detect` string. A "detect" string is a string in the form "detect:<NAME>:<HUMAN-SIZE>:<ID>".
# Detect strings allow for automatic determination of Linux block device paths from known basic information
# about disks by leveraging "lsscsi" on the target host. The "NAME" should be some descriptive identifier,
# for instance the manufacturer (e.g. "INTEL"), the "HUMAN-SIZE" should be the labeled human-readable size
# of the device (e.g. "480GB", "1.92TB"), and "ID" specifies the Nth 0-indexed device which matches the
# NAME" and "HUMAN-SIZE" values (e.g. "2" would match the third device with the corresponding "NAME" and
# "HUMAN-SIZE"). When matching against sizes, there is +/- 3% flexibility to account for base-1000 vs.
# base-1024 differences and rounding errors. The "NAME" may contain whitespace but if so the entire detect
# string should be quoted, and is case-insensitive.
target_disk="detect:LOGICAL:146GB:0"
# SSH key method (usually tftp)
# SSH key fetch method (usually tftp)
target_keys_method="tftp"
# SSH key path (usually keys.txt)
# SSH key fetch path (usually keys.txt)
target_keys_path="keys.txt"
# Deploy username (usually deploy)
@@ -179,6 +188,6 @@ pvcbootstrapd_checkin_uri="http://10.255.255.1:9999/checkin/host"
## Bootstrap Process
This diagram outlines the various states the nodes and clusters will be in throughout the setup process along with the individual steps for reference.
This diagram outlines the various states the nodes and clusters will be in throughout the setup process along with the individual steps for reference. Which node starts characterizing first can be random, but is shown as `node1` for clarity. For non-Redflish installs, the first several steps must be completed manually as referenced above.
![PVC Bootstrap Process](/docs/images/pvcbootstrapd-process.png)

View File

@@ -66,7 +66,7 @@ pvc:
path: "/var/home/joshua/pvc"
# Path to the deploy key (if applicable) used to clone and pull the repository
keyfile: "/var/home/joshua/id_ed25519.joshua.key"
key_file: "/var/home/joshua/id_ed25519.joshua.key"
# Git remote URI for the repository
remote: "ssh://git@git.bonifacelabs.ca:2222/bonifacelabs/pvc.git"
@@ -77,6 +77,9 @@ pvc:
# Clusters configuration file
clusters_file: "clusters.yml"
# Lock file to use for Git interaction
lock_file: "/run/pvcbootstrapd.lock"
# Filenames of the various group_vars components of a cluster
# Generally with pvc-ansible this will contain 2 files: "base.yml", and "pvc.yml"; refer to the
# pvc-ansible documentation and examples for details on these files.

View File

@@ -179,7 +179,7 @@ def read_config():
)
# Get the Ansible configuration
for key in ["path", "keyfile", "remote", "branch", "clusters_file"]:
for key in ["path", "key_file", "remote", "branch", "clusters_file", "lock_file"]:
try:
config[f"ansible_{key}"] = o_ansible[key]
except Exception:

View File

@@ -66,7 +66,7 @@ def run_bootstrap(config, cspec, cluster, nodes):
limit=f"{cluster.name}",
playbook=f"{config['ansible_path']}/pvc.yml",
extravars={
"ansible_ssh_private_key_file": config["ansible_keyfile"],
"ansible_ssh_private_key_file": config["ansible_key_file"],
"bootstrap": "yes",
},
forks=len(nodes),

View File

@@ -22,6 +22,7 @@
import os.path
import git
import yaml
from filelock import FileLock
import pvcbootstrapd.lib.notifications as notifications
@@ -36,7 +37,7 @@ def init_repository(config):
Clone the Ansible git repository
"""
try:
git_ssh_cmd = f"ssh -i {config['ansible_keyfile']} -o StrictHostKeyChecking=no"
git_ssh_cmd = f"ssh -i {config['ansible_key_file']} -o StrictHostKeyChecking=no"
if not os.path.exists(config["ansible_path"]):
print(
f"First run: cloning repository {config['ansible_remote']} branch {config['ansible_branch']} to {config['ansible_path']}"
@@ -60,25 +61,29 @@ def pull_repository(config):
"""
Pull (with rebase) the Ansible git repository
"""
with FileLock(config['ansible_lock_file']):
logger.info(f"Updating local configuration repository {config['ansible_path']}")
try:
git_ssh_cmd = f"ssh -i {config['ansible_keyfile']} -o StrictHostKeyChecking=no"
git_ssh_cmd = f"ssh -i {config['ansible_key_file']} -o StrictHostKeyChecking=no"
g = git.cmd.Git(f"{config['ansible_path']}")
logger.debug("Performing git pull")
g.pull(rebase=True, env=dict(GIT_SSH_COMMAND=git_ssh_cmd))
logger.debug("Performing git submodule update")
g.submodule("update", "--init", env=dict(GIT_SSH_COMMAND=git_ssh_cmd))
except Exception as e:
logger.warn(e)
notifications.send_webhook(config, "failure", "Failed to update Git repository")
logger.info("Completed repository synchonization")
def commit_repository(config):
"""
Commit uncommitted changes to the Ansible git repository
"""
with FileLock(config['ansible_lock_file']):
logger.info(
f"Committing changes to local configuration repository {config['ansible_path']}"
)
try:
g = git.cmd.Git(f"{config['ansible_path']}")
g.add("--all")
@@ -102,12 +107,12 @@ def push_repository(config):
"""
Push changes to the default remote
"""
with FileLock(config['ansible_lock_file']):
logger.info(
f"Pushing changes from local configuration repository {config['ansible_path']}"
)
try:
git_ssh_cmd = f"ssh -i {config['ansible_keyfile']} -o StrictHostKeyChecking=no"
git_ssh_cmd = f"ssh -i {config['ansible_key_file']} -o StrictHostKeyChecking=no"
g = git.Repo(f"{config['ansible_path']}")
origin = g.remote(name="origin")
origin.push(env=dict(GIT_SSH_COMMAND=git_ssh_cmd))

View File

@@ -43,7 +43,7 @@ def run_paramiko(config, node_address):
ssh_client.connect(
hostname=node_address,
username=config["deploy_username"],
key_filename=config["ansible_keyfile"],
key_filename=config["ansible_key_file"],
)
yield ssh_client
ssh_client.close()

View File

@@ -43,7 +43,7 @@ def init_tftp(config):
os.makedirs(config["tftp_root_path"])
os.makedirs(config["tftp_host_path"])
shutil.copyfile(
f"{config['ansible_keyfile']}.pub", f"{config['tftp_root_path']}/keys.txt"
f"{config['ansible_key_file']}.pub", f"{config['tftp_root_path']}/keys.txt"
)
build_tftp_repository(config)