Skip to content

Commit 1d44c57

Browse files
authored
Merge pull request #872 from ErikJiang/update_spray_image
Update spray image
2 parents f095c08 + c2e5001 commit 1d44c57

File tree

3 files changed

+185
-2
lines changed

3 files changed

+185
-2
lines changed

.github/workflows/call-build-imgs-for-spray.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ jobs:
6363
- name: kubespray base image build
6464
uses: docker/[email protected]
6565
with:
66-
context: ./build/images/kubespray
66+
context: ./
67+
file: build/images/kubespray/Dockerfile
6768
build-args: |
6869
SPRAY_REF=${{ inputs.SPRAY_REF }}
6970
github-token: ${{ secrets.GITHUB_TOKEN }}

build/images/kubespray/Dockerfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,9 @@ FROM scratch
3939
COPY --from=spray-build / /
4040

4141
ENV ANSIBLE_CONFIG=/kubespray/ansible.cfg
42-
WORKDIR /kubespray
42+
WORKDIR /kubespray
43+
44+
COPY build/images/patch_files/pkg_mgr.py /tmp/
45+
RUN SITE_PKG_PATH=$(python3 -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])') \
46+
&& PKG_MGR_PATH="${SITE_PKG_PATH}/ansible/module_utils/facts/system/pkg_mgr.py" \
47+
&& cp /tmp/pkg_mgr.py ${PKG_MGR_PATH}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Collect facts related to the system package manager
2+
3+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4+
5+
from __future__ import (absolute_import, division, print_function)
6+
__metaclass__ = type
7+
8+
import os
9+
import subprocess
10+
11+
import ansible.module_utils.compat.typing as t
12+
13+
from ansible.module_utils.facts.collector import BaseFactCollector
14+
15+
# A list of dicts. If there is a platform with more than one
16+
# package manager, put the preferred one last. If there is an
17+
# ansible module, use that as the value for the 'name' key.
18+
PKG_MGRS = [{'path': '/usr/bin/rpm-ostree', 'name': 'atomic_container'},
19+
{'path': '/usr/bin/yum', 'name': 'yum'},
20+
{'path': '/usr/bin/dnf', 'name': 'dnf'},
21+
{'path': '/usr/bin/apt-get', 'name': 'apt'},
22+
{'path': '/usr/bin/zypper', 'name': 'zypper'},
23+
{'path': '/usr/sbin/urpmi', 'name': 'urpmi'},
24+
{'path': '/usr/bin/pacman', 'name': 'pacman'},
25+
{'path': '/bin/opkg', 'name': 'opkg'},
26+
{'path': '/usr/pkg/bin/pkgin', 'name': 'pkgin'},
27+
{'path': '/opt/local/bin/pkgin', 'name': 'pkgin'},
28+
{'path': '/opt/tools/bin/pkgin', 'name': 'pkgin'},
29+
{'path': '/opt/local/bin/port', 'name': 'macports'},
30+
{'path': '/usr/local/bin/brew', 'name': 'homebrew'},
31+
{'path': '/opt/homebrew/bin/brew', 'name': 'homebrew'},
32+
{'path': '/sbin/apk', 'name': 'apk'},
33+
{'path': '/usr/sbin/pkg', 'name': 'pkgng'},
34+
{'path': '/usr/sbin/swlist', 'name': 'swdepot'},
35+
{'path': '/usr/bin/emerge', 'name': 'portage'},
36+
{'path': '/usr/sbin/pkgadd', 'name': 'svr4pkg'},
37+
{'path': '/usr/bin/pkg', 'name': 'pkg5'},
38+
{'path': '/usr/bin/xbps-install', 'name': 'xbps'},
39+
{'path': '/usr/local/sbin/pkg', 'name': 'pkgng'},
40+
{'path': '/usr/bin/swupd', 'name': 'swupd'},
41+
{'path': '/usr/sbin/sorcery', 'name': 'sorcery'},
42+
{'path': '/usr/bin/installp', 'name': 'installp'},
43+
{'path': '/QOpenSys/pkgs/bin/yum', 'name': 'yum'},
44+
]
45+
46+
47+
class OpenBSDPkgMgrFactCollector(BaseFactCollector):
48+
name = 'pkg_mgr'
49+
_fact_ids = set() # type: t.Set[str]
50+
_platform = 'OpenBSD'
51+
52+
def collect(self, module=None, collected_facts=None):
53+
facts_dict = {}
54+
55+
facts_dict['pkg_mgr'] = 'openbsd_pkg'
56+
return facts_dict
57+
58+
59+
# the fact ends up being 'pkg_mgr' so stick with that naming/spelling
60+
class PkgMgrFactCollector(BaseFactCollector):
61+
name = 'pkg_mgr'
62+
_fact_ids = set() # type: t.Set[str]
63+
_platform = 'Generic'
64+
required_facts = set(['distribution'])
65+
66+
def _pkg_mgr_exists(self, pkg_mgr_name):
67+
for cur_pkg_mgr in [pkg_mgr for pkg_mgr in PKG_MGRS if pkg_mgr['name'] == pkg_mgr_name]:
68+
if os.path.exists(cur_pkg_mgr['path']):
69+
return pkg_mgr_name
70+
71+
def _check_rh_versions(self, pkg_mgr_name, collected_facts):
72+
if os.path.exists('/run/ostree-booted'):
73+
return "atomic_container"
74+
75+
if collected_facts['ansible_distribution'] == 'Fedora':
76+
try:
77+
if int(collected_facts['ansible_distribution_major_version']) < 23:
78+
if self._pkg_mgr_exists('yum'):
79+
pkg_mgr_name = 'yum'
80+
81+
else:
82+
if self._pkg_mgr_exists('dnf'):
83+
pkg_mgr_name = 'dnf'
84+
except ValueError:
85+
# If there's some new magical Fedora version in the future,
86+
# just default to dnf
87+
pkg_mgr_name = 'dnf'
88+
elif collected_facts['ansible_distribution'] == 'Amazon':
89+
try:
90+
if int(collected_facts['ansible_distribution_major_version']) < 2022:
91+
if self._pkg_mgr_exists('yum'):
92+
pkg_mgr_name = 'yum'
93+
else:
94+
if self._pkg_mgr_exists('dnf'):
95+
pkg_mgr_name = 'dnf'
96+
except ValueError:
97+
pkg_mgr_name = 'dnf'
98+
elif collected_facts['ansible_distribution'] == 'Kylin Linux Advanced Server':
99+
try:
100+
major_version = collected_facts['ansible_distribution_major_version']
101+
major_version = major_version[1:] if major_version[0] == 'V' else major_version
102+
if int(major_version) < 10:
103+
if self._pkg_mgr_exists('yum'):
104+
pkg_mgr_name = 'yum'
105+
else:
106+
if self._pkg_mgr_exists('dnf'):
107+
pkg_mgr_name = 'dnf'
108+
except ValueError:
109+
pkg_mgr_name = 'dnf'
110+
else:
111+
# If it's not one of the above and it's Red Hat family of distros, assume
112+
# RHEL or a clone. For versions of RHEL < 8 that Ansible supports, the
113+
# vendor supported official package manager is 'yum' and in RHEL 8+
114+
# (as far as we know at the time of this writing) it is 'dnf'.
115+
# If anyone wants to force a non-official package manager then they
116+
# can define a provider to either the package or yum action plugins.
117+
if int(collected_facts['ansible_distribution_major_version']) < 8:
118+
pkg_mgr_name = 'yum'
119+
else:
120+
pkg_mgr_name = 'dnf'
121+
return pkg_mgr_name
122+
123+
def _check_apt_flavor(self, pkg_mgr_name):
124+
# Check if '/usr/bin/apt' is APT-RPM or an ordinary (dpkg-based) APT.
125+
# There's rpm package on Debian, so checking if /usr/bin/rpm exists
126+
# is not enough. Instead ask RPM if /usr/bin/apt-get belongs to some
127+
# RPM package.
128+
rpm_query = '/usr/bin/rpm -q --whatprovides /usr/bin/apt-get'.split()
129+
if os.path.exists('/usr/bin/rpm'):
130+
with open(os.devnull, 'w') as null:
131+
try:
132+
subprocess.check_call(rpm_query, stdout=null, stderr=null)
133+
pkg_mgr_name = 'apt_rpm'
134+
except subprocess.CalledProcessError:
135+
# No apt-get in RPM database. Looks like Debian/Ubuntu
136+
# with rpm package installed
137+
pkg_mgr_name = 'apt'
138+
return pkg_mgr_name
139+
140+
def pkg_mgrs(self, collected_facts):
141+
# Filter out the /usr/bin/pkg because on Altlinux it is actually the
142+
# perl-Package (not Solaris package manager).
143+
# Since the pkg5 takes precedence over apt, this workaround
144+
# is required to select the suitable package manager on Altlinux.
145+
if collected_facts['ansible_os_family'] == 'Altlinux':
146+
return filter(lambda pkg: pkg['path'] != '/usr/bin/pkg', PKG_MGRS)
147+
else:
148+
return PKG_MGRS
149+
150+
def collect(self, module=None, collected_facts=None):
151+
facts_dict = {}
152+
collected_facts = collected_facts or {}
153+
154+
pkg_mgr_name = 'unknown'
155+
for pkg in self.pkg_mgrs(collected_facts):
156+
if os.path.exists(pkg['path']):
157+
pkg_mgr_name = pkg['name']
158+
159+
# Handle distro family defaults when more than one package manager is
160+
# installed or available to the distro, the ansible_fact entry should be
161+
# the default package manager officially supported by the distro.
162+
if collected_facts['ansible_os_family'] == "RedHat":
163+
pkg_mgr_name = self._check_rh_versions(pkg_mgr_name, collected_facts)
164+
elif collected_facts['ansible_os_family'] == 'Debian' and pkg_mgr_name != 'apt':
165+
# It's possible to install yum, dnf, zypper, rpm, etc inside of
166+
# Debian. Doing so does not mean the system wants to use them.
167+
pkg_mgr_name = 'apt'
168+
elif collected_facts['ansible_os_family'] == 'Altlinux':
169+
if pkg_mgr_name == 'apt':
170+
pkg_mgr_name = 'apt_rpm'
171+
172+
# Check if /usr/bin/apt-get is ordinary (dpkg-based) APT or APT-RPM
173+
if pkg_mgr_name == 'apt':
174+
pkg_mgr_name = self._check_apt_flavor(pkg_mgr_name)
175+
176+
facts_dict['pkg_mgr'] = pkg_mgr_name
177+
return facts_dict

0 commit comments

Comments
 (0)