Accepting request 1236216 from systemsmanagement:saltstack

- Revert setting SELinux context for minion service (bsc#1233667)
- Remove System V init support
  * Make systemd the only supported init system by removing System V init
    and insserv references
  * Ensure package builds with no init system dependencies if built
    without systemd (for example for use in containers)
  * Apply some spec-cleaner suggestions (update copyright year, sort
    requirements, adjust spacing)
- Added:
  * revert-setting-selinux-context-for-minion-service-bs.patch

- Fix the condition of alternatives for Tumbleweed and Leap 16
- Use update-alternatives for salt-call and fix builing on EL8
- Build all python bindings for all flavors
- Make minion reconnecting on changing master IP (bsc#1228182)
- Added:
  * make-minion-reconnecting-on-changing-master-ip-bsc-1.patch

OBS-URL: https://build.opensuse.org/request/show/1236216
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/salt?expand=0&rev=163
This commit is contained in:
Ana Guerrero 2025-01-12 10:10:21 +00:00 committed by Git OBS Bridge
commit cec31345f1
5 changed files with 1156 additions and 261 deletions

View File

@ -1 +1 @@
e1eca529a18f7fde5ceec0e3d9524028c7affd12 d7c50289494a6b41234aee2204209083e30fbd8d

View File

@ -0,0 +1,770 @@
From eb6c67e6f535cdfbf685a54c6352018673e37a12 Mon Sep 17 00:00:00 2001
From: Victor Zhestkov <vzhestkov@suse.com>
Date: Tue, 26 Nov 2024 11:59:08 +0300
Subject: [PATCH] Make minion reconnecting on changing master IP
(bsc#1228182)
* Minions check dns when re-connecting to a master
Check for a chainging dns record anytime a minion gets disconnected from
it's master. See github issue #63654 #61482.
* Regression tests for dns defined masters
Adding tests to validate we check for changing dns anytime we're
disconnected from the currently connected master
* Update docs for master dns changes
Update docs to use master_alive_interval to detect master ip changes via
DNS.
* Remove comment which is not true anymore
* Make minion reconnecting on changing master IP
with zeromq transport
* Don't create schedule for alive if no master_alive_interval
* Skip the tests if running with non-root user
* Skip if unable to set additional IP address
* Set master_tries to -1 for minions
* Fix the tests
---------
Co-authored-by: Daniel A. Wozniak <daniel.wozniak@broadcom.com>
---
conf/minion | 5 +-
doc/ref/configuration/minion.rst | 4 +-
salt/channel/client.py | 2 -
salt/config/__init__.py | 4 +-
salt/minion.py | 190 ++++++++----------
salt/transport/zeromq.py | 17 +-
tests/pytests/scenarios/dns/__init__.py | 0
tests/pytests/scenarios/dns/conftest.py | 99 +++++++++
.../scenarios/dns/multimaster/conftest.py | 124 ++++++++++++
.../scenarios/dns/multimaster/test_dns.py | 54 +++++
tests/pytests/scenarios/dns/test_dns.py | 37 ++++
.../multimaster/test_failover_master.py | 4 -
tests/pytests/unit/test_minion.py | 2 +
13 files changed, 422 insertions(+), 120 deletions(-)
create mode 100644 tests/pytests/scenarios/dns/__init__.py
create mode 100644 tests/pytests/scenarios/dns/conftest.py
create mode 100644 tests/pytests/scenarios/dns/multimaster/conftest.py
create mode 100644 tests/pytests/scenarios/dns/multimaster/test_dns.py
create mode 100644 tests/pytests/scenarios/dns/test_dns.py
diff --git a/conf/minion b/conf/minion
index eeef626fa8..f89e18451f 100644
--- a/conf/minion
+++ b/conf/minion
@@ -271,9 +271,8 @@
#ping_interval: 0
# To auto recover minions if master changes IP address (DDNS)
-# auth_tries: 10
-# auth_safemode: True
-# ping_interval: 2
+# master_alive_interval: 10
+# master_tries: -1
#
# Minions won't know master is missing until a ping fails. After the ping fail,
# the minion will attempt authentication and likely fails out and cause a restart.
diff --git a/doc/ref/configuration/minion.rst b/doc/ref/configuration/minion.rst
index 57af5ce4a3..a1b0f2e86e 100644
--- a/doc/ref/configuration/minion.rst
+++ b/doc/ref/configuration/minion.rst
@@ -291,7 +291,9 @@ Default: ``0``
Configures how often, in seconds, the minion will verify that the current
master is alive and responding. The minion will try to establish a connection
-to the next master in the list if it finds the existing one is dead.
+to the next master in the list if it finds the existing one is dead. This
+setting can also be used to detect master DNS record changes when a minion has
+been disconnected.
.. code-block:: yaml
diff --git a/salt/channel/client.py b/salt/channel/client.py
index 76d7a8e5b9..34aafb2c9e 100644
--- a/salt/channel/client.py
+++ b/salt/channel/client.py
@@ -385,8 +385,6 @@ class AsyncPubChannel:
# else take the relayed publish_port master reports
else:
publish_port = self.auth.creds["publish_port"]
- # TODO: The zeromq transport does not use connect_callback and
- # disconnect_callback.
yield self.transport.connect(
publish_port, self.connect_callback, self.disconnect_callback
)
diff --git a/salt/config/__init__.py b/salt/config/__init__.py
index b3cd5d85ae..d4865807e6 100644
--- a/salt/config/__init__.py
+++ b/salt/config/__init__.py
@@ -75,7 +75,7 @@ elif salt.utils.platform.is_darwin():
else:
_DFLT_IPC_MODE = "ipc"
_DFLT_FQDNS_GRAINS = False
- _MASTER_TRIES = 1
+ _MASTER_TRIES = -1
_MASTER_USER = salt.utils.user.get_user()
@@ -1272,7 +1272,7 @@ DEFAULT_MINION_OPTS = immutabletypes.freeze(
"username": None,
"password": None,
"zmq_filtering": False,
- "zmq_monitor": False,
+ "zmq_monitor": True,
"cache_sreqs": True,
"cmd_safe": True,
"sudo_user": "",
diff --git a/salt/minion.py b/salt/minion.py
index e21a017cfd..834f0848c6 100644
--- a/salt/minion.py
+++ b/salt/minion.py
@@ -2737,10 +2737,64 @@ class Minion(MinionBase):
# we are not connected anymore
self.connected = False
log.info("Connection to master %s lost", self.opts["master"])
+ if self.opts["transport"] != "tcp":
+ self.schedule.delete_job(name=master_event(type="alive"))
+
+ log.info("Trying to tune in to next master from master-list")
+
+ if hasattr(self, "pub_channel"):
+ self.pub_channel.on_recv(None)
+ if hasattr(self.pub_channel, "auth"):
+ self.pub_channel.auth.invalidate()
+ if hasattr(self.pub_channel, "close"):
+ self.pub_channel.close()
+ if hasattr(self, "req_channel") and self.req_channel:
+ self.req_channel.close()
+ self.req_channel = None
+
+ # if eval_master finds a new master for us, self.connected
+ # will be True again on successful master authentication
+ try:
+ master, self.pub_channel = yield self.eval_master(
+ opts=self.opts,
+ failed=True,
+ failback=tag.startswith(master_event(type="failback")),
+ )
+ except SaltClientError:
+ pass
+
+ if self.connected:
+ self.opts["master"] = master
+
+ # re-init the subsystems to work with the new master
+ log.info(
+ "Re-initialising subsystems for new master %s",
+ self.opts["master"],
+ )
+
+ self.req_channel = salt.channel.client.AsyncReqChannel.factory(
+ self.opts, io_loop=self.io_loop
+ )
- if self.opts["master_type"] != "failover":
- # modify the scheduled job to fire on reconnect
- if self.opts["transport"] != "tcp":
+ # put the current schedule into the new loaders
+ self.opts["schedule"] = self.schedule.option("schedule")
+ (
+ self.functions,
+ self.returners,
+ self.function_errors,
+ self.executors,
+ ) = self._load_modules()
+ # make the schedule to use the new 'functions' loader
+ self.schedule.functions = self.functions
+ self.pub_channel.on_recv(self._handle_payload)
+ self._fire_master_minion_start()
+ log.info("Minion is ready to receive requests!")
+
+ # update scheduled job to run with the new master addr
+ if (
+ self.opts["transport"] != "tcp"
+ and self.opts["master_alive_interval"] > 0
+ ):
schedule = {
"function": "status.master",
"seconds": self.opts["master_alive_interval"],
@@ -2749,116 +2803,35 @@ class Minion(MinionBase):
"return_job": False,
"kwargs": {
"master": self.opts["master"],
- "connected": False,
+ "connected": True,
},
}
self.schedule.modify_job(
name=master_event(type="alive", master=self.opts["master"]),
schedule=schedule,
)
- else:
- # delete the scheduled job to don't interfere with the failover process
- if self.opts["transport"] != "tcp":
- self.schedule.delete_job(name=master_event(type="alive"))
-
- log.info("Trying to tune in to next master from master-list")
-
- if hasattr(self, "pub_channel"):
- self.pub_channel.on_recv(None)
- if hasattr(self.pub_channel, "auth"):
- self.pub_channel.auth.invalidate()
- if hasattr(self.pub_channel, "close"):
- self.pub_channel.close()
- del self.pub_channel
-
- # if eval_master finds a new master for us, self.connected
- # will be True again on successful master authentication
- try:
- master, self.pub_channel = yield self.eval_master(
- opts=self.opts,
- failed=True,
- failback=tag.startswith(master_event(type="failback")),
- )
- except SaltClientError:
- pass
-
- if self.connected:
- self.opts["master"] = master
-
- # re-init the subsystems to work with the new master
- log.info(
- "Re-initialising subsystems for new master %s",
- self.opts["master"],
- )
-
- self.req_channel = (
- salt.transport.client.AsyncReqChannel.factory(
- self.opts, io_loop=self.io_loop
- )
- )
-
- # put the current schedule into the new loaders
- self.opts["schedule"] = self.schedule.option("schedule")
- (
- self.functions,
- self.returners,
- self.function_errors,
- self.executors,
- ) = self._load_modules()
- # make the schedule to use the new 'functions' loader
- self.schedule.functions = self.functions
- self.pub_channel.on_recv(self._handle_payload)
- self._fire_master_minion_start()
- log.info("Minion is ready to receive requests!")
-
- # update scheduled job to run with the new master addr
- if self.opts["transport"] != "tcp":
- schedule = {
- "function": "status.master",
- "seconds": self.opts["master_alive_interval"],
- "jid_include": True,
- "maxrunning": 1,
- "return_job": False,
- "kwargs": {
- "master": self.opts["master"],
- "connected": True,
- },
- }
- self.schedule.modify_job(
- name=master_event(
- type="alive", master=self.opts["master"]
- ),
- schedule=schedule,
- )
- if (
- self.opts["master_failback"]
- and "master_list" in self.opts
- ):
- if self.opts["master"] != self.opts["master_list"][0]:
- schedule = {
- "function": "status.ping_master",
- "seconds": self.opts[
- "master_failback_interval"
- ],
- "jid_include": True,
- "maxrunning": 1,
- "return_job": False,
- "kwargs": {
- "master": self.opts["master_list"][0]
- },
- }
- self.schedule.modify_job(
- name=master_event(type="failback"),
- schedule=schedule,
- )
- else:
- self.schedule.delete_job(
- name=master_event(type="failback"), persist=True
- )
- else:
- self.restart = True
- self.io_loop.stop()
+ if self.opts["master_failback"] and "master_list" in self.opts:
+ if self.opts["master"] != self.opts["master_list"][0]:
+ schedule = {
+ "function": "status.ping_master",
+ "seconds": self.opts["master_failback_interval"],
+ "jid_include": True,
+ "maxrunning": 1,
+ "return_job": False,
+ "kwargs": {"master": self.opts["master_list"][0]},
+ }
+ self.schedule.modify_job(
+ name=master_event(type="failback"),
+ schedule=schedule,
+ )
+ else:
+ self.schedule.delete_job(
+ name=master_event(type="failback"), persist=True
+ )
+ else:
+ self.restart = True
+ self.io_loop.stop()
elif tag.startswith(master_event(type="connected")):
# handle this event only once. otherwise it will pollute the log
@@ -2870,7 +2843,10 @@ class Minion(MinionBase):
self.connected = True
# modify the __master_alive job to only fire,
# if the connection is lost again
- if self.opts["transport"] != "tcp":
+ if (
+ self.opts["transport"] != "tcp"
+ and self.opts["master_alive_interval"] > 0
+ ):
schedule = {
"function": "status.master",
"seconds": self.opts["master_alive_interval"],
diff --git a/salt/transport/zeromq.py b/salt/transport/zeromq.py
index 7cc6b9987f..89f705190e 100644
--- a/salt/transport/zeromq.py
+++ b/salt/transport/zeromq.py
@@ -1,6 +1,7 @@
"""
Zeromq transport classes
"""
+
import errno
import hashlib
import logging
@@ -211,6 +212,12 @@ class PublishClient(salt.transport.base.PublishClient):
self.master_pub,
)
log.debug("%r connecting to %s", self, self.master_pub)
+ if (
+ hasattr(self, "_monitor")
+ and self._monitor is not None
+ and disconnect_callback is not None
+ ):
+ self._monitor.disconnect_callback = disconnect_callback
self._socket.connect(self.master_pub)
connect_callback(True)
@@ -680,13 +687,21 @@ class ZeroMQSocketMonitor:
log.debug("ZeroMQ event: %s", evt)
if evt["event"] == zmq.EVENT_MONITOR_STOPPED:
self.stop()
+ elif evt["event"] == zmq.EVENT_DISCONNECTED:
+ if (
+ hasattr(self, "disconnect_callback")
+ and self.disconnect_callback is not None
+ ):
+ self.disconnect_callback()
def stop(self):
if self._socket is None:
return
self._socket.disable_monitor()
self._socket = None
- self._monitor_socket = None
+ if self._monitor_socket is not None:
+ self._monitor_socket.close()
+ self._monitor_socket = None
if self._monitor_stream is not None:
self._monitor_stream.close()
self._monitor_stream = None
diff --git a/tests/pytests/scenarios/dns/__init__.py b/tests/pytests/scenarios/dns/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/pytests/scenarios/dns/conftest.py b/tests/pytests/scenarios/dns/conftest.py
new file mode 100644
index 0000000000..5a8850719f
--- /dev/null
+++ b/tests/pytests/scenarios/dns/conftest.py
@@ -0,0 +1,99 @@
+import logging
+import pathlib
+import subprocess
+
+import pytest
+
+log = logging.getLogger(__name__)
+
+
+@pytest.fixture(scope="package")
+def master_alive_interval():
+ return 5
+
+
+class HostsFile:
+ """
+ Simple helper class for tests that need to modify /etc/hosts.
+ """
+
+ def __init__(self, path, orig_text):
+ self._path = path
+ self._orig_text = orig_text
+
+ @property
+ def orig_text(self):
+ return self._orig_text
+
+ def __getattr__(self, key):
+ if key in ["_path", "_orig_text", "orig_text"]:
+ return self.__getattribute__(key)
+ return getattr(self._path, key)
+
+
+@pytest.fixture
+def etc_hosts():
+ hosts = pathlib.Path("/etc/hosts")
+ orig_text = hosts.read_text(encoding="utf-8")
+ hosts = HostsFile(hosts, orig_text)
+ try:
+ yield hosts
+ finally:
+ hosts.write_text(orig_text)
+
+
+@pytest.fixture(scope="package")
+def master(request, salt_factories):
+
+ try:
+ subprocess.check_output(["ip", "addr", "add", "172.16.0.1/32", "dev", "lo"])
+ ip_addr_set = True
+ except subprocess.CalledProcessError:
+ ip_addr_set = False
+
+ config_defaults = {
+ "open_mode": True,
+ "transport": request.config.getoption("--transport"),
+ }
+ config_overrides = {
+ "interface": "0.0.0.0",
+ }
+ factory = salt_factories.salt_master_daemon(
+ "master",
+ defaults=config_defaults,
+ overrides=config_overrides,
+ extra_cli_arguments_after_first_start_failure=["--log-level=info"],
+ )
+ factory.ip_addr_set = ip_addr_set
+ with factory.started(start_timeout=180):
+ yield factory
+
+ try:
+ subprocess.check_output(["ip", "addr", "del", "172.16.0.1/32", "dev", "lo"])
+ except subprocess.CalledProcessError:
+ pass
+
+
+@pytest.fixture(scope="package")
+def salt_cli(master):
+ return master.salt_cli(timeout=180)
+
+
+@pytest.fixture(scope="package")
+def minion(master, master_alive_interval):
+ config_defaults = {
+ "transport": master.config["transport"],
+ }
+ port = master.config["ret_port"]
+ config_overrides = {
+ "master": f"master.local:{port}",
+ "publish_port": master.config["publish_port"],
+ "master_alive_interval": master_alive_interval,
+ }
+ factory = master.salt_minion_daemon(
+ "minion",
+ defaults=config_defaults,
+ overrides=config_overrides,
+ extra_cli_arguments_after_first_start_failure=["--log-level=info"],
+ )
+ return factory
diff --git a/tests/pytests/scenarios/dns/multimaster/conftest.py b/tests/pytests/scenarios/dns/multimaster/conftest.py
new file mode 100644
index 0000000000..3333f812ce
--- /dev/null
+++ b/tests/pytests/scenarios/dns/multimaster/conftest.py
@@ -0,0 +1,124 @@
+import logging
+import os
+import shutil
+import subprocess
+
+import pytest
+
+log = logging.getLogger(__name__)
+
+
+@pytest.fixture(scope="package")
+def salt_mm_master_1(request, salt_factories):
+
+ try:
+ subprocess.check_output(["ip", "addr", "add", "172.16.0.1/32", "dev", "lo"])
+ ip_addr_set = True
+ except subprocess.CalledProcessError:
+ ip_addr_set = False
+
+ config_defaults = {
+ "open_mode": True,
+ "transport": request.config.getoption("--transport"),
+ }
+ config_overrides = {
+ "interface": "0.0.0.0",
+ "master_sign_pubkey": True,
+ }
+ factory = salt_factories.salt_master_daemon(
+ "mm-master-1",
+ defaults=config_defaults,
+ overrides=config_overrides,
+ extra_cli_arguments_after_first_start_failure=["--log-level=info"],
+ )
+ factory.ip_addr_set = ip_addr_set
+ try:
+ with factory.started(start_timeout=180):
+ yield factory
+ finally:
+
+ try:
+ subprocess.check_output(["ip", "addr", "del", "172.16.0.1/32", "dev", "lo"])
+ except subprocess.CalledProcessError:
+ pass
+
+
+@pytest.fixture(scope="package")
+def mm_master_1_salt_cli(salt_mm_master_1):
+ return salt_mm_master_1.salt_cli(timeout=180)
+
+
+@pytest.fixture(scope="package")
+def salt_mm_master_2(salt_factories, salt_mm_master_1):
+ # if salt.utils.platform.is_darwin() or salt.utils.platform.is_freebsd():
+ # subprocess.check_output(["ifconfig", "lo0", "alias", "127.0.0.2", "up"])
+
+ config_defaults = {
+ "open_mode": True,
+ "transport": salt_mm_master_1.config["transport"],
+ }
+ config_overrides = {
+ "interface": "0.0.0.0",
+ "master_sign_pubkey": True,
+ }
+
+ # Use the same ports for both masters, they are binding to different interfaces
+ for key in (
+ "ret_port",
+ "publish_port",
+ ):
+ config_overrides[key] = salt_mm_master_1.config[key] + 1
+ factory = salt_factories.salt_master_daemon(
+ "mm-master-2",
+ defaults=config_defaults,
+ overrides=config_overrides,
+ extra_cli_arguments_after_first_start_failure=["--log-level=info"],
+ )
+
+ # Both masters will share the same signing key pair
+ for keyfile in ("master_sign.pem", "master_sign.pub"):
+ shutil.copyfile(
+ os.path.join(salt_mm_master_1.config["pki_dir"], keyfile),
+ os.path.join(factory.config["pki_dir"], keyfile),
+ )
+ with factory.started(start_timeout=180):
+ yield factory
+
+
+@pytest.fixture(scope="package")
+def mm_master_2_salt_cli(salt_mm_master_2):
+ return salt_mm_master_2.salt_cli(timeout=180)
+
+
+@pytest.fixture(scope="package")
+def salt_mm_minion_1(salt_mm_master_1, salt_mm_master_2, master_alive_interval):
+ config_defaults = {
+ "transport": salt_mm_master_1.config["transport"],
+ }
+
+ mm_master_1_port = salt_mm_master_1.config["ret_port"]
+ mm_master_2_port = salt_mm_master_2.config["ret_port"]
+ config_overrides = {
+ "master": [
+ f"master1.local:{mm_master_1_port}",
+ f"master2.local:{mm_master_2_port}",
+ ],
+ "publish_port": salt_mm_master_1.config["publish_port"],
+ "master_alive_interval": master_alive_interval,
+ "master_tries": -1,
+ "verify_master_pubkey_sign": True,
+ "retry_dns": True,
+ }
+ factory = salt_mm_master_1.salt_minion_daemon(
+ "mm-minion-1",
+ defaults=config_defaults,
+ overrides=config_overrides,
+ extra_cli_arguments_after_first_start_failure=["--log-level=info"],
+ )
+ # Need to grab the public signing key from the master, either will do
+ shutil.copyfile(
+ os.path.join(salt_mm_master_1.config["pki_dir"], "master_sign.pub"),
+ os.path.join(factory.config["pki_dir"], "master_sign.pub"),
+ )
+ # with factory.started(start_timeout=180):
+ yield factory
diff --git a/tests/pytests/scenarios/dns/multimaster/test_dns.py b/tests/pytests/scenarios/dns/multimaster/test_dns.py
new file mode 100644
index 0000000000..fafb30c12e
--- /dev/null
+++ b/tests/pytests/scenarios/dns/multimaster/test_dns.py
@@ -0,0 +1,54 @@
+import logging
+import subprocess
+import time
+
+import pytest
+
+log = logging.getLogger(__name__)
+
+
+@pytest.mark.skip_unless_on_linux
+@pytest.mark.skip_if_not_root
+def test_multimaster_dns(
+ salt_mm_master_1,
+ salt_mm_minion_1,
+ mm_master_1_salt_cli,
+ etc_hosts,
+ caplog,
+ master_alive_interval,
+):
+ """
+ Verify a minion configured with multimaster hot/hot will pick up a master's
+ dns change if it's been disconnected.
+ """
+
+ if not salt_mm_master_1.ip_addr_set:
+ pytest.skip("Unable to set additional IP address for master1")
+
+ etc_hosts.write_text(
+ f"{etc_hosts.orig_text}\n172.16.0.1 master1.local master2.local"
+ )
+
+ log.info("Added hosts record for master1.local and master2.local")
+
+ with salt_mm_minion_1.started(start_timeout=180):
+ with caplog.at_level(logging.INFO):
+ ret = mm_master_1_salt_cli.run("test.ping", minion_tgt="mm-minion-1")
+ assert ret.returncode == 0
+ etc_hosts.write_text(
+ f"{etc_hosts.orig_text}\n127.0.0.1 master1.local master2.local"
+ )
+ log.info("Changed hosts record for master1.local and master2.local")
+ subprocess.check_output(["ip", "addr", "del", "172.16.0.1/32", "dev", "lo"])
+ log.info("Removed secondary master IP address.")
+ # Wait for the minion's master_alive_interval, adding a second for
+ # reliablity.
+ time.sleep(master_alive_interval + 1)
+ assert (
+ "Master ip address changed from 172.16.0.1 to 127.0.0.1" in caplog.text
+ )
+ ret = mm_master_1_salt_cli.run("test.ping", minion_tgt="mm-minion-1")
+ assert ret.returncode == 0
+ assert (
+ "Master ip address changed from 172.16.0.1 to 127.0.0.1" in caplog.text
+ )
diff --git a/tests/pytests/scenarios/dns/test_dns.py b/tests/pytests/scenarios/dns/test_dns.py
new file mode 100644
index 0000000000..cd33f0e7f0
--- /dev/null
+++ b/tests/pytests/scenarios/dns/test_dns.py
@@ -0,0 +1,37 @@
+import logging
+import subprocess
+import time
+
+import pytest
+
+log = logging.getLogger(__name__)
+
+
+@pytest.mark.skip_unless_on_linux
+@pytest.mark.skip_if_not_root
+def test_dns_change(master, minion, salt_cli, etc_hosts, caplog, master_alive_interval):
+ """
+ Verify a minion will pick up a master's dns change if it's been disconnected.
+ """
+
+ if not master.ip_addr_set:
+ pytest.skip("Unable to set additional IP address for master")
+
+ etc_hosts.write_text(f"{etc_hosts.orig_text}\n172.16.0.1 master.local")
+
+ with minion.started(start_timeout=180):
+ with caplog.at_level(logging.INFO):
+ ret = salt_cli.run("test.ping", minion_tgt="minion")
+ assert ret.returncode == 0
+ etc_hosts.write_text(f"{etc_hosts.orig_text}\n127.0.0.1 master.local")
+ log.info("Changed hosts record for master1.local and master2.local")
+ subprocess.check_output(["ip", "addr", "del", "172.16.0.1/32", "dev", "lo"])
+ log.info("Removed secondary master IP address.")
+ # Wait for the minion's master_alive_interval, adding a second for
+ # reliablity.
+ time.sleep(master_alive_interval + 1)
+ assert (
+ "Master ip address changed from 172.16.0.1 to 127.0.0.1" in caplog.text
+ )
+ ret = salt_cli.run("test.ping", minion_tgt="minion")
+ assert ret.returncode == 0
diff --git a/tests/pytests/scenarios/failover/multimaster/test_failover_master.py b/tests/pytests/scenarios/failover/multimaster/test_failover_master.py
index 9f6251a4d6..ebb2899ff0 100644
--- a/tests/pytests/scenarios/failover/multimaster/test_failover_master.py
+++ b/tests/pytests/scenarios/failover/multimaster/test_failover_master.py
@@ -162,10 +162,6 @@ def test_minions_alive_with_no_master(
"""
Make sure the minions stay alive after all masters have stopped.
"""
- if grains["os_family"] == "Debian" and grains["osmajorrelease"] == 9:
- pytest.skip(
- "Skipping on Debian 9 until flaky issues resolved. See issue #61749"
- )
start_time = time.time()
with salt_mm_failover_master_1.stopped():
with salt_mm_failover_master_2.stopped():
diff --git a/tests/pytests/unit/test_minion.py b/tests/pytests/unit/test_minion.py
index a9e91742a2..017c28d163 100644
--- a/tests/pytests/unit/test_minion.py
+++ b/tests/pytests/unit/test_minion.py
@@ -884,6 +884,8 @@ async def test_master_type_failover(minion_opts):
assert opts["master"] == "master2"
return MockPubChannel()
+ minion_opts["master_tries"] = 1
+
with patch("salt.minion.resolve_dns", mock_resolve_dns), patch(
"salt.channel.client.AsyncPubChannel.factory", mock_channel_factory
), patch("salt.loader.grains", MagicMock(return_value=[])):
--
2.47.0

View File

@ -0,0 +1,65 @@
From 7217fccdce5df73fda1a8378dc7120642ffe8181 Mon Sep 17 00:00:00 2001
From: Victor Zhestkov <vzhestkov@suse.com>
Date: Mon, 16 Dec 2024 15:31:26 +0300
Subject: [PATCH] Revert setting SELinux context for minion service
(bsc#1233667)
This reverts commit d933c8f0795fdada84a01a2cc754586fa720993d.
---
pkg/common/salt-minion.service | 1 -
pkg/old/deb/salt-minion.service | 1 -
pkg/old/suse/salt-minion.service | 1 -
pkg/old/suse/salt-minion.service.rhel7 | 1 -
4 files changed, 4 deletions(-)
diff --git a/pkg/common/salt-minion.service b/pkg/common/salt-minion.service
index 696d0263c3..69aff18c58 100644
--- a/pkg/common/salt-minion.service
+++ b/pkg/common/salt-minion.service
@@ -9,7 +9,6 @@ Type=notify
NotifyAccess=all
LimitNOFILE=8192
ExecStart=/usr/bin/salt-minion
-SELinuxContext=system_u:system_r:unconfined_t:s0
[Install]
WantedBy=multi-user.target
diff --git a/pkg/old/deb/salt-minion.service b/pkg/old/deb/salt-minion.service
index b0ad82c133..7e6cf14654 100644
--- a/pkg/old/deb/salt-minion.service
+++ b/pkg/old/deb/salt-minion.service
@@ -8,7 +8,6 @@ KillMode=process
NotifyAccess=all
LimitNOFILE=8192
ExecStart=/usr/bin/salt-minion
-SELinuxContext=system_u:system_r:unconfined_t:s0
[Install]
WantedBy=multi-user.target
diff --git a/pkg/old/suse/salt-minion.service b/pkg/old/suse/salt-minion.service
index b99ef06352..12f28314cb 100644
--- a/pkg/old/suse/salt-minion.service
+++ b/pkg/old/suse/salt-minion.service
@@ -10,7 +10,6 @@ ExecStart=/usr/bin/salt-minion
KillMode=process
Restart=on-failure
RestartSec=15
-SELinuxContext=system_u:system_r:unconfined_t:s0
[Install]
WantedBy=multi-user.target
diff --git a/pkg/old/suse/salt-minion.service.rhel7 b/pkg/old/suse/salt-minion.service.rhel7
index 92cc66d32f..6917267714 100644
--- a/pkg/old/suse/salt-minion.service.rhel7
+++ b/pkg/old/suse/salt-minion.service.rhel7
@@ -9,7 +9,6 @@ ExecStart=/usr/bin/salt-minion
KillMode=process
Restart=on-failure
RestartSec=15
-SELinuxContext=system_u:system_r:unconfined_t:s0
[Install]
WantedBy=multi-user.target
--
2.47.1

View File

@ -1,3 +1,29 @@
-------------------------------------------------------------------
Thu Jan 9 12:57:12 UTC 2025 - Pablo Suárez Hernández <psuarezhernandez@suse.com>
- Revert setting SELinux context for minion service (bsc#1233667)
- Remove System V init support
* Make systemd the only supported init system by removing System V init
and insserv references
* Ensure package builds with no init system dependencies if built
without systemd (for example for use in containers)
* Apply some spec-cleaner suggestions (update copyright year, sort
requirements, adjust spacing)
- Added:
* revert-setting-selinux-context-for-minion-service-bs.patch
-------------------------------------------------------------------
Tue Nov 26 14:53:34 UTC 2024 - Victor Zhestkov <vzhestkov@suse.com>
- Fix the condition of alternatives for Tumbleweed and Leap 16
- Use update-alternatives for salt-call and fix builing on EL8
- Build all python bindings for all flavors
- Make minion reconnecting on changing master IP (bsc#1228182)
- Added:
* make-minion-reconnecting-on-changing-master-ip-bsc-1.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Thu Oct 17 14:02:57 UTC 2024 - Marek Czernek <marek.czernek@suse.com> Thu Oct 17 14:02:57 UTC 2024 - Marek Czernek <marek.czernek@suse.com>

552
salt.spec
View File

@ -1,7 +1,7 @@
# #
# spec file for package salt # spec file for package salt
# #
# Copyright (c) 2021 SUSE LLC # Copyright (c) 2024 SUSE LLC
# #
# All modifications and additions to the file contributed by third parties # All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed # remain the property of their copyright owners, unless otherwise agreed
@ -12,10 +12,21 @@
# license that conforms to the Open Source Definition (Version 1.9) # license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative. # published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/ # Please submit bugfixes or comments via https://bugs.opensuse.org/
# #
%global debug_package %{nil} %global debug_package %{nil}
%if 0%{?suse_version} > 1500
%bcond_without libalternatives
%else
%bcond_with libalternatives
%endif
%if 0%{?sle_version} >= 150400 || 0%{?suse_version} >= 1600
%define _alternatives 1
%endif
%global flavor @BUILD_FLAVOR@%{nil} %global flavor @BUILD_FLAVOR@%{nil}
%if "%{flavor}" == "testsuite" %if "%{flavor}" == "testsuite"
%define psuffix -test %define psuffix -test
@ -28,7 +39,6 @@
%else %else
%bcond_with systemd %bcond_with systemd
%endif %endif
%{!?python3_sitelib: %global python3_sitelib %(python3 -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
%if 0%{?suse_version} > 1110 %if 0%{?suse_version} > 1110
%bcond_without bash_completion %bcond_without bash_completion
%bcond_without fish_completion %bcond_without fish_completion
@ -41,13 +51,41 @@
%bcond_without docs %bcond_without docs
%bcond_with builddocs %bcond_with builddocs
%if %{without systemd}
%define service_del_preun echo %{*}
%endif
%{?sle15allpythons}
%define skip_python2 1
%if 0%{?rhel} == 8 || (0%{?suse_version} == 1500 && 0%{?sle_version} < 150400)
%define __python3_bin_suffix 3.6
%if 0%{?rhel} == 8
%define __python3 /usr/libexec/platform-python
%else
%define __python3 /usr/bin/python3
%endif
%define python_module() python3-%**
%define python_files() -n python3-%1
%define python_subpackages %{nil}
%define python_sitelib %python3_sitelib
%define python_expand(+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=) %{lua: \
local args = rpm.expand("%**")\
local python_bin = rpm.expand("%__python3")\
local python_bin_suffix = rpm.expand("%__python3_bin_suffix")\
args = args:gsub("$python_bin_suffix", python_bin_suffix)\
args = args:gsub("$python_sitelib", "python3_sitelib")\
args = args:gsub("$python", python_bin)\
print(rpm.expand(args .. "\\n"))\
}
%define _nosinglespec 1
%endif
Name: salt%{psuffix} Name: salt%{psuffix}
Version: 3006.0 Version: 3006.0
Release: 0 Release: 0
Summary: A parallel remote execution system Summary: A parallel remote execution system
License: Apache-2.0 License: Apache-2.0
Group: System/Management Group: System/Management
Url: https://saltproject.io/ URL: https://saltproject.io/
Source: v%{version}.tar.gz Source: v%{version}.tar.gz
Source1: README.SUSE Source1: README.SUSE
Source2: salt-tmpfiles.d Source2: salt-tmpfiles.d
@ -454,6 +492,12 @@ Patch144: fix-x509-private-key-tests-and-test_suse-on-sle12-68.patch
Patch145: enhance-cleanup-mechanism-after-salt-bundle-upgrade-.patch Patch145: enhance-cleanup-mechanism-after-salt-bundle-upgrade-.patch
# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/commit/9683260d61668da8559ecde6caf63a52fedd8790 # PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/commit/9683260d61668da8559ecde6caf63a52fedd8790
Patch146: handle-logger-flushing-already-closed-file-686.patch Patch146: handle-logger-flushing-already-closed-file-686.patch
# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/66422
# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/66757
# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/66760
Patch147: make-minion-reconnecting-on-changing-master-ip-bsc-1.patch
# PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/690
Patch148: revert-setting-selinux-context-for-minion-service-bs.patch
### IMPORTANT: The line below is used as a snippet marker. Do not touch it. ### IMPORTANT: The line below is used as a snippet marker. Do not touch it.
### SALT PATCHES LIST END ### SALT PATCHES LIST END
@ -464,7 +508,11 @@ BuildRequires: logrotate
BuildRequires: fdupes BuildRequires: fdupes
%endif %endif
%if 0%{?_alternatives}
Requires: %{name}-call = %{version}-%{release}
%else
Requires: python3-%{name} = %{version}-%{release} Requires: python3-%{name} = %{version}-%{release}
%endif
Obsoletes: python2-%{name} Obsoletes: python2-%{name}
Requires(pre): %{_sbindir}/groupadd Requires(pre): %{_sbindir}/groupadd
@ -473,7 +521,6 @@ Provides: user(salt)
Provides: group(salt) Provides: group(salt)
%if 0%{?suse_version} %if 0%{?suse_version}
Requires(pre): %fillup_prereq
Requires(pre): shadow Requires(pre): shadow
%endif %endif
@ -499,10 +546,6 @@ Requires: iproute
%if %{with systemd} %if %{with systemd}
BuildRequires: pkgconfig(systemd) BuildRequires: pkgconfig(systemd)
%{?systemd_ordering} %{?systemd_ordering}
%else
%if 0%{?suse_version}
Requires(pre): %insserv_prereq
%endif
%endif %endif
%if %{with fish_completion} %if %{with fish_completion}
@ -526,6 +569,9 @@ BuildRequires: zsh
BuildRequires: yum BuildRequires: yum
%endif %endif
%define python_subpackage_only 1
%python_subpackages
%description %description
Salt is a distributed remote execution system used to execute commands and Salt is a distributed remote execution system used to execute commands and
query data. It was developed in order to bring the best solutions found in query data. It was developed in order to bring the best solutions found in
@ -536,7 +582,11 @@ servers, handle them quickly and through a simple and manageable interface.
%if "%{flavor}" != "testsuite" %if "%{flavor}" != "testsuite"
%if 0%{?_nosinglespec}
%package -n python3-salt %package -n python3-salt
%else
%package -n python-salt
%endif
Summary: python3 library for salt Summary: python3 library for salt
Group: System/Management Group: System/Management
Requires: %{name} = %{version}-%{release} Requires: %{name} = %{version}-%{release}
@ -544,62 +594,76 @@ BuildRequires: python-rpm-macros
%if 0%{?rhel} == 8 %if 0%{?rhel} == 8
BuildRequires: platform-python BuildRequires: platform-python
%else %else
BuildRequires: python3 BuildRequires: %{python_module base}
%endif %endif
BuildRequires: python3-devel BuildRequires: %{python_module setuptools}
BuildRequires: python3-setuptools
# requirements/base.txt # requirements/base.txt
%if 0%{?rhel} || 0%{?fedora} %if 0%{?rhel} || 0%{?fedora}
BuildRequires: python3-jinja2 BuildRequires: python3-jinja2
BuildRequires: python3-m2crypto
BuildRequires: python3-markupsafe BuildRequires: python3-markupsafe
BuildRequires: python3-msgpack > 0.3 BuildRequires: python3-msgpack > 0.3
BuildRequires: python3-zmq >= 2.2.0 BuildRequires: python3-zmq >= 2.2.0
BuildRequires: python3-m2crypto
%else %else
BuildRequires: python3-Jinja2 BuildRequires: %{python_module Jinja2}
BuildRequires: python3-MarkupSafe BuildRequires: %{python_module MarkupSafe}
BuildRequires: python3-msgpack-python > 0.3 BuildRequires: %{python_module msgpack-python > 0.3}
BuildRequires: python3-pyzmq >= 2.2.0 BuildRequires: %{python_module pyzmq > 2.2.0}
%if 0%{?suse_version} >= 1500 %if 0%{?suse_version} >= 1500
BuildRequires: python3-M2Crypto BuildRequires: %{python_module M2Crypto}
%else %else
BuildRequires: python3-pycrypto >= 2.6.1 BuildRequires: %{python_module pycrypto >= 2.6.1}
%endif %endif
%endif %endif
BuildRequires: python3-PyYAML BuildRequires: %{python_module PyYAML}
BuildRequires: python3-psutil BuildRequires: %{python_module psutil}
BuildRequires: python3-requests >= 1.0.0 BuildRequires: %{python_module requests >= 1.0.0}
BuildRequires: python3-distro BuildRequires: %{python_module distro}
BuildRequires: python3-looseversion BuildRequires: %{python_module looseversion}
BuildRequires: python3-packaging BuildRequires: %{python_module packaging}
BuildRequires: python3-contextvars BuildRequires: %{python_module contextvars}
# requirements/zeromq.txt # requirements/zeromq.txt
%if %{with test} %if %{with test}
BuildRequires: python3-boto >= 2.32.1 BuildRequires: %{python_module boto >= 2.32.1}
BuildRequires: %{python3-mock if %python-base < 3.8} BuildRequires: %{python_module mock if %python-base < 3.8}
BuildRequires: python3-moto >= 0.3.6 BuildRequires: %{python_module moto >= 0.3.6}
BuildRequires: python3-pip BuildRequires: %{python_module pip}
BuildRequires: python3-salt-testing >= 2015.2.16 BuildRequires: %{python_module salt-testing >= 2015.2.16}
BuildRequires: python3-unittest2 BuildRequires: %{python_module unittest2}
BuildRequires: python3-xml BuildRequires: %{python_module xml}
%endif %endif
%if %{with builddocs} %if %{with builddocs}
BuildRequires: python3-sphinx BuildRequires: %{python_module sphinx}
%endif %endif
%if 0%{?rhel} == 8 %if 0%{?rhel} == 8
Requires: platform-python Requires: platform-python
%else %else
Requires: python3 %if 0%{?_nosinglespec}
Requires: %{python_module base}
%else
Requires: python-base
%endif %endif
%endif
%if 0%{?_alternatives}
%if %{with libalternatives}
Requires: alts
BuildRequires: alts
%else
Requires(post): update-alternatives
Requires(postun):update-alternatives
%endif
%endif
# requirements/base.txt # requirements/base.txt
%if 0%{?rhel} || 0%{?fedora} %if 0%{?rhel} || 0%{?fedora}
Requires: python3-jinja2 Requires: python3-jinja2
Requires: yum Requires: python3-m2crypto
Requires: python3-markupsafe Requires: python3-markupsafe
Requires: python3-msgpack > 0.3 Requires: python3-msgpack > 0.3
Requires: python3-m2crypto
Requires: python3-zmq >= 2.2.0 Requires: python3-zmq >= 2.2.0
Requires: yum
%if 0%{?rhel} == 8 || 0%{?fedora} >= 30 %if 0%{?rhel} == 8 || 0%{?fedora} >= 30
Requires: dnf Requires: dnf
@ -608,42 +672,78 @@ Requires: dnf
Requires: yum-plugin-security Requires: yum-plugin-security
%endif %endif
%else # SUSE %else # SUSE
Requires: python3-Jinja2 %if 0%{?_nosinglespec}
Requires: python3-MarkupSafe Requires: %{python_module Jinja2}
Requires: python3-msgpack-python > 0.3 Requires: %{python_module MarkupSafe}
Requires: %{python_module msgpack-python > 0.3}
%if 0%{?suse_version} >= 1500 %if 0%{?suse_version} >= 1500
Requires: python3-M2Crypto Requires: %{python_module M2Crypto}
%else %else
Requires: python3-pycrypto >= 2.6.1 Requires: %{python_module pycrypto >= 2.6.1}
%endif
Requires: %{python_module pyzmq >= 2.2.0}
%else
Requires: python-Jinja2
Requires: python-MarkupSafe
Requires: python-msgpack-python > 0.3
%if 0%{?suse_version} >= 1500
Requires: python-M2Crypto
%else
Requires: python-pycrypto >= 2.6.1
%endif
Requires: python-pyzmq >= 2.2.0
%endif %endif
Requires: python3-pyzmq >= 2.2.0
%endif # end of RHEL / SUSE specific section %endif # end of RHEL / SUSE specific section
Requires: python3-jmespath %if 0%{?_nosinglespec}
Requires: python3-PyYAML Recommends: %{python_module jmespath}
Requires: python3-psutil Requires: %{python_module PyYAML}
Requires: python3-requests >= 1.0.0 Requires: %{python_module psutil}
Requires: python3-distro Requires: %{python_module requests >= 1.0.0}
Requires: python3-looseversion Requires: %{python_module distro}
Requires: python3-packaging Requires: %{python_module looseversion}
Requires: python3-contextvars Requires: %{python_module packaging}
Requires: %{python_module contextvars}
%if 0%{?suse_version} %if 0%{?suse_version}
# required for zypper.py # required for zypper.py
Requires: python3-rpm Requires: %{python_module rpm}
Requires(pre): libzypp(plugin:system) >= 0
Requires: python3-zypp-plugin
# requirements/opt.txt (not all) # requirements/opt.txt (not all)
# Suggests: python-MySQL-python ## Disabled for now, originally Recommended # Suggests: python-MySQL-python ## Disabled for now, originally Recommended
Suggests: python3-timelib Suggests: %{python_module timelib}
Suggests: python3-gnupg Suggests: %{python_module gnupg}
%endif
%else
Recommends: python-jmespath
Requires: python-PyYAML
Requires: python-psutil
Requires: python-requests >= 1.0.0
Requires: python-distro
Requires: python-looseversion
Requires: python-packaging
Requires: python-contextvars
%if 0%{?suse_version}
# required for zypper.py
Requires: python-rpm
# requirements/opt.txt (not all)
# Suggests: python-MySQL-python ## Disabled for now, originally Recommended
Suggests: python-timelib
Suggests: python-gnupg
# requirements/zeromq.txt # requirements/zeromq.txt
%endif %endif
%endif
# #
%if 0%{?suse_version} %if 0%{?suse_version}
# python-xml is part of python-base in all rhel versions # python-xml is part of python-base in all rhel versions
Requires: python3-xml %if 0%{?_nosinglespec}
Suggests: python3-Mako Requires: %{python_module xml}
Recommends: python3-netaddr Suggests: %{python_module Mako}
Recommends: python3-pyinotify Recommends: %{python_module netaddr}
Recommends: %{python_module pyinotify}
%else
Requires: python-xml
Suggests: python-Mako
Recommends: python-netaddr
Recommends: python-pyinotify
%endif
%endif %endif
# Required by Salt modules # Required by Salt modules
@ -653,9 +753,19 @@ Requires: file
Recommends: man Recommends: man
Recommends: python3-passlib Recommends: python3-passlib
Provides: bundled(python3-tornado) = 4.5.3 %if 0%{?_nosinglespec}
Provides: bundled(%{python_module tornado}) = 4.5.3
%else
Provides: bundled(python-tornado) = 4.5.3
%endif
Provides: %{name}-call = %{version}-%{release}
%if 0%{?_nosinglespec}
%description -n python3-salt %description -n python3-salt
%else
%description -n python-salt
%endif
Python3 specific files for salt Python3 specific files for salt
%package api %package api
@ -717,13 +827,6 @@ Requires: pmtools
%if %{with systemd} %if %{with systemd}
%{?systemd_requires} %{?systemd_requires}
BuildRequires: systemd BuildRequires: systemd
%else
%if 0%{?suse_version}
Requires(pre): %insserv_prereq
%endif
%endif
%if 0%{?suse_version}
Requires(pre): %fillup_prereq
%endif %endif
%description master %description master
@ -738,16 +841,13 @@ Requires: %{name} = %{version}-%{release}
%if 0%{?suse_version} > 1500 || 0%{?sle_version} > 150000 %if 0%{?suse_version} > 1500 || 0%{?sle_version} > 150000
Requires: (%{name}-transactional-update = %{version}-%{release} if read-only-root-fs) Requires: (%{name}-transactional-update = %{version}-%{release} if read-only-root-fs)
%endif %endif
%if 0%{?suse_version}
Requires: python3-zypp-plugin
Requires(pre): libzypp(plugin:system) >= 0
%endif
%if %{with systemd} %if %{with systemd}
%{?systemd_requires} %{?systemd_requires}
%else
%if 0%{?suse_version}
Requires(pre): %insserv_prereq
%endif
%endif
%if 0%{?suse_version}
Requires(pre): %fillup_prereq
%endif %endif
%description minion %description minion
@ -760,13 +860,6 @@ Group: System/Management
Requires: %{name} = %{version}-%{release} Requires: %{name} = %{version}-%{release}
%if %{with systemd} %if %{with systemd}
%{?systemd_requires} %{?systemd_requires}
%else
%if 0%{?suse_version}
Requires(pre): %insserv_prereq
%endif
%endif
%if 0%{?suse_version}
Requires(pre): %fillup_prereq
%endif %endif
%description proxy %description proxy
@ -776,7 +869,6 @@ Examples include network gear that has an API but runs a proprietary OS,
devices with limited CPU or memory, or devices that could run a minion, but for devices with limited CPU or memory, or devices that could run a minion, but for
security reasons, will not. security reasons, will not.
%package syndic %package syndic
Summary: The syndic component for saltstack Summary: The syndic component for saltstack
Group: System/Management Group: System/Management
@ -784,13 +876,6 @@ Requires: %{name} = %{version}-%{release}
Requires: %{name}-master = %{version}-%{release} Requires: %{name}-master = %{version}-%{release}
%if %{with systemd} %if %{with systemd}
%{?systemd_requires} %{?systemd_requires}
%else
%if 0%{?suse_version}
Requires(pre): %insserv_prereq
%endif
%endif
%if 0%{?suse_version}
Requires(pre): %fillup_prereq
%endif %endif
%description syndic %description syndic
@ -808,13 +893,6 @@ Recommends: sshpass
%endif %endif
%if %{with systemd} %if %{with systemd}
%{?systemd_requires} %{?systemd_requires}
%else
%if 0%{?suse_version}
Requires(pre): %insserv_prereq
%endif
%endif
%if 0%{?suse_version}
Requires(pre): %fillup_prereq
%endif %endif
%description ssh %description ssh
@ -891,44 +969,73 @@ list of active executors. This package add the configuration file.
%if "%{flavor}" == "testsuite" %if "%{flavor}" == "testsuite"
%package -n python3-salt-testsuite %if 0%{?_nosinglespec}
%package -n %{python_module salt-testsuite}
%else
%package -n python-salt-testsuite
%endif
Summary: Unit and integration tests for Salt Summary: Unit and integration tests for Salt
%if 0%{?rhel} == 8 %if 0%{?rhel} == 8
BuildRequires: platform-python BuildRequires: platform-python
%else %else
BuildRequires: python3 BuildRequires: %{python_module base}
%endif %endif
BuildRequires: python3-devel BuildRequires: %{python_module setuptools}
BuildRequires: python3-setuptools
Requires: salt = %{version} Requires: salt = %{version}
Recommends: python3-CherryPy %if 0%{?_nosinglespec}
Requires: python3-Genshi Recommends: %{python_module CherryPy}
Requires: python3-Mako Requires: %{python_module Genshi}
Requires: %{python_module Mako}
%if !0%{?suse_version} > 1600 || 0%{?centos} %if !0%{?suse_version} > 1600 || 0%{?centos}
Requires: python3-boto Requires: %{python_module boto}
%endif %endif
Requires: python3-boto3 Requires: %{python_module boto3}
Requires: python3-docker Requires: %{python_module docker}
%if 0%{?suse_version} < 1600 %if 0%{?suse_version} < 1600
Requires: python3-mock Requires: %{python_module mock}
%endif
Requires: %{python_module pygit2}
Requires: %{python_module pytest >= 7.0.1}
Requires: %{python_module pytest-httpserver}
Requires: %{python_module pytest-salt-factories >= 1.0.0~rc21}
Requires: %{python_module pytest-subtests}
Requires: %{python_module testinfra}
Requires: %{python_module yamllint}
Requires: %{python_module pip}
%else
Recommends: python-CherryPy
Requires: python-Genshi
Requires: python-Mako
%if !0%{?suse_version} > 1600 || 0%{?centos}
Requires: python-boto
%endif
Requires: python-boto3
Requires: python-docker
%if 0%{?suse_version} < 1600
Requires: python-mock
%endif
Requires: python-pygit2
Requires: python-pytest >= 7.0.1
Requires: python-pytest-httpserver
Requires: python-pytest-salt-factories >= 1.0.0~rc21
Requires: python-pytest-subtests
Requires: python-testinfra
Requires: python-yamllint
Requires: python-pip
%endif %endif
Requires: python3-pygit2
Requires: python3-pytest >= 7.0.1
Requires: python3-pytest-httpserver
Requires: python3-pytest-salt-factories >= 1.0.0~rc21
Requires: python3-pytest-subtests
Requires: python3-testinfra
Requires: python3-yamllint
Requires: python3-pip
Requires: docker Requires: docker
Requires: openssh Requires: openssh
Requires: git Requires: git
Obsoletes: %{name}-tests Obsoletes: %{name}-tests
%if 0%{?_nosinglespec}
%description -n python3-salt-testsuite %description -n python3-salt-testsuite
%else
%description -n python-salt-testsuite
%endif
Collection of unit, functional, and integration tests for %{name}. Collection of unit, functional, and integration tests for %{name}.
%endif %endif
@ -949,8 +1056,10 @@ cp %{S:6} .
%if 0%{?fedora} || 0%{?rhel} %if 0%{?fedora} || 0%{?rhel}
export PATH=/usr/bin:$PATH export PATH=/usr/bin:$PATH
%endif %endif
python3 setup.py --with-salt-version=%{version} --salt-transport=both build %{python_expand #
mv build _build.python3 $python setup.py --with-salt-version=%{version} --salt-transport=both build
mv build _build.%{$python_bin_suffix}
}
%if %{with docs} && %{without builddocs} %if %{with docs} && %{without builddocs}
# extract docs from the tarball # extract docs from the tarball
@ -970,16 +1079,18 @@ cd doc && make html && rm _build/html/.buildinfo && rm _build/html/_images/proxy
%install %install
%if "%{flavor}" != "testsuite" %if "%{flavor}" != "testsuite"
mv _build.python3 build %{python_expand #
python3 setup.py --salt-transport=both install --prefix=%{_prefix} --root=%{buildroot} mv _build.%{$python_bin_suffix} build
mv build _build.python3 $python setup.py --salt-transport=both install --prefix=%{_prefix} --root=%{buildroot}
mv build _build.%{$python_bin_suffix}
DEF_PYPATH=_build.python3/scripts-*/ DEF_PYPATH=_build.%{$python_bin_suffix}/scripts-*/
rm -f %{buildroot}%{_bindir}/* rm -f %{buildroot}%{_bindir}/*
for script in $DEF_PYPATH/*; do for script in $DEF_PYPATH/*; do
install -m 0755 $script %{buildroot}%{_bindir} install -m 0755 $script %{buildroot}%{_bindir}
done done
}
## create missing directories ## create missing directories
install -Dd -m 0750 %{buildroot}%{_localstatedir}/cache/salt/cloud install -Dd -m 0750 %{buildroot}%{_localstatedir}/cache/salt/cloud
@ -1015,18 +1126,22 @@ install -Dd -m 0755 %{buildroot}%{_sbindir}
install -Dd -m 0755 %{buildroot}%{_sysconfdir}/logrotate.d/ install -Dd -m 0755 %{buildroot}%{_sysconfdir}/logrotate.d/
# Install salt-support profiles # Install salt-support profiles
install -Dpm 0644 salt/cli/support/profiles/* %{buildroot}%{python3_sitelib}/salt/cli/support/profiles %{python_expand #
install -Dpm 0644 salt/cli/support/profiles/* %{buildroot}%{$python_sitelib}/salt/cli/support/profiles
}
%endif %endif
%if "%{flavor}" == "testsuite" %if "%{flavor}" == "testsuite"
# Install Salt tests # Install Salt tests
install -Dd %{buildroot}%{python3_sitelib}/salt-testsuite %{python_expand #
cp -a tests %{buildroot}%{python3_sitelib}/salt-testsuite/ install -Dd %{buildroot}%{$python_sitelib}/salt-testsuite
cp -a tests %{buildroot}%{$python_sitelib}/salt-testsuite/
# Remove runtests.py which is not used as deprecated method of running the tests # Remove runtests.py which is not used as deprecated method of running the tests
rm %{buildroot}%{python3_sitelib}/salt-testsuite/tests/runtests.py rm %{buildroot}%{$python_sitelib}/salt-testsuite/tests/runtests.py
# Copy conf files to the testsuite as they are used by the tests # Copy conf files to the testsuite as they are used by the tests
cp -a conf %{buildroot}%{python3_sitelib}/salt-testsuite/ cp -a conf %{buildroot}%{$python_sitelib}/salt-testsuite/
}
%endif %endif
%if "%{flavor}" != "testsuite" %if "%{flavor}" != "testsuite"
@ -1074,22 +1189,6 @@ ln -s service %{buildroot}%{_sbindir}/rcsalt-syndic
ln -s service %{buildroot}%{_sbindir}/rcsalt-minion ln -s service %{buildroot}%{_sbindir}/rcsalt-minion
ln -s service %{buildroot}%{_sbindir}/rcsalt-api ln -s service %{buildroot}%{_sbindir}/rcsalt-api
install -Dpm 644 %{S:2} %{buildroot}/usr/lib/tmpfiles.d/salt.conf install -Dpm 644 %{S:2} %{buildroot}/usr/lib/tmpfiles.d/salt.conf
%else
mkdir -p %{buildroot}%{_initddir}
## install init scripts
install -Dpm 0755 pkg/old/suse/salt-master %{buildroot}%{_initddir}/salt-master
install -Dpm 0755 pkg/old/suse/salt-syndic %{buildroot}%{_initddir}/salt-syndic
install -Dpm 0755 pkg/old/suse/salt-minion %{buildroot}%{_initddir}/salt-minion
install -Dpm 0755 pkg/old/suse/salt-api %{buildroot}%{_initddir}/salt-api
ln -sf %{_initddir}/salt-master %{buildroot}%{_sbindir}/rcsalt-master
ln -sf %{_initddir}/salt-syndic %{buildroot}%{_sbindir}/rcsalt-syndic
ln -sf %{_initddir}/salt-minion %{buildroot}%{_sbindir}/rcsalt-minion
ln -sf %{_initddir}/salt-api %{buildroot}%{_sbindir}/rcsalt-api
%endif
## Install sysV salt-minion watchdog for SLES11 and RHEL6
%if 0%{?rhel} == 6 || 0%{?suse_version} == 1110
install -Dpm 0755 scripts/suse/watchdog/salt-daemon-watcher %{buildroot}%{_bindir}/salt-daemon-watcher
%endif %endif
# #
@ -1137,9 +1236,20 @@ install -Dpm 0640 conf/suse/standalone-formulas-configuration.conf %{buildroot}%
%if 0%{?suse_version} > 1020 %if 0%{?suse_version} > 1020
%fdupes %{buildroot}%{_docdir} %fdupes %{buildroot}%{_docdir}
%fdupes %{buildroot}%{python3_sitelib} %python_expand %fdupes %{buildroot}%{$python_sitelib}
%endif %endif
%if 0%{?_alternatives}
%python_clone -a %{buildroot}%{_bindir}/salt-call
%endif
%endif
%check
%if %{with test}
%{python_expand #
$python setup.py test --runtests-opts=-u
}
%endif %endif
%if "%{flavor}" != "testsuite" %if "%{flavor}" != "testsuite"
@ -1153,6 +1263,10 @@ getent passwd salt >/dev/null || %{_sbindir}/useradd -r -g salt -d $S_HOME -s /b
if [[ -d "$S_PHOME/.ssh" ]]; then if [[ -d "$S_PHOME/.ssh" ]]; then
mv $S_PHOME/.ssh $S_HOME mv $S_PHOME/.ssh $S_HOME
fi fi
%if 0%{?_alternatives}
[ -h %{_bindir}/salt-call ] || rm -f %{_bindir}/salt-call
%python_libalternatives_reset_alternative salt-call
%endif
%post %post
%if %{with systemd} %if %{with systemd}
@ -1185,14 +1299,9 @@ dbus-uuidgen --ensure
%if %{with systemd} %if %{with systemd}
%if 0%{?suse_version} %if 0%{?suse_version}
%service_add_post salt-proxy@.service %service_add_post salt-proxy@.service
%fillup_only
%else %else
%systemd_post salt-proxy@.service %systemd_post salt-proxy@.service
%endif %endif
%else
%if 0%{?suse_version}
%fillup_and_insserv
%endif
%endif %endif
%postun proxy %postun proxy
@ -1202,11 +1311,6 @@ dbus-uuidgen --ensure
%else %else
%systemd_postun_with_restart salt-proxy@.service %systemd_postun_with_restart salt-proxy@.service
%endif %endif
%else
%if 0%{?suse_version}
%insserv_cleanup
%restart_on_update salt-proxy
%endif
%endif %endif
%preun syndic %preun syndic
@ -1216,15 +1320,6 @@ dbus-uuidgen --ensure
%else %else
%systemd_preun salt-syndic.service %systemd_preun salt-syndic.service
%endif %endif
%else
%if 0%{?suse_version}
%stop_on_removal salt-syndic
%else
if [ $1 -eq 0 ] ; then
/sbin/service salt-syndic stop >/dev/null 2>&1
/sbin/chkconfig --del salt-syndic
fi
%endif
%endif %endif
%pre syndic %pre syndic
@ -1238,14 +1333,9 @@ dbus-uuidgen --ensure
%if %{with systemd} %if %{with systemd}
%if 0%{?suse_version} %if 0%{?suse_version}
%service_add_post salt-syndic.service %service_add_post salt-syndic.service
%fillup_only
%else %else
%systemd_post salt-syndic.service %systemd_post salt-syndic.service
%endif %endif
%else
%if 0%{?suse_version}
%fillup_and_insserv
%endif
%endif %endif
%postun syndic %postun syndic
@ -1255,11 +1345,6 @@ dbus-uuidgen --ensure
%else %else
%systemd_postun_with_restart salt-syndic.service %systemd_postun_with_restart salt-syndic.service
%endif %endif
%else
%if 0%{?suse_version}
%insserv_cleanup
%restart_on_update salt-syndic
%endif
%endif %endif
%preun master %preun master
@ -1269,15 +1354,6 @@ dbus-uuidgen --ensure
%else %else
%systemd_preun salt-master.service %systemd_preun salt-master.service
%endif %endif
%else
%if 0%{?suse_version}
%stop_on_removal salt-master
%else
if [ $1 -eq 0 ] ; then
/sbin/service salt-master stop >/dev/null 2>&1
/sbin/chkconfig --del salt-master
fi
%endif
%endif %endif
%pre master %pre master
@ -1313,16 +1389,9 @@ if [ "${systemd_ver%%.*}" -lt 228 ]; then
fi fi
%if 0%{?suse_version} %if 0%{?suse_version}
%service_add_post salt-master.service %service_add_post salt-master.service
%fillup_only
%else %else
%systemd_post salt-master.service %systemd_post salt-master.service
%endif %endif
%else
%if 0%{?suse_version}
%fillup_and_insserv
%else
/sbin/chkconfig --add salt-master
%endif
%endif %endif
%postun master %postun master
@ -1332,15 +1401,6 @@ fi
%else %else
%systemd_postun_with_restart salt-master.service %systemd_postun_with_restart salt-master.service
%endif %endif
%else
%if 0%{?suse_version}
%restart_on_update salt-master
%insserv_cleanup
%else
if [ "$1" -ge "1" ] ; then
/sbin/service salt-master condrestart >/dev/null 2>&1 || :
fi
%endif
%endif %endif
%preun minion %preun minion
@ -1350,15 +1410,6 @@ fi
%else %else
%systemd_preun salt-minion.service %systemd_preun salt-minion.service
%endif %endif
%else
%if 0%{?suse_version}
%stop_on_removal salt-minion
%else
if [ $1 -eq 0 ] ; then
/sbin/service salt-minion stop >/dev/null 2>&1
/sbin/chkconfig --del salt-minion
fi
%endif
%endif %endif
%pre minion %pre minion
@ -1372,16 +1423,9 @@ fi
%if %{with systemd} %if %{with systemd}
%if 0%{?suse_version} %if 0%{?suse_version}
%service_add_post salt-minion.service %service_add_post salt-minion.service
%fillup_only
%else %else
%systemd_post salt-minion.service %systemd_post salt-minion.service
%endif %endif
%else
%if 0%{?suse_version}
%fillup_and_insserv
%else
/sbin/chkconfig --add salt-minion
%endif
%endif %endif
%postun minion %postun minion
@ -1391,15 +1435,6 @@ fi
%else %else
%systemd_postun_with_restart salt-minion.service %systemd_postun_with_restart salt-minion.service
%endif %endif
%else
%if 0%{?suse_version}
%insserv_cleanup
%restart_on_update salt-minion
%else
if [ "$1" -ge "1" ] ; then
/sbin/service salt-minion condrestart >/dev/null 2>&1 || :
fi
%endif
%endif %endif
%preun api %preun api
@ -1427,10 +1462,6 @@ fi
%else %else
%systemd_post salt-api.service %systemd_post salt-api.service
%endif %endif
%else
%if 0%{?suse_version}
%fillup_and_insserv
%endif
%endif %endif
%postun api %postun api
@ -1440,14 +1471,25 @@ fi
%else %else
%systemd_postun_with_restart salt-api.service %systemd_postun_with_restart salt-api.service
%endif %endif
%else
%if 0%{?suse_version}
%insserv_cleanup
%restart_on_update
%endif
%endif %endif
%posttrans -n python3-salt %if 0%{?_alternatives}
%pre -n python-salt
[ -h %{_bindir}/salt-call ] || rm -f %{_bindir}/salt-call
%python_libalternatives_reset_alternative salt-call
%post -n python-salt
%python_install_alternative salt-call
%postun -n python-salt
%python_uninstall_alternative salt-call
%endif
%if 0%{?_nosinglespec}
%posttrans -n %{python_module salt}
%else
%posttrans -n python-salt
%endif
# force re-generate a new thin.tgz # force re-generate a new thin.tgz
rm -f %{_localstatedir}/cache/salt/master/thin/version rm -f %{_localstatedir}/cache/salt/master/thin/version
rm -f %{_localstatedir}/cache/salt/minion/thin/version rm -f %{_localstatedir}/cache/salt/minion/thin/version
@ -1455,11 +1497,9 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
%files api %files api
%defattr(-,root,root) %defattr(-,root,root)
%{_bindir}/salt-api %{_bindir}/salt-api
%{_sbindir}/rcsalt-api
%if %{with systemd} %if %{with systemd}
%{_sbindir}/rcsalt-api
%{_unitdir}/salt-api.service %{_unitdir}/salt-api.service
%else
%{_initddir}/salt-api
%endif %endif
%{_mandir}/man1/salt-api.1.* %{_mandir}/man1/salt-api.1.*
@ -1485,11 +1525,9 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
%defattr(-,root,root) %defattr(-,root,root)
%{_bindir}/salt-syndic %{_bindir}/salt-syndic
%{_mandir}/man1/salt-syndic.1.gz %{_mandir}/man1/salt-syndic.1.gz
%{_sbindir}/rcsalt-syndic
%if %{with systemd} %if %{with systemd}
%{_sbindir}/rcsalt-syndic
%{_unitdir}/salt-syndic.service %{_unitdir}/salt-syndic.service
%else
%{_initddir}/salt-syndic
%endif %endif
%files minion %files minion
@ -1501,7 +1539,9 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
%dir %attr(0750, root, root) %{_sysconfdir}/salt/minion.d/ %dir %attr(0750, root, root) %{_sysconfdir}/salt/minion.d/
%dir %attr(0750, root, root) %{_sysconfdir}/salt/pki/minion/ %dir %attr(0750, root, root) %{_sysconfdir}/salt/pki/minion/
%dir %attr(0750, root, root) %{_localstatedir}/cache/salt/minion/ %dir %attr(0750, root, root) %{_localstatedir}/cache/salt/minion/
%if %{with systemd}
%{_sbindir}/rcsalt-minion %{_sbindir}/rcsalt-minion
%endif
# Install plugin only on SUSE machines # Install plugin only on SUSE machines
%if 0%{?suse_version} %if 0%{?suse_version}
@ -1522,13 +1562,6 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
%if %{with systemd} %if %{with systemd}
%{_unitdir}/salt-minion.service %{_unitdir}/salt-minion.service
%else
%config(noreplace) %{_initddir}/salt-minion
%endif
## Install sysV salt-minion watchdog for SLES11 and RHEL6
%if 0%{?rhel} == 6 || 0%{?suse_version} == 1110
%{_bindir}/salt-daemon-watcher
%endif %endif
%files proxy %files proxy
@ -1554,11 +1587,9 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
%if 0%{?suse_version} <= 1500 %if 0%{?suse_version} <= 1500
%config(noreplace) %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/salt %config(noreplace) %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/salt
%endif %endif
%{_sbindir}/rcsalt-master
%if %{with systemd} %if %{with systemd}
%{_sbindir}/rcsalt-master
%{_unitdir}/salt-master.service %{_unitdir}/salt-master.service
%else
%config(noreplace) %{_initddir}/salt-master
%endif %endif
# #
%config(noreplace) %attr(0640, root, salt) %{_sysconfdir}/salt/master %config(noreplace) %attr(0640, root, salt) %{_sysconfdir}/salt/master
@ -1584,7 +1615,9 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
%files %files
%defattr(-,root,root,-) %defattr(-,root,root,-)
%{_bindir}/spm %{_bindir}/spm
%if ! 0%{?_alternatives}
%{_bindir}/salt-call %{_bindir}/salt-call
%endif
%{_bindir}/salt-support %{_bindir}/salt-support
%{_mandir}/man1/salt-call.1.gz %{_mandir}/man1/salt-call.1.gz
%{_mandir}/man1/spm.1.gz %{_mandir}/man1/spm.1.gz
@ -1603,13 +1636,16 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
%endif %endif
%{_mandir}/man1/salt.1.* %{_mandir}/man1/salt.1.*
%files -n python3-salt %files %{python_files salt}
%defattr(-,root,root,-) %defattr(-,root,root,-)
%dir %{python3_sitelib}/salt %if 0%{?_alternatives}
%dir %{python3_sitelib}/salt-*.egg-info %python_alternative %{_bindir}/salt-call
%{python3_sitelib}/salt/* %endif
%{python3_sitelib}/salt-*.egg-info/* %dir %{python_sitelib}/salt
%exclude %{python3_sitelib}/salt/cloud/deploy/*.sh %dir %{python_sitelib}/salt-*.egg-info
%{python_sitelib}/salt/*
%{python_sitelib}/salt-*.egg-info/*
%exclude %{python_sitelib}/salt/cloud/deploy/*.sh
%if %{with docs} %if %{with docs}
%files doc %files doc
@ -1656,10 +1692,8 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
%endif %endif
%if "%{flavor}" == "testsuite" %if "%{flavor}" == "testsuite"
%files -n python3-salt-testsuite %files %{python_files salt-testsuite}
%{python3_sitelib}/salt-testsuite %{python_sitelib}/salt-testsuite
%endif %endif
%changelog %changelog