This makes sense. I think we can minimally fix the messaging seen on the commandline when running `sudo cloud-init schema --system` to actually have it consume the rendered #cloud-config or #template: jinja user-data instead of the raw `#include <your-url>` as the potential source for invalid user-data.
Minimally I think we need to fix https://github.com/canoncloud-config ical/cloud-init/blob/main/cloudinit/config/schema.py#L621-L623 to validated the processed/rendered userdata instead of "userdata_raw" so that `sudo cloud-init schema --system` provides a concise error about what the procesed invalid user-data is.
I can validate that we get a less than desirable message from `sudo cloud-init schema --system` when we launch a container with a valid #include containing valid #cloud-config.
reproducer:
# terminal 1 on host system 192.168.1.8
$ mkdir -p instance-data
$ cd instance-data
$ cat > user-data <<EOF
#cloud-config
ssh_import_id: [chad.smith]
EOF
$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
# verify cloud-init schema --system alias for rendered user-data (not correct)
root@include-k:~# cloud-init schema --system --annotate
#include http://192.168.1.8:8000/user-data # E1
# Errors: -------------
# E1: File None needs to begin with "#cloud-config"
What I think we want:
root@include-k:~# cloud-init schema --system --annotate
Valid cloud-config: system userdata
This comes with something like the following diff, but needs tweaking and unittest coverage
diff --git a/cloudinit/config/schema.py b/cloudinit/config/schema.py
index d62073d0..aa4ec3a1 100644
--- a/cloudinit/config/schema.py
+++ b/cloudinit/config/schema.py
@@ -18,8 +17,8 @@ from typing import TYPE_CHECKING, List, NamedTuple, Optional, Type, Union, cast
import yaml
This makes sense. I think we can minimally fix the messaging seen on the commandline when running `sudo cloud-init schema --system` to actually have it consume the rendered #cloud-config or #template: jinja user-data instead of the raw `#include <your-url>` as the potential source for invalid user-data.
Minimally I think we need to fix https:/ /github. com/canoncloud- config ical/cloud- init/blob/ main/cloudinit/ config/ schema. py#L621- L623 to validated the processed/rendered userdata instead of "userdata_raw" so that `sudo cloud-init schema --system` provides a concise error about what the procesed invalid user-data is.
I can validate that we get a less than desirable message from `sudo cloud-init schema --system` when we launch a container with a valid #include containing valid #cloud-config.
reproducer:
# terminal 1 on host system 192.168.1.8
$ mkdir -p instance-data
$ cd instance-data
$ cat > user-data <<EOF
#cloud-config
ssh_import_id: [chad.smith]
EOF
$ python3 -m http.server 0.0.0.0: 8000/) ...
Serving HTTP on 0.0.0.0 port 8000 (http://
# terminal 2 on host system 192.168.1.8 192.168. 1.8:8000/ user-data daily:kinetic include-k -c user.user- data="$ (cat include.yaml)"
$ cat > include.yaml <<EOF
#include http://
EOF
$ lxc launch ubuntu-
$ lxc exec include-k bash
root@include-k:~#
# See raw userdata (this is ok/desired) 192.168. 1.8:8000/ user-data
root@include-k:~# cloud-init query userdata
#include http://
# verify cloud-init schema --system alias for rendered user-data (not correct) 192.168. 1.8:8000/ user-data # E1
root@include-k:~# cloud-init schema --system --annotate
#include http://
# Errors: -------------
# E1: File None needs to begin with "#cloud-config"
What I think we want:
root@include-k:~# cloud-init schema --system --annotate
Valid cloud-config: system userdata
This comes with something like the following diff, but needs tweaking and unittest coverage config/ schema. py b/cloudinit/ config/ schema. py config/ schema. py config/ schema. py
diff --git a/cloudinit/
index d62073d0..aa4ec3a1 100644
--- a/cloudinit/
+++ b/cloudinit/
@@ -18,8 +17,8 @@ from typing import TYPE_CHECKING, List, NamedTuple, Optional, Type, Union, cast
import yaml
from cloudinit import importer, safeyaml from_dir, load_file from_dir, load_file
-from cloudinit.cmd.devel import read_cfg_paths
-from cloudinit.util import error, get_modules_
+from cloudinit.stages import Init
+from cloudinit.util import encode_text, error, get_modules_
try: cloudconfig_ file(config_ path, schema, annotate=False):
"Unable to read system userdata as non-root user." ipath_cur( "userdata_ raw") user_data_ file, decode=False) content_ type() == "text/cloud- config" : text(part. get_payload( )) exists( config_ path):
from jsonschema import ValidationError as _ValidationError
@@ -617,9 +616,17 @@ def validate_
" Try using sudo"
)
- paths = read_cfg_paths()
- user_data_file = paths.get_
- content = load_file(
+ init = Init(ds_deps=[])
+ ds = init.fetch("trust")
+ ud = ds.get_userdata()
+ content = None
+ for part in ud.walk():
+ if part.get_
+ content = encode_
+ break
+ if not content:
+ print("No cloud-config userdata found. Skipping verification")
+ return
else:
if not os.path.
raise RuntimeError(