This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new f2bdce47df Unvendor cgroupspy (#22736)
f2bdce47df is described below
commit f2bdce47df9b69dbc9714bf455435013e178051d
Author: Jarek Potiuk <[email protected]>
AuthorDate: Tue Apr 5 00:04:43 2022 +0200
Unvendor cgroupspy (#22736)
The 0.2.2 release of `cgroupspy` makes it Python 3.10 compatible.
We can remove vendoring done as of #22209 #22208 #2207 #22206
Discussion and links:
* https://github.com/cloudsigma/cgroupspy/pull/14
---
airflow/_vendor/cgroupspy/__init__.py | 27 --
airflow/_vendor/cgroupspy/contenttypes.py | 155 ----------
airflow/_vendor/cgroupspy/controllers.py | 324 --------------------
airflow/_vendor/cgroupspy/interfaces.py | 339 ---------------------
airflow/_vendor/cgroupspy/nodes.py | 283 -----------------
airflow/_vendor/cgroupspy/trees.py | 246 ---------------
airflow/_vendor/cgroupspy/utils.py | 69 -----
airflow/_vendor/vendor.md | 1 -
airflow/task/task_runner/cgroup_task_runner.py | 2 +-
licenses/LICENSE-cgroupspy.txt | 27 --
scripts/ci/pre_commit/pre_commit_setup_cfg_file.sh | 2 +-
setup.cfg | 1 -
setup.py | 10 +-
13 files changed, 5 insertions(+), 1481 deletions(-)
diff --git a/airflow/_vendor/cgroupspy/__init__.py
b/airflow/_vendor/cgroupspy/__init__.py
deleted file mode 100644
index 1c55e2e68f..0000000000
--- a/airflow/_vendor/cgroupspy/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-"""
-Copyright (c) 2014, CloudSigma AG
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the CloudSigma AG nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL CloudSigma AG BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-__version__ = "0.2.1"
diff --git a/airflow/_vendor/cgroupspy/contenttypes.py
b/airflow/_vendor/cgroupspy/contenttypes.py
deleted file mode 100644
index f18b556745..0000000000
--- a/airflow/_vendor/cgroupspy/contenttypes.py
+++ /dev/null
@@ -1,155 +0,0 @@
-"""
-Copyright (c) 2014, CloudSigma AG
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the CloudSigma AG nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL CLOUDSIGMA AG BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-
-
-class BaseContentType(object):
-
- def __str__(self):
- raise NotImplementedError("Please implement this method in subclass")
-
- def __repr__(self):
- return "<{self.__class__.__name__}: {self}>".format(self=self)
-
- @classmethod
- def from_string(cls, value):
- raise NotImplementedError("This method should return an instance of
the content type")
-
-
-class DeviceAccess(BaseContentType):
- TYPE_ALL = "all"
- TYPE_CHAR = "c"
- TYPE_BLOCK = "b"
-
- ACCESS_UNSPEC = 0
- ACCESS_READ = 1
- ACCESS_WRITE = 2
- ACCESS_MKNOD = 4
-
- def __init__(self, dev_type=None, major=None, minor=None, access=None):
- self.dev_type = dev_type or self.TYPE_ALL
-
- # the default behaviour of device access cgroups if unspecified is as
follows
- if major is not None:
- self.major = int(major)
- else:
- self.major = "*"
-
- if minor is not None:
- self.minor = int(minor)
- else:
- self.minor = "*"
-
- if isinstance(access, str):
- value = 0
- if 'r' in access:
- value |= self.ACCESS_READ
- if 'w' in access:
- value |= self.ACCESS_WRITE
- if 'm' in access:
- value |= self.ACCESS_MKNOD
- self.access = value
- else:
- self.access = access or (self.ACCESS_READ | self.ACCESS_WRITE |
self.ACCESS_MKNOD)
-
- def _check_access_bit(self, offset):
- mask = 1 << offset
- return self.access & mask
-
- @property
- def can_read(self):
- return self._check_access_bit(0) == self.ACCESS_READ
-
- @property
- def can_write(self):
- return self._check_access_bit(1) == self.ACCESS_WRITE
-
- @property
- def can_mknod(self):
- return self._check_access_bit(2) == self.ACCESS_MKNOD
-
- @property
- def access_string(self):
- accstr = ""
- if self.can_read:
- accstr += "r"
- if self.can_write:
- accstr += "w"
- if self.can_mknod:
- accstr += "m"
- return accstr
-
- def __str__(self):
- return "{self.dev_type} {self.major}:{self.minor}
{self.access_string}".format(self=self)
-
- def __eq__(self, other):
- return self.dev_type == other.dev_type and self.major == other.major \
- and self.minor == other.minor and self.access_string ==
other.access_string
-
- @classmethod
- def from_string(cls, value):
- dev_type, major_minor, access_string = value.split()
- major, minor = major_minor.split(":")
- major = int(major) if major != "*" else None
- minor = int(minor) if minor != "*" else None
-
- access_mode = 0
- for idx, char in enumerate("rwm"):
- if char in access_string:
- access_mode |= (1 << idx)
- return cls(dev_type, major, minor, access_mode)
-
-
-class DeviceThrottle(BaseContentType):
-
- def __init__(self, limit, major=None, minor=None, ):
- self.limit = limit
-
- if major is not None and major != '*':
- self.major = int(major)
- else:
- self.major = '*'
-
- if minor is not None and minor != '*':
- self.minor = int(minor)
- else:
- self.minor = '*'
-
- def __eq__(self, other):
- return self.limit == other.limit and self.major == other.major and
self.minor == other.minor
-
- def __str__(self):
- return "{self.major}:{self.minor} {self.limit}".format(self=self)
-
- @classmethod
- def from_string(cls, value):
- try:
- major_minor, limit = value.split()
- major, minor = major_minor.split(":")
- return cls(int(limit), major, minor)
- except Exception:
- raise RuntimeError("Value {} cannot be converted to a string that
matches the pattern: "
- "[device major]:[device minor] [throttle limit
in bytes]".format(value))
diff --git a/airflow/_vendor/cgroupspy/controllers.py
b/airflow/_vendor/cgroupspy/controllers.py
deleted file mode 100644
index 483c53c6f8..0000000000
--- a/airflow/_vendor/cgroupspy/controllers.py
+++ /dev/null
@@ -1,324 +0,0 @@
-"""
-Copyright (c) 2014, CloudSigma AG
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the CloudSigma AG nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL CloudSigma AG BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-import os
-import errno
-from airflow._vendor.cgroupspy.contenttypes import DeviceAccess, DeviceThrottle
-
-from .interfaces import BaseFileInterface, FlagFile, BitFieldFile,
IntegerFile, SplitValueFile, DictOrFlagFile
-from .interfaces import MultiLineIntegerFile, CommaDashSetFile, DictFile,
IntegerListFile, TypedFile
-
-
-class Controller(object):
-
- """
- Base controller. Provides access to general files, existing in all cgroups
and means to get/set properties
- """
-
- tasks = MultiLineIntegerFile("tasks")
- procs = MultiLineIntegerFile("cgroup.procs")
- notify_on_release = FlagFile("notify_on_release")
- clone_children = FlagFile("cgroup.clone_children")
-
- def __init__(self, node):
- self.node = node
-
- def filepath(self, filename):
- """The full path to a file"""
-
- return os.path.join(self.node.full_path, filename)
-
- def list_interfaces(self):
- result = {}
-
- for data in [self.__class__.__dict__, Controller.__dict__]:
- for k, interface in data.items():
- if not issubclass(interface.__class__, BaseFileInterface):
- continue
-
- result[k] = interface
-
- return result
-
- def get_interface(self, key):
- if key in self.__class__.__dict__:
- interface = self.__class__.__dict__[key]
- elif key in Controller.__dict__:
- interface = Controller.__dict__[key]
- else:
- return None
-
- if not issubclass(interface.__class__, BaseFileInterface):
- return None
-
- return interface
-
- def get_property(self, filename):
- """Opens the file and reads the value"""
-
- with open(self.filepath(filename)) as f:
- return f.read().strip()
-
- def get_content(self, key):
- interface = self.get_interface(key)
-
- if interface is None or interface.writeonly:
- return None
-
- try:
- content = self.get_property(interface.filename)
- except IOError as e:
- if e.errno == errno.ENOENT:
- # does not exist
- return None
- elif e.errno == errno.EACCES:
- # cannot be read
- return None
- elif e.errno == errno.EINVAL:
- # invalid argument
- return None
- raise
-
- if not content.strip():
- return ''
-
- return interface.sanitize_get(content)
-
- def set_property(self, filename, value):
- """Opens the file and writes the value"""
-
- with open(self.filepath(filename), "w") as f:
- return f.write(str(value))
-
-
-class CpuController(Controller):
-
- """
- Cpu cGroup controller. Provides access to
-
- cpu.cfs_period_us
- cpu.cfs_quota_us
- cpu.rt_period_us
- cpu.rt_runtime_us
- cpu.shares
- cpu.stat
- """
- cfs_period_us = IntegerFile("cpu.cfs_period_us")
- cfs_quota_us = IntegerFile("cpu.cfs_quota_us")
- rt_period_us = IntegerFile("cpu.rt_period_us")
- rt_runtime_us = IntegerFile("cpu.rt_runtime_us")
- shares = IntegerFile("cpu.shares")
- stat = DictFile("cpu.stat", readonly=True)
-
-
-class CpuAcctController(Controller):
-
- """
- cpuacct.stat
- cpuacct.usage
- cpuacct.usage_percpu
- """
- acct_stat = DictFile("cpuacct.stat", readonly=True)
- usage = IntegerFile("cpuacct.usage")
- usage_percpu = IntegerListFile("cpuacct.usage_percpu", readonly=True)
-
-
-class CpuSetController(Controller):
-
- """
- CpuSet cGroup controller. Provides access to
-
- cpuset.cpu_exclusive
- cpuset.cpus
- cpuset.mem_exclusive
- cpuset.mem_hardwall
- cpuset.memory_migrate
- cpuset.memory_pressure
- cpuset.memory_pressure_enabled
- cpuset.memory_spread_page
- cpuset.memory_spread_slab
- cpuset.mems
- cpuset.sched_load_balance
- cpuset.sched_relax_domain_level
- """
-
- cpus = CommaDashSetFile("cpuset.cpus")
- mems = CommaDashSetFile("cpuset.mems")
-
- cpu_exclusive = FlagFile("cpuset.cpu_exclusive")
- mem_exclusive = FlagFile("cpuset.mem_exclusive")
- mem_hardwall = FlagFile("cpuset.mem_hardwall")
- memory_migrate = FlagFile("cpuset.memory_migrate")
- memory_pressure = FlagFile("cpuset.memory_pressure")
- memory_pressure_enabled = FlagFile("cpuset.memory_pressure_enabled")
- memory_spread_page = FlagFile("cpuset.memory_spread_page")
- memory_spread_slab = FlagFile("cpuset.memory_spread_slab")
- sched_load_balance = FlagFile("cpuset.sched_load_balance")
-
- sched_relax_domain_level = IntegerFile("cpuset.sched_relax_domain_level")
-
-
-class MemoryController(Controller):
-
- """
- Memory cGroup controller. Provides access to
-
- memory.failcnt
- memory.force_empty
- memory.limit_in_bytes
- memory.max_usage_in_bytes
- memory.memsw.failcnt
- memory.memsw.limit_in_bytes
- memory.memsw.max_usage_in_bytes
- memory.memsw.usage_in_bytes
- memory.move_charge_at_immigrate
- memory.numa_stat
- memory.oom_control
- memory.pressure_level
- memory.soft_limit_in_bytes
- memory.stat
- memory.swappiness
- memory.usage_in_bytes
- memory.use_hierarchy
- """
-
- failcnt = IntegerFile("memory.failcnt")
- memsw_failcnt = IntegerFile("memory.memsw.failcnt")
-
- limit_in_bytes = IntegerFile("memory.limit_in_bytes")
- soft_limit_in_bytes = IntegerFile("memory.soft_limit_in_bytes")
- usage_in_bytes = IntegerFile("memory.usage_in_bytes")
- max_usage_in_bytes = IntegerFile("memory.max_usage_in_bytes")
-
- memsw_limit_in_bytes = IntegerFile("memory.memsw.limit_in_bytes")
- memsw_usage_in_bytes = IntegerFile("memory.memsw.usage_in_bytes")
- memsw_max_usage_in_bytes = IntegerFile("memory.memsw.max_usage_in_bytes")
- swappiness = IntegerFile("memory.swappiness")
-
- stat = DictFile("memory.stat", readonly=True)
-
- use_hierarchy = FlagFile("memory.use_hierarchy")
- force_empty = FlagFile("memory.force_empty")
- oom_control = DictOrFlagFile("memory.oom_control")
-
- move_charge_at_immigrate = BitFieldFile("memory.move_charge_at_immigrate")
-
- # Requires special file interface
- # numa_stat =
-
- # Requires eventfd handling -
https://www.kernel.org/doc/Documentation/cgroups/memory.txt
- # pressure_level =
-
-
-class DevicesController(Controller):
- """
- devices.allow
- devices.deny
- devices.list
- """
-
- allow = TypedFile("devices.allow", DeviceAccess, writeonly=True)
- deny = TypedFile("devices.deny", DeviceAccess, writeonly=True)
- list = TypedFile("devices.list", DeviceAccess, readonly=True, many=True)
-
-
-class BlkIOController(Controller):
- """
- blkio.io_merged
- blkio.io_merged_recursive
- blkio.io_queued
- blkio.io_queued_recursive
- blkio.io_service_bytes
- blkio.io_service_bytes_recursive
- blkio.io_serviced
- blkio.io_serviced_recursive
- blkio.io_service_time
- blkio.io_service_time_recursive
- blkio.io_wait_time
- blkio.io_wait_time_recursive
- blkio.leaf_weight
- blkio.leaf_weight_device
- blkio.reset_stats
- blkio.sectors
- blkio.sectors_recursive
- blkio.throttle.io_service_bytes
- blkio.throttle.io_serviced
- blkio.throttle.read_bps_device
- blkio.throttle.read_iops_device
- blkio.throttle.write_bps_device
- blkio.throttle.write_iops_device
- blkio.time
- blkio.time_recursive
- blkio.weight
- blkio.weight_device
- """
-
- io_merged = SplitValueFile("blkio.io_merged", 1, int)
- io_merged_recursive = SplitValueFile("blkio.io_merged_recursive", 1, int)
- io_queued = SplitValueFile("blkio.io_queued", 1, int)
- io_queued_recursive = SplitValueFile("blkio.io_queued_recursive", 1, int)
- io_service_bytes = SplitValueFile("blkio.io_service_bytes", 1, int)
- io_service_bytes_recursive =
SplitValueFile("blkio.io_service_bytes_recursive", 1, int)
- io_serviced = SplitValueFile("blkio.io_serviced", 1, int)
- io_serviced_recursive = SplitValueFile("blkio.io_serviced_recursive", 1,
int)
- io_service_time = SplitValueFile("blkio.io_service_time", 1, int)
- io_service_time_recursive =
SplitValueFile("blkio.io_service_time_recursive", 1, int)
- io_wait_time = SplitValueFile("blkio.io_wait_time", 1, int)
- io_wait_time_recursive = SplitValueFile("blkio.io_wait_time_recursive", 1,
int)
- leaf_weight = IntegerFile("blkio.leaf_weight")
- # TODO: Uncomment the following properties after researching how to
interact with files
- # leaf_weight_device =
- reset_stats = IntegerFile("blkio.reset_stats")
- # sectors =
- # sectors_recursive =
- # throttle_io_service_bytes =
- # throttle_io_serviced =
- throttle_read_bps_device = TypedFile("blkio.throttle.read_bps_device",
contenttype=DeviceThrottle, many=True)
- throttle_read_iops_device = TypedFile("blkio.throttle.read_iops_device",
contenttype=DeviceThrottle, many=True)
- throttle_write_bps_device = TypedFile("blkio.throttle.write_bps_device ",
contenttype=DeviceThrottle, many=True)
- throttle_write_iops_device = TypedFile("blkio.throttle.write_iops_device
", contenttype=DeviceThrottle, many=True)
- # time =
- # time_recursive =
- weight = IntegerFile("blkio.weight")
- # weight_device =
-
-
-class NetClsController(Controller):
-
- """
- net_cls.classid
- """
- class_id = IntegerFile("net_cls.classid")
-
-
-class NetPrioController(Controller):
-
- """
- net_prio.prioidx
- net_prio.ifpriomap
- """
- prioidx = IntegerFile("net_prio.prioidx", readonly=True)
- ifpriomap = DictFile("net_prio.ifpriomap")
diff --git a/airflow/_vendor/cgroupspy/interfaces.py
b/airflow/_vendor/cgroupspy/interfaces.py
deleted file mode 100644
index 85468cca8a..0000000000
--- a/airflow/_vendor/cgroupspy/interfaces.py
+++ /dev/null
@@ -1,339 +0,0 @@
-"""
-Copyright (c) 2014, CloudSigma AG
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the CloudSigma AG nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL CloudSigma AG BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-from collections.abc import Iterable
-from airflow._vendor.cgroupspy.contenttypes import BaseContentType
-
-
-class BaseFileInterface(object):
-
- """
- Basic cgroups file interface, implemented as a python descriptor. Provides
means to get and set cgroup properties.
- """
- readonly = False
- writeonly = False
-
- def __init__(self, filename, readonly=None, writeonly=None):
- if readonly and writeonly:
- raise RuntimeError("This interface cannot be both readonly and
writeonly")
-
- try:
- self.filename = filename.encode()
- except AttributeError:
- self.filename = filename
- self.readonly = readonly or self.readonly
- self.writeonly = writeonly or self.writeonly
-
- def __get__(self, instance, owner):
- if self.writeonly:
- raise RuntimeError("This interface is writeonly")
-
- value = instance.get_property(self.filename)
- return self.sanitize_get(value)
-
- def __set__(self, instance, value):
- if self.readonly:
- raise RuntimeError("This interface is readonly")
-
- value = self.sanitize_set(value)
- if value is not None:
- return instance.set_property(self.filename, value)
-
- def sanitize_get(self, value):
- return value
-
- def sanitize_set(self, value):
- return value
-
-
-class FlagFile(BaseFileInterface):
-
- """
- Converts True/False to 1/0 and vise versa.
- """
-
- def sanitize_get(self, value):
- return bool(int(value))
-
- def sanitize_set(self, value):
- return int(bool(value))
-
-
-class BitFieldFile(BaseFileInterface):
-
- """
- Example: '2' becomes [False, True, False, False, False, False, False,
False]
- """
-
- def sanitize_get(self, value):
- v = int(value)
- # Calculate the length of the value in bits by converting to hex
- length = (len(hex(v)) - 2) * 4
- # Increase length to the next multiple of 8
- length += (7 - (length - 1) % 8)
- return [bool((v >> i) & 1) for i in range(length)]
-
- def sanitize_set(self, value):
- try:
- value = value.encode()
- except AttributeError:
- pass
- if isinstance(value, bytes) or not isinstance(value, Iterable):
- return int(value)
- return sum((int(bool(value[i])) << i) for i in range(len(value)))
-
-
-class IntegerFile(BaseFileInterface):
-
- """
- Get/set single integer values.
- """
-
- def sanitize_get(self, value):
- val = int(value)
- if val == -1:
- val = None
- return val
-
- def sanitize_set(self, value):
- if value is None:
- value = -1
- return int(value)
-
-
-class DictFile(BaseFileInterface):
- def sanitize_get(self, value):
- res = {}
- for el in value.split("\n"):
- key, val = el.split()
- res[key] = int(val)
- return res
-
- def sanitize_set(self, value):
- if not isinstance(value, dict):
- raise ValueError("Value {} must be a dict".format(value))
-
- keys = sorted(value.keys())
- return "\n".join("{} {}".format(k, value[k]) for k in keys)
-
-
-class ListFile(BaseFileInterface):
- readonly = True
-
- def sanitize_get(self, value):
- return value.split()
-
-
-class IntegerListFile(ListFile):
-
- """
- ex: 253237230463342 317756630269369 247294096796305 289833051422078
- """
-
- def sanitize_get(self, value):
- value_list = super(IntegerListFile, self).sanitize_get(value)
- return list(map(int, value_list))
-
- def sanitize_set(self, value):
- if value is None:
- value = '-1'
-
- return " ".join([str(v) for v in value])
-
-
-class CommaDashSetFile(BaseFileInterface):
-
- """
- Builds a set from files containing the following data format 'cpuset.cpus:
1-3,6,11-15',
- returning {1,2,3,5,11,12,13,14,15}
- """
-
- def sanitize_get(self, value):
- elems = []
- for el_group in value.strip().split(','):
- if "-" in el_group:
- start, end = el_group.split("-")
- for el in range(int(start), int(end) + 1):
- elems.append(el)
- else:
- if el_group != '':
- elems.append(int(el_group))
- return set(elems)
-
- def sanitize_set(self, value):
- if len(value) == 0:
- return ' '
-
- try:
- value = value.decode()
- except AttributeError:
- pass
-
- if isinstance(value, str):
- value = value.strip()
- if not value:
- return ' '
- value = value.split(',')
-
- if isinstance(value, Iterable):
- value = set(value)
- else:
- raise ValueError("Value {} must be a sequence of
int".format(value))
-
- for k in value:
- if not isinstance(k, int):
- raise ValueError("Value {} must be a sequence of
int".format(value))
-
- value = sorted(list(value))
- index = [i for i in range(len(value))]
- for i in range(len(value)):
- if index[i] != i:
- continue
-
- j = i
-
- while j < len(value) - 1:
- if value[j] + 1 == value[j + 1]:
- index[j + 1] = i
- j += 1
- else:
- break
-
- parts = []
- for i in range(len(value)):
- if i > 0 and index[i - 1] == index[i]:
- continue
-
- j = i
-
- while j + 1 < len(value) and index[j + 1] == index[j]:
- j += 1
-
- if i == j:
- parts.append(str(value[i]))
- else:
- parts.append('{}-{}'.format(value[i], value[j]))
-
- return ','.join(parts)
-
-
-class MultiLineIntegerFile(BaseFileInterface):
-
- def sanitize_get(self, value):
- int_list = [int(val) for val in value.strip().split("\n") if val]
- return int_list
-
- def sanitize_set(self, value):
- if value is None:
- return '-1'
-
- return '\n'.join(str(x) for x in value)
-
-
-class SplitValueFile(BaseFileInterface):
- """
- Example: Getting int(10) for file with value 'Total 10'. Readonly.
- """
- readonly = True
-
- def __init__(self, filename, position, restype=None, splitchar=" ",
prefix="Total"):
- super(SplitValueFile, self).__init__(filename)
- self.position = position
- self.restype = restype
- self.splitchar = splitchar
- self.prefix = prefix
-
- def sanitize_get(self, value):
- res = value.strip().split(self.splitchar)[self.position]
- if self.restype and not isinstance(res, self.restype):
- return self.restype(res)
- return res
-
- def sanitize_set(self, value):
- return '{}{}{}'.format(self.prefix, self.splitchar, value)
-
-
-class TypedFile(BaseFileInterface):
-
- def __init__(self, filename, contenttype, readonly=None, writeonly=None,
many=False):
- if not issubclass(contenttype, BaseContentType):
- raise RuntimeError("Contenttype should be a class inheriting "
- "from BaseContentType, not
{}".format(contenttype))
-
- self.contenttype = contenttype
- self.many = many
- super(TypedFile, self).__init__(filename, readonly=readonly,
writeonly=writeonly)
-
- def sanitize_set(self, value):
- if isinstance(value, self.contenttype):
- return str(value)
-
- if self.many:
- items = []
- for entry in value:
- if isinstance(entry, str):
- entry = entry.strip()
- if not entry:
- continue
- items.append(str(self.contenttype.from_string(entry)))
- else:
- items.append(str(entry))
- return "\n".join(items)
- else:
- return str(self.contenttype.from_string(value))
-
- def sanitize_get(self, value):
- if self.many:
- result = []
- for line in value.splitlines():
- line = line.strip()
- if not line:
- continue
- result.append(self.contenttype.from_string(line))
- return result
-
- return self.contenttype.from_string(value)
-
-
-class DictOrFlagFile(BaseFileInterface):
- def __init__(self, filename, readonly=None, writeonly=None):
- super(DictOrFlagFile, self).__init__(filename, readonly=readonly,
writeonly=writeonly)
- self.interfaces = {
- 'dict': DictFile(filename),
- 'flag': FlagFile(filename),
- }
-
- def sanitize_get(self, value):
- try:
- return self.interfaces['dict'].sanitize_get(value)
- except Exception:
- return self.interfaces['flag'].sanitize_get(value)
-
- def sanitize_set(self, value):
- try:
- return self.interfaces['dict'].sanitize_set(value)
- except Exception:
- return self.interfaces['flag'].sanitize_set(value)
diff --git a/airflow/_vendor/cgroupspy/nodes.py
b/airflow/_vendor/cgroupspy/nodes.py
deleted file mode 100644
index 8789aae993..0000000000
--- a/airflow/_vendor/cgroupspy/nodes.py
+++ /dev/null
@@ -1,283 +0,0 @@
-"""
-Copyright (c) 2014, CloudSigma AG
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the CloudSigma AG nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL CLOUDSIGMA AG BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-import logging
-
-import os
-
-from .controllers import CpuAcctController, CpuController, CpuSetController,
MemoryController, DevicesController, \
- BlkIOController, NetClsController, NetPrioController
-from .utils import walk_tree, walk_up_tree
-
-
-LOG = logging.getLogger(__name__)
-
-
-class Node(object):
-
- """
- Basic cgroup tree node. Provides means to link it to a parent and set a
controller, depending on the cgroup the node
- exists in.
- """
- NODE_ROOT = b"root"
- NODE_CONTROLLER_ROOT = b"controller_root"
- NODE_SLICE = b"slice"
- NODE_SCOPE = b"scope"
- NODE_CGROUP = b"cgroup"
-
- CONTROLLERS = {
- b"memory": MemoryController,
- b"cpuset": CpuSetController,
- b"cpu": CpuController,
- b"cpuacct": CpuAcctController,
- b"devices": DevicesController,
- b"blkio": BlkIOController,
- b"net_cls": NetClsController,
- b"net_prio": NetPrioController,
- }
-
- def __init__(self, name, parent=None):
- if isinstance(name, str):
- name = name.encode()
-
- self.name = name
- self.verbose_name = name
-
- if parent and not isinstance(parent, Node):
- raise ValueError('Parent should be another Node')
-
- self.parent = parent
- self.children = []
- self.node_type = self._get_node_type()
- self.controller_type = self._get_controller_type()
- self.controller = self._get_controller()
-
- def __eq__(self, other):
- if isinstance(other, self.__class__) and self.full_path ==
other.full_path:
- return True
- return False
-
- def __repr__(self):
- return "<{} {}>".format(self.__class__.__name__, self.path.decode())
-
- @property
- def full_path(self):
- """Absolute system path to the node"""
-
- if self.parent:
- return os.path.join(self.parent.full_path, self.name)
- return self.name
-
- @property
- def path(self):
- """Node's relative path from the root node"""
-
- if self.parent:
- try:
- parent_path = self.parent.path.encode()
- except AttributeError:
- parent_path = self.parent.path
- return os.path.join(parent_path, self.name)
- return b"/"
-
- def _get_node_type(self):
- """Returns the current node's type"""
-
- if self.parent is None:
- return self.NODE_ROOT
- elif self.parent.node_type == self.NODE_ROOT:
- return self.NODE_CONTROLLER_ROOT
- elif b".slice" in self.name or b'.partition' in self.name:
- return self.NODE_SLICE
- elif b".scope" in self.name:
- return self.NODE_SCOPE
- else:
- return self.NODE_CGROUP
-
- def _get_controller_type(self):
- """Returns the current node's controller type"""
-
- if self.node_type == self.NODE_CONTROLLER_ROOT and self.name in
self.CONTROLLERS:
- return self.name
- elif self.parent:
- return self.parent.controller_type
- else:
- return None
-
- def _get_controller(self):
- """Returns the current node's controller"""
-
- if self.controller_type:
- return self.CONTROLLERS[self.controller_type](self)
- return None
-
- def create_cgroup(self, name):
- """
- Create a cgroup by name and attach it under this node.
- """
- if isinstance(name, str):
- name = name.encode()
-
- node = Node(name, parent=self)
- if node in self.children:
- raise RuntimeError('Node {} already exists under {}'.format(name,
self.path))
-
- fp = os.path.join(self.full_path, name)
- os.mkdir(fp)
- self.children.append(node)
- return node
-
- def delete_cgroup(self, name):
- """
- Delete a cgroup by name and detach it from this node.
- Raises OSError if the cgroup is not empty.
- """
- name = name.encode()
- fp = os.path.join(self.full_path, name)
- if os.path.exists(fp):
- os.rmdir(fp)
- node = Node(name, parent=self)
- try:
- self.children.remove(node)
- except ValueError:
- return
-
- def delete_empty_children(self):
- """
- Walk through the children of this node and delete any that are empty.
- """
- removed_children = []
-
- for child in self.children:
- child.delete_empty_children()
- try:
- if os.path.exists(child.full_path):
- os.rmdir(child.full_path)
- removed_children.append(child)
- except OSError:
- pass
-
- for child in removed_children:
- self.children.remove(child)
-
- def walk(self):
- """Walk through this node and its children - pre-order depth-first"""
- return walk_tree(self)
-
- def walk_up(self):
- """Walk through this node and its children - post-order depth-first"""
- return walk_up_tree(self)
-
-
-class NodeControlGroup(object):
-
- """
- A tree node that can group together same multiple nodes based on their
position in the cgroup hierarchy
-
- For example - we have mounted all the cgroups in /sys/fs/cgroup/ and we
have a scope in each of them under
- /{cpuset,cpu,memory,cpuacct}/isolated.scope/. Then NodeControlGroup, can
provide access to all cgroup properties
- like
-
- isolated_scope.cpu
- isolated_scope.memory
- isolated_scope.cpuset
-
- Requires a basic Node tree to be generated.
- """
-
- def __init__(self, name, parent=None):
- self.name = name
- self.parent = parent
- self.children_map = {}
- self.controllers = {}
- self.nodes = []
-
- @property
- def path(self):
- if self.parent:
- base_name, ext = os.path.splitext(self.name)
- if ext not in [b'.slice', b'.scope', b'.partition']:
- base_name = self.name
- return os.path.join(self.parent.path, base_name)
- return b"/"
-
- def add_node(self, node):
- """
- A a Node object to the group. Only one node per cgroup is supported
- """
- if self.controllers.get(node.controller_type, None):
- raise RuntimeError("Cannot add node {} to the node group. A node
for {} group is already assigned".format(
- node,
- node.controller_type
- ))
- self.nodes.append(node)
- if node.controller:
- self.controllers[node.controller_type] = node.controller
- setattr(self, node.controller_type.decode(), node.controller)
-
- def __repr__(self):
- return "<{} {}>".format(self.__class__.__name__, self.name.decode())
-
- @property
- def children(self):
- return list(self.children_map.values())
-
- @property
- def group_tasks(self):
- """All tasks in the hierarchy, affected by this group."""
- tasks = set()
- for node in walk_tree(self):
- for ctrl in node.controllers.values():
- tasks.update(ctrl.tasks)
- return tasks
-
- @property
- def tasks(self):
- """Tasks in this exact group"""
- tasks = set()
- for ctrl in self.controllers.values():
- tasks.update(ctrl.tasks)
- return tasks
-
-
-class NodeVM(NodeControlGroup):
-
- """Abstraction of a QEMU virtual machine node."""
-
- @property
- def verbose_name(self):
- try:
- return self.nodes[0].verbose_name
- except Exception:
- return "AnonymousVM"
-
- @property
- def emulator(self):
- return self.children_map.get(b"emulator", None)
-
- @property
- def vcpus(self):
- return [node for name, node in self.children_map.items() if
name.startswith(b"vcpu")]
diff --git a/airflow/_vendor/cgroupspy/trees.py
b/airflow/_vendor/cgroupspy/trees.py
deleted file mode 100644
index f773f22db5..0000000000
--- a/airflow/_vendor/cgroupspy/trees.py
+++ /dev/null
@@ -1,246 +0,0 @@
-"""
-Copyright (c) 2014, CloudSigma AG
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the CloudSigma AG nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL CLOUDSIGMA AG BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-import os
-
-from .nodes import Node, NodeControlGroup, NodeVM
-from .utils import walk_tree, walk_up_tree, split_path_components
-
-
-class BaseTree(object):
-
- """ A basic cgroup node tree. An exact representation of the filesystem
tree, provided by cgroups. """
-
- def __init__(self, root_path=b"/sys/fs/cgroup/", groups=None,
sub_groups=None):
- """
- Construct a basic cgroup node tree. An exact representation of the
filesystem tree, provided by cgroups.
-
- :param root_path: str -> The path of the root folder containing the
cgroups. By default it is /sys/fs/cgroup/
- :param groups: None | list -> Use only those controllers to collect
information in this tree instance
- :param sub_groups: None | list -> Use only those slices to retrieve
information. If the slice does not exist,
- then create it
- """
- if isinstance(root_path, str):
- root_path = root_path.encode()
-
- self.root_path = root_path
- self._groups = groups or []
- self._sub_groups = sub_groups or []
- self.root = Node(root_path)
- self._build_tree()
-
- @property
- def groups(self):
- return self._groups
-
- @property
- def sub_groups(self):
- return self._sub_groups
-
- def _build_tree(self):
- """
- Build a full or a partial tree, depending on the groups/sub-groups
specified.
- """
-
- groups = self._groups or self.get_children_paths(self.root_path)
- for group in groups:
- node = Node(name=group, parent=self.root)
- self.root.children.append(node)
- self._init_sub_groups(node)
-
- def _init_sub_groups(self, parent):
- """
- Initialise sub-groups, and create any that do not already exist.
- """
- if not self._sub_groups:
- self._init_children(parent)
- return
-
- sub_group_components = dict()
-
- for sub_group in self._sub_groups:
- sub_group = sub_group.strip()
- if not sub_group:
- continue
-
- components = split_path_components(sub_group)
- if not components:
- continue
-
- sub_group_components[sub_group] = components
-
- self._sub_groups = list(sub_group_components.keys())
- if not self._sub_groups:
- self._init_children(parent)
- return
-
- for sub_group, components in sub_group_components.items():
- for component in components:
- if isinstance(component, str):
- component = component.encode()
-
- fp = os.path.join(parent.full_path, component)
- if os.path.exists(fp):
- node = Node(name=component, parent=parent)
- parent.children.append(node)
- else:
- node = parent.create_cgroup(component)
- parent = node
- self._init_children(node)
-
- def _init_children(self, parent):
- """
- Initialise each node's children - essentially build the tree.
- """
-
- for dir_name in self.get_children_paths(parent.full_path):
- child = Node(name=dir_name, parent=parent)
- parent.children.append(child)
- self._init_children(child)
-
- def get_children_paths(self, parent_full_path):
- for dir_name in os.listdir(parent_full_path):
- if os.path.isdir(os.path.join(parent_full_path, dir_name)):
- yield dir_name
-
- def walk(self, root=None):
- """Walk through each each node - pre-order depth-first"""
-
- if root is None:
- root = self.root
- return walk_tree(root)
-
- def walk_up(self, root=None):
- """Walk through each each node - post-order depth-first"""
-
- if root is None:
- root = self.root
- return walk_up_tree(root)
-
-
-class Tree(BaseTree):
- def get_node_by_path(self, path):
- try:
- path = path.encode()
- except AttributeError:
- pass
- path = path.rstrip(b"/")
- for node in self.walk():
- if node.path == path:
- return node
-
-
-class GroupedTree(object):
- """
- A grouped tree - that has access to all cgroup partitions with the same
name ex:
- 'machine' partition in memory, cpuset, cpus, etc cgroups.
- All these attributes are accessed via machine.cpus, machine.cpuset, etc.
-
- """
-
- def __init__(self, root_path=b"/sys/fs/cgroup", groups=None,
sub_groups=None):
-
- self.node_tree = BaseTree(root_path=root_path, groups=groups,
sub_groups=sub_groups)
- self.control_root = NodeControlGroup(name=b"cgroup")
- for ctrl in self.node_tree.root.children:
- self.control_root.add_node(ctrl)
-
- self._init_control_tree(self.control_root)
-
- def _init_control_tree(self, cgroup):
- new_cgroups = []
- for node in cgroup.nodes:
-
- for child in node.children:
- if child.name not in cgroup.children_map:
- new_cgroup = self._create_node(child.verbose_name,
parent=cgroup)
- cgroup.children_map[child.name] = new_cgroup
- new_cgroups.append(new_cgroup)
-
- cgroup.children_map[child.name].add_node(child)
-
- for new_group in new_cgroups:
- self._init_control_tree(new_group)
-
- def _create_node(self, name, parent):
- return NodeControlGroup(name, parent=parent)
-
- def walk(self, root=None):
- if root is None:
- root = self.control_root
- return walk_tree(root)
-
- def walk_up(self, root=None):
- if root is None:
- root = self.control_root
- return walk_up_tree(root)
-
- def get_node_by_name(self, pattern):
- try:
- pattern = pattern.encode()
- except AttributeError:
- pass
- for node in self.walk():
- if pattern in node.name:
- return node
-
- def get_node_by_path(self, path):
- try:
- path = path.encode()
- except AttributeError:
- pass
- for node in self.walk():
- if path == node.path:
- return node
-
-
-class VMTree(GroupedTree):
-
- def __init__(self, *args, **kwargs):
- self.vms = {}
- super(VMTree, self).__init__(*args, **kwargs)
-
- def _create_node(self, name, parent):
- if b"libvirt-qemu" in name or b"machine-qemu" in name or parent.name
== b"qemu":
- vm_node = NodeVM(name, parent=parent)
- if isinstance(name, bytes):
- key = name.decode()
- else:
- key = name
- self.vms[key] = vm_node
- return vm_node
- return super(VMTree, self)._create_node(name, parent=parent)
-
- def get_vm_node(self, name):
- keys = [
- name,
- '%s.libvirt-qemu' % name,
- "machine-qemu%s" % name
- ]
-
- for key in keys:
- if key in self.vms:
- return self.vms[key]
diff --git a/airflow/_vendor/cgroupspy/utils.py
b/airflow/_vendor/cgroupspy/utils.py
deleted file mode 100644
index 884f8071f1..0000000000
--- a/airflow/_vendor/cgroupspy/utils.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""
-Copyright (c) 2014, CloudSigma AG
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the CloudSigma AG nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL CLOUDSIGMA AG BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-import os
-
-
-def walk_tree(root):
- """Pre-order depth-first"""
- yield root
-
- for child in root.children:
- for el in walk_tree(child):
- yield el
-
-
-def walk_up_tree(root):
- """Post-order depth-first"""
- for child in root.children:
- for el in walk_up_tree(child):
- yield el
-
- yield root
-
-
-def split_path_components(path):
- if isinstance(path, bytes):
- path = str(path.decode())
-
- if path.endswith('/'):
- path = path.rstrip('/')
-
- components = []
- while True:
- path, component = os.path.split(path)
- if component != "":
- components.append(component)
- else:
- if path != "":
- components.append(path)
- break
- components.reverse()
-
- if len(components) > 0 and components[0] == '/':
- return components[1:]
-
- return components
diff --git a/airflow/_vendor/vendor.md b/airflow/_vendor/vendor.md
index 94d18bc452..ab102ab083 100644
--- a/airflow/_vendor/vendor.md
+++ b/airflow/_vendor/vendor.md
@@ -1,3 +1,2 @@
| Package | Version | File | SHA256
|
|-----------|---------|------------------------|------------------------------------------------------------------|
-| cgroupspy | 0.2.1 | cgroupspy-0.2.1.tar.gz |
2a9e578566b99ac05c452d23044ea3061c9f9445752360c2ce4e9f2439fa1577 |
diff --git a/airflow/task/task_runner/cgroup_task_runner.py
b/airflow/task/task_runner/cgroup_task_runner.py
index a738652985..d6c6e53abf 100644
--- a/airflow/task/task_runner/cgroup_task_runner.py
+++ b/airflow/task/task_runner/cgroup_task_runner.py
@@ -23,8 +23,8 @@ import os
import uuid
import psutil
+from cgroupspy import trees
-from airflow._vendor.cgroupspy import trees
from airflow.task.task_runner.base_task_runner import BaseTaskRunner
from airflow.utils.operator_resources import Resources
from airflow.utils.platform import getuser
diff --git a/licenses/LICENSE-cgroupspy.txt b/licenses/LICENSE-cgroupspy.txt
deleted file mode 100644
index 6070cf1c8e..0000000000
--- a/licenses/LICENSE-cgroupspy.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2014, CloudSigma AG
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-* Neither the name of cgroupspy nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/scripts/ci/pre_commit/pre_commit_setup_cfg_file.sh
b/scripts/ci/pre_commit/pre_commit_setup_cfg_file.sh
index e741f9ea4b..5d2cf27a7c 100755
--- a/scripts/ci/pre_commit/pre_commit_setup_cfg_file.sh
+++ b/scripts/ci/pre_commit/pre_commit_setup_cfg_file.sh
@@ -33,7 +33,7 @@ readonly TMP_FILE
TMP_OUTPUT=$(mktemp)
readonly TMP_OUTPUT
-find "licenses" -type f -exec echo " " {} \; | LC_ALL=C sort >>"${TMP_FILE}"
+find "licenses" -type f -exec echo " " {} \; | grep -v "LICENSES-ui.txt" |
LC_ALL=C sort >>"${TMP_FILE}"
SETUP_CFG_FILE="${AIRFLOW_SOURCES}/setup.cfg"
readonly SETUP_CFG_FILE
diff --git a/setup.cfg b/setup.cfg
index 11507cb4c6..7e4a9aa54f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -30,7 +30,6 @@ license_files =
# Start of licenses generated automatically
licenses/LICENSE-bootstrap.txt
licenses/LICENSE-bootstrap3-typeahead.txt
- licenses/LICENSE-cgroupspy.txt
licenses/LICENSE-d3-shape.txt
licenses/LICENSE-d3-tip.txt
licenses/LICENSE-d3js.txt
diff --git a/setup.py b/setup.py
index 4c2a9c8f0a..a91626be5b 100644
--- a/setup.py
+++ b/setup.py
@@ -248,13 +248,9 @@ celery = [
'celery>=5.2.3,<6',
'flower>=1.0.0',
]
-cgroups = [ # type:ignore
- # Cgroups are now vendored in `airflow/_vendor/cgroupspy` for Python 3.10
compatibility
- # The vendored code can be removed once cgroupspy released a new version
after fixing
- # the incompatibility https://github.com/cloudsigma/cgroupspy/issues/13
(hopefully >0.2.1 will
- # be good for that. We should also be able to remove type:ignore above, as
MyPy can't derive the type
- # when this line is commented out
- # 'cgroupspy>0.2.1',
+cgroups = [
+ # Cgroupspy 0.2.2 added Python 3.10 compatibility
+ 'cgroupspy>=0.2.2',
]
cloudant = [
'cloudant>=2.0',