Patrik Lundin
94a65a31e0
Problem seen: ``` Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Unknown variable: '::osfamily'. (file: /etc/puppet/cosmos-modules/augeas/manifests/params.pp, line: 7, column: 8) on node example-1.sunet.se ``` This way we run modules installed from upstream apt packages instead. Solution to delete keys to use local pacakges from pahol. While here fix pylint issue with not importing platform module at beginning of file.
161 lines
4.6 KiB
Python
Executable file
161 lines
4.6 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
""" Write out a puppet cosmos-modules.conf """
|
|
|
|
import hashlib
|
|
import os
|
|
import os.path
|
|
import platform
|
|
import sys
|
|
|
|
from debian import debian_support
|
|
|
|
try:
|
|
from configobj import ConfigObj
|
|
|
|
OS_INFO = ConfigObj("/etc/os-release")
|
|
except (IOError, ModuleNotFoundError):
|
|
OS_INFO = None
|
|
|
|
|
|
def get_file_hash(modulesfile):
|
|
"""
|
|
Based on https://github.com/python/cpython/pull/31930: should use
|
|
hashlib.file_digest() but it is only available in python 3.11
|
|
"""
|
|
try:
|
|
with open(modulesfile, "rb") as fileobj:
|
|
digestobj = hashlib.sha256()
|
|
_bufsize = 2**18
|
|
buf = bytearray(_bufsize) # Reusable buffer to reduce allocations.
|
|
view = memoryview(buf)
|
|
while True:
|
|
size = fileobj.readinto(buf)
|
|
if size == 0:
|
|
break # EOF
|
|
digestobj.update(view[:size])
|
|
except FileNotFoundError:
|
|
return ""
|
|
|
|
return digestobj.hexdigest()
|
|
|
|
|
|
def get_list_hash(file_lines):
|
|
"""Get hash of list contents"""
|
|
|
|
file_lines_hash = hashlib.sha256()
|
|
for line in file_lines:
|
|
file_lines_hash.update(line)
|
|
|
|
return file_lines_hash.hexdigest()
|
|
|
|
|
|
def create_file_content(modules):
|
|
"""
|
|
Write out the expected file contents to a list so we can check the
|
|
expected checksum before writing anything
|
|
"""
|
|
file_lines = []
|
|
file_lines.append(
|
|
"# Generated by {}\n".format( # pylint: disable=consider-using-f-string
|
|
os.path.basename(sys.argv[0])
|
|
).encode("utf-8")
|
|
)
|
|
for key in modules:
|
|
file_lines.append(
|
|
"{0:11} {1} {2} {3}\n".format( # pylint: disable=consider-using-f-string
|
|
key,
|
|
modules[key]["repo"],
|
|
modules[key]["upgrade"],
|
|
modules[key]["tag"],
|
|
).encode("utf-8")
|
|
)
|
|
|
|
return file_lines
|
|
|
|
|
|
def main():
|
|
"""Starting point of the program"""
|
|
|
|
modulesfile: str = "/etc/puppet/cosmos-modules.conf"
|
|
modulesfile_tmp: str = modulesfile + ".tmp"
|
|
|
|
modules: dict = {
|
|
"sunet": {
|
|
"repo": "https://github.com/SUNET/puppet-sunet.git",
|
|
"upgrade": "yes",
|
|
"tag": "stable-2023v1-2*",
|
|
},
|
|
"augeas": {
|
|
"repo": "https://github.com/SUNET/puppet-augeas.git",
|
|
"upgrade": "yes",
|
|
"tag": "sunet-2*",
|
|
},
|
|
"concat": {
|
|
"repo": "https://github.com/SUNET/puppetlabs-concat.git",
|
|
"upgrade": "yes",
|
|
"tag": "sunet-2*",
|
|
},
|
|
"stdlib": {
|
|
"repo": "https://github.com/SUNET/puppetlabs-stdlib.git",
|
|
"upgrade": "yes",
|
|
"tag": "sunet-2*",
|
|
},
|
|
"apt": {
|
|
"repo": "https://github.com/SUNET/puppetlabs-apt.git",
|
|
"upgrade": "yes",
|
|
"tag": "sunet-2*",
|
|
},
|
|
"docker": {
|
|
"repo": "https://github.com/SUNET/garethr-docker.git",
|
|
"upgrade": "yes",
|
|
"tag": "sunet-2*",
|
|
},
|
|
}
|
|
|
|
if OS_INFO:
|
|
# Provided by Debian/Ubuntu via
|
|
# https://github.com/SUNET/multiverse/blob/main/global/pre-tasks.d/030puppet
|
|
|
|
if (OS_INFO["ID"] == "debian" and int(OS_INFO["VERSION_ID"]) >= 12) or (
|
|
OS_INFO["ID"] == "ubuntu"
|
|
and debian_support.version_compare(OS_INFO["VERSION_ID"], "24.04") >= 0
|
|
):
|
|
del modules["augeas"]
|
|
del modules["apt"]
|
|
del modules["concat"]
|
|
del modules["stdlib"]
|
|
|
|
# Make test machines use special test branch of puppet-sunet:
|
|
if OS_INFO["ID"] == "ubuntu":
|
|
nodename = platform.node()
|
|
name_parts = nodename.split("-")
|
|
if len(name_parts) > 1:
|
|
if name_parts[1] == "test":
|
|
modules["sunet"]["tag"] = "testing-2*"
|
|
|
|
# Build list of expected file content
|
|
file_lines = create_file_content(modules)
|
|
|
|
# Get hash of the list
|
|
list_hash = get_list_hash(file_lines)
|
|
|
|
# Get hash of the existing file on disk
|
|
file_hash = get_file_hash(modulesfile)
|
|
|
|
# Update the file if necessary
|
|
if list_hash != file_hash:
|
|
# Since we are reading the file with 'rb' when computing our hash use 'wb' when
|
|
# writing so we dont end up creating a file that does not match the
|
|
# expected hash
|
|
with open(modulesfile_tmp, "wb") as fileobj:
|
|
for line in file_lines:
|
|
fileobj.write(line)
|
|
|
|
# Rename it in place so the update is atomic for anything else trying to
|
|
# read the file
|
|
os.rename(modulesfile_tmp, modulesfile)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|