|
Packit Service |
509fd4 |
#!/usr/bin/python3
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
"""
|
|
Packit Service |
509fd4 |
gen-user-data
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
This tool generates a cloud-config user-data file from a directory containing
|
|
Packit Service |
509fd4 |
configuration. Its main purpose is to make it easy to include files in the
|
|
Packit Service |
509fd4 |
user-data, which need to be encoded in base64.
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
It writes the assembled user-data to standard out.
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
The configuration directory may contain:
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
* user-data.yml -- a base user-data. Anything that exists in this file will be
|
|
Packit Service |
509fd4 |
transferred as-is. Any additional configuration is appended
|
|
Packit Service |
509fd4 |
to already existing configuration.
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
* files/ -- a directory containing additional files to include. The
|
|
Packit Service |
509fd4 |
file's path on the target system mirrors its path relative
|
|
Packit Service |
509fd4 |
to this directore (`files/etc/hosts` → `/etc/hosts`). Its
|
|
Packit Service |
509fd4 |
permissions are copied over, but the owner will always be
|
|
Packit Service |
509fd4 |
root:root. Empty directories are ignored.
|
|
Packit Service |
509fd4 |
"""
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
import argparse
|
|
Packit Service |
509fd4 |
import base64
|
|
Packit Service |
509fd4 |
import json
|
|
Packit Service |
509fd4 |
import os
|
|
Packit Service |
509fd4 |
import stat
|
|
Packit Service |
509fd4 |
import sys
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
def octal_mode_string(mode):
|
|
Packit Service |
509fd4 |
"""Convert stat.st_mode to the format cloud-init expects.
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
cloud-init's write_files plugin expects file permissions in the format
|
|
Packit Service |
509fd4 |
returned by python2's oct() function, for example '0644'. In python3, oct()
|
|
Packit Service |
509fd4 |
returns a string in the new octal notation, '0o644'.
|
|
Packit Service |
509fd4 |
"""
|
|
Packit Service |
509fd4 |
return "0" + oct(stat.S_IMODE(mode))[2:]
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
def main():
|
|
Packit Service |
509fd4 |
p = argparse.ArgumentParser(description="Generate cloud-config user-data")
|
|
Packit Service |
509fd4 |
p.add_argument("configdir", metavar="CONFIGDIR", help="input directory")
|
|
Packit Service |
509fd4 |
args = p.parse_args()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
write_files = []
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
filesdir = f"{args.configdir}/files"
|
|
Packit Service |
509fd4 |
for directory, dirs, files in os.walk(filesdir, followlinks=True):
|
|
Packit Service |
509fd4 |
for name in files:
|
|
Packit Service |
509fd4 |
path = f"{directory}/{name}"
|
|
Packit Service |
509fd4 |
with open(path, "rb") as f:
|
|
Packit Service |
509fd4 |
content = base64.b64encode(f.read()).decode("utf-8")
|
|
Packit Service |
509fd4 |
write_files.append({
|
|
Packit Service |
509fd4 |
"path": "/" + os.path.relpath(path, filesdir),
|
|
Packit Service |
509fd4 |
"encoding": "b64",
|
|
Packit Service |
509fd4 |
"content": content,
|
|
Packit Service |
509fd4 |
"permissions": octal_mode_string(os.lstat(path).st_mode)
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
with open(f"{args.configdir}/user-data.yml") as f:
|
|
Packit Service |
509fd4 |
sys.stdout.write(f.read())
|
|
Packit Service |
509fd4 |
sys.stdout.write("write_files: ")
|
|
Packit Service |
509fd4 |
json.dump(write_files, sys.stdout)
|
|
Packit Service |
509fd4 |
sys.stdout.write("\n")
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
if __name__ == "__main__":
|
|
Packit Service |
509fd4 |
sys.exit(main())
|