PHP 7.4.33
Preview: atomic_helper.py Size: 2.79 KB
/lib/python3/dist-packages/cloudinit/atomic_helper.py
# This file is part of cloud-init. See LICENSE file for license information.

import json
import logging
import os
import stat
import tempfile
from base64 import b64decode, b64encode

from cloudinit import performance, util

_DEF_PERMS = 0o644
LOG = logging.getLogger(__name__)


@performance.timed("Base64 decoding")
def b64d(source):
    """base64 decode data

    :param source: a bytes or str to decode
    :return: base64 as a decoded str if utf-8 encoded, otherwise bytes
    """
    decoded = b64decode(source)
    try:
        return decoded.decode("utf-8")
    except UnicodeDecodeError:
        return decoded


@performance.timed("Base64 encoding")
def b64e(source):
    """base64 encode data

    :param source: a bytes or str to decode
    :return: base64 encoded str
    """
    if not isinstance(source, bytes):
        source = source.encode("utf-8")
    return b64encode(source).decode("utf-8")


def write_file(
    filename, content, mode=_DEF_PERMS, omode="wb", preserve_mode=False
):
    """open filename in mode omode, write content, set permissions to mode"""

    with performance.Timed(f"Writing {filename}"):
        return _write_file(filename, content, mode, omode, preserve_mode)


def _write_file(
    filename, content, mode=_DEF_PERMS, omode="wb", preserve_mode=False
):
    if preserve_mode:
        try:
            file_stat = os.stat(filename)
            mode = stat.S_IMODE(file_stat.st_mode)
        except OSError:
            pass

    tf = None
    try:
        dirname = os.path.dirname(filename)
        util.ensure_dir(dirname)
        tf = tempfile.NamedTemporaryFile(dir=dirname, delete=False, mode=omode)
        LOG.debug(
            "Atomically writing to file %s (via temporary file %s) - %s: [%o]"
            " %d bytes/chars",
            filename,
            tf.name,
            omode,
            mode,
            len(content),
        )
        tf.write(content)
        tf.close()
        os.chmod(tf.name, mode)
        os.rename(tf.name, filename)
    except Exception as e:
        if tf is not None:
            os.unlink(tf.name)
        raise e


def json_serialize_default(_obj):
    """Handler for types which aren't json serializable."""
    try:
        return "ci-b64:{0}".format(b64e(_obj))
    except AttributeError:
        return "Warning: redacted unserializable type {0}".format(type(_obj))


@performance.timed("Dumping json")
def json_dumps(data):
    """Return data in nicely formatted json."""
    return json.dumps(
        data,
        indent=1,
        sort_keys=True,
        separators=(",", ": "),
        default=json_serialize_default,
    )


def write_json(filename, data, mode=_DEF_PERMS):
    # dump json representation of data to file filename.
    return write_file(
        filename,
        json_dumps(data) + "\n",
        omode="w",
        mode=mode,
    )

Directory Contents

Dirs: 12 × Files: 31
Name Size Perms Modified Actions
analyze DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
cmd DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
config DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
distros DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
filters DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
handlers DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
log DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
mergers DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
net DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
reporting DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
sources DIR
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
- drwxr-xr-x 2025-08-01 06:35:22
Edit Download
8.30 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
2.79 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
3.22 KB lrw-r--r-- 2025-06-24 21:15:25
Edit Download
7.81 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
2.00 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
5.28 KB lrw-r--r-- 2025-06-24 21:15:25
Edit Download
7.99 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
16.16 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
2.43 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
7.79 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
24.07 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
3.10 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
2.52 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
1022 B lrw-r--r-- 2025-06-24 20:50:00
Edit Download
10.11 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
2.12 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
3.92 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
1.93 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
5.93 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
22.21 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
41.53 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
12.43 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
7.74 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
2.94 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
703 B lrw-r--r-- 2025-06-24 20:50:00
Edit Download
38.15 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
14.44 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
90.38 KB lrw-r--r-- 2025-06-24 21:15:25
Edit Download
568 B lrw-r--r-- 2025-06-24 21:15:25
Edit Download
3.76 KB lrw-r--r-- 2025-06-24 20:50:00
Edit Download
0 B lrw-r--r-- 2025-06-24 20:50:00
Edit Download
If ZipArchive is unavailable, a .tar will be created (no compression).