Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ubuntu/devel #4735

Merged
merged 17 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cloudinit/cmd/devel/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from cloudinit.cmd.devel import read_cfg_paths
from cloudinit.handlers.jinja_template import (
JinjaLoadError,
JinjaSyntaxParsingException,
NotJinjaError,
render_jinja_payload_from_file,
)
Expand Down Expand Up @@ -99,6 +100,13 @@ def render_template(user_data_path, instance_data_path=None, debug=False):
"Cannot render from instance data due to exception: %s", repr(e)
)
return 1
except JinjaSyntaxParsingException as e:
LOG.error(
"Failed to render templated user-data file '%s'. %s",
user_data_path,
str(e),
)
return 1
if not rendered_payload:
LOG.error("Unable to render user-data file: %s", user_data_path)
return 1
Expand Down
20 changes: 14 additions & 6 deletions cloudinit/cmd/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
render_jinja_payload,
)
from cloudinit.sources import REDACT_SENSITIVE_VALUE
from cloudinit.templater import JinjaSyntaxParsingException

NAME = "query"
LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -277,12 +278,19 @@ def handle_args(name, args):
return 1
if args.format:
payload = "## template: jinja\n{fmt}".format(fmt=args.format)
rendered_payload = render_jinja_payload(
payload=payload,
payload_fn="query commandline",
instance_data=instance_data,
debug=True if args.debug else False,
)
try:
rendered_payload = render_jinja_payload(
payload=payload,
payload_fn="query commandline",
instance_data=instance_data,
debug=True if args.debug else False,
)
except JinjaSyntaxParsingException as e:
LOG.error(
"Failed to render templated data. %s",
str(e),
)
return 1
if rendered_payload:
print(rendered_payload)
return 0
Expand Down
14 changes: 13 additions & 1 deletion cloudinit/config/cc_apt_configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,6 @@ def get_apt_cfg() -> Dict[str, str]:
"Dir::Etc::sourceparts", DEFAULT_APT_CFG["Dir::Etc::sourceparts"]
)
except ImportError:

try:
apt_dump, _ = subp.subp(["apt-config", "dump"])
except subp.ProcessExecutionError:
Expand Down Expand Up @@ -680,7 +679,20 @@ def generate_sources_list(cfg, release, mirrors, cloud):
)
aptsrc_file = apt_sources_list
disabled = disable_suites(cfg.get("disable_suites"), rendered, release)
disable_apt_sources_list = False
if aptsrc_file == apt_sources_deb822 and os.path.exists(apt_sources_list):
disable_apt_sources_list = True
util.write_file(aptsrc_file, disabled, mode=0o644)
if disable_apt_sources_list:
LOG.warning(
"Disabling %s to favor deb822 source format", apt_sources_list
)
content = pathlib.Path(apt_sources_list).read_bytes()
content = b"# disabled by cloud-init\n" + content
util.rename(apt_sources_list, f"{apt_sources_list}.disabled")
util.write_file(
f"{apt_sources_list}.disabled", content, preserve_mode=True
)


def add_apt_key_raw(key, file_name, hardened=False):
Expand Down
4 changes: 4 additions & 0 deletions cloudinit/config/cc_final_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
stderr=True,
log=LOG,
)
except templater.JinjaSyntaxParsingException as e:
util.logexc(
LOG, "Failed to render templated final message: %s", str(e)
)
except Exception:
util.logexc(LOG, "Failed to render final message template")

Expand Down
8 changes: 8 additions & 0 deletions cloudinit/config/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -816,9 +816,12 @@ def _get_config_type_and_rendered_userdata(
:return: UserDataTypeAndDecodedContent
:raises: SchemaValidationError when non-jinja content found but
header declared ## template: jinja.
:raises JinjaSyntaxParsingException when jinja syntax error found.
:raises JinjaLoadError when jinja template fails to load.
"""
from cloudinit.handlers.jinja_template import (
JinjaLoadError,
JinjaSyntaxParsingException,
NotJinjaError,
render_jinja_payload_from_file,
)
Expand All @@ -840,6 +843,11 @@ def _get_config_type_and_rendered_userdata(
)
]
) from e
except JinjaSyntaxParsingException as e:
error(
"Failed to render templated user-data. " + str(e),
sys_exit=True,
)
except JinjaLoadError as e:
error(str(e), sys_exit=True)
schema_position = "format-l2.c1"
Expand Down
3 changes: 3 additions & 0 deletions cloudinit/distros/alpine.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ def _write_hostname(self, hostname, filename):
if create_hostname_file:
pass
else:
LOG.info(
"create_hostname_file is False; hostname file not created"
)
return
if not conf:
conf = HostnameConf("")
Expand Down
3 changes: 3 additions & 0 deletions cloudinit/distros/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ def _write_hostname(self, hostname, filename):
if create_hostname_file:
pass
else:
LOG.info(
"create_hostname_file is False; hostname file not created"
)
return
if not conf:
conf = HostnameConf("")
Expand Down
3 changes: 3 additions & 0 deletions cloudinit/distros/debian.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ def _write_hostname(self, hostname, filename):
if create_hostname_file:
pass
else:
LOG.info(
"create_hostname_file is False; hostname file not created"
)
return
if not conf:
conf = HostnameConf("")
Expand Down
3 changes: 3 additions & 0 deletions cloudinit/distros/gentoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ def _write_hostname(self, hostname, filename):
if create_hostname_file:
pass
else:
LOG.info(
"create_hostname_file is False; hostname file not created"
)
return
if not conf:
conf = HostnameConf("")
Expand Down
4 changes: 4 additions & 0 deletions cloudinit/distros/opensuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ def _write_hostname(self, hostname, filename):
if create_hostname_file:
pass
else:
LOG.info(
"create_hostname_file is False; hostname file not"
"created"
)
return
if not conf:
conf = HostnameConf("")
Expand Down
3 changes: 3 additions & 0 deletions cloudinit/distros/photon.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ def _write_hostname(self, hostname, filename):
str(hostname),
]
)
LOG.info(
"create_hostname_file is False; hostname set transiently"
)
if ret:
LOG.warning(
(
Expand Down
3 changes: 3 additions & 0 deletions cloudinit/distros/rhel.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ def _write_hostname(self, hostname, filename):
str(hostname),
]
)
LOG.info(
"create_hostname_file is False; hostname set transiently"
)
else:
host_cfg = {
"HOSTNAME": hostname,
Expand Down
17 changes: 14 additions & 3 deletions cloudinit/handlers/jinja_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from cloudinit.settings import PER_ALWAYS
from cloudinit.templater import (
MISSING_JINJA_PREFIX,
JinjaSyntaxParsingException,
detect_template,
render_string,
)
Expand Down Expand Up @@ -54,9 +55,19 @@ def handle_part(self, data, ctype, filename, payload, frequency, headers):
if ctype in handlers.CONTENT_SIGNALS:
return
jinja_json_file = self.paths.get_runpath("instance_data_sensitive")
rendered_payload = render_jinja_payload_from_file(
payload, filename, jinja_json_file
)
try:
rendered_payload = render_jinja_payload_from_file(
payload, filename, jinja_json_file
)
except JinjaSyntaxParsingException as e:
LOG.warning(
"Ignoring jinja template for %s. "
"Failed to render template. %s",
filename,
str(e),
)
return

if not rendered_payload:
return
subtype = handlers.type_from_starts_with(rendered_payload)
Expand Down
2 changes: 2 additions & 0 deletions cloudinit/net/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,8 @@ def subnet_is_ipv6(subnet) -> bool:
"""Common helper for checking network_state subnets for ipv6."""
# 'static6', 'dhcp6', 'ipv6_dhcpv6-stateful', 'ipv6_dhcpv6-stateless' or
# 'ipv6_slaac'
# This function is inappropriate for v2-based routes as routes defined
# under v2 subnets can contain ipv4 and ipv6 simultaneously
if subnet["type"].endswith("6") or subnet["type"] in IPV6_DYNAMIC_TYPES:
# This is a request either static6 type or DHCPv6.
return True
Expand Down
20 changes: 13 additions & 7 deletions cloudinit/net/dhcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
# This file is part of cloud-init. See LICENSE file for license information.

import abc
import contextlib
import glob
import logging
import os
import re
import signal
import time
from contextlib import suppress
from io import StringIO
from typing import Any, Dict, List
from typing import Any, Dict, List, Optional

import configobj

Expand Down Expand Up @@ -268,7 +268,7 @@ def dhcp_discovery(

# this function waits for these files to exist, clean previous runs
# to avoid false positive in wait_for_files
with contextlib.suppress(FileNotFoundError):
with suppress(FileNotFoundError):
os.remove(pid_file)
os.remove(lease_file)

Expand Down Expand Up @@ -514,9 +514,15 @@ def get_latest_lease(lease_d=None):
return latest_file

@staticmethod
def parse_dhcp_server_from_lease_file(lease_file):
with open(lease_file, "r") as fd:
for line in fd:
def parse_dhcp_server_from_lease_file(lease_file) -> Optional[str]:
"""Parse a lease file for the dhcp server address

@param lease_file: Name of a file to be parsed
@return: An address if found, or None
"""
latest_address = None
with suppress(FileNotFoundError), open(lease_file, "r") as file:
for line in file:
if "dhcp-server-identifier" in line:
words = line.strip(" ;\r\n").split(" ")
if len(words) > 2:
Expand Down Expand Up @@ -561,7 +567,7 @@ def dhcp_discovery(

tmp_dir = temp_utils.get_tmp_ancestor(needs_exe=True)
lease_file = os.path.join(tmp_dir, interface + ".lease.json")
with contextlib.suppress(FileNotFoundError):
with suppress(FileNotFoundError):
os.remove(lease_file)

# udhcpc needs the interface up to send initial discovery packets
Expand Down
Loading
Loading