Compare commits
13 Commits
df957acc66
...
f4dad55b8b
Author | SHA1 | Date |
---|---|---|
Yu Watanabe | f4dad55b8b | |
Yu Watanabe | 5e467d74ad | |
Justin Trudell | 0ccdaa79ca | |
Lennart Poettering | fe573a798d | |
Yu Watanabe | 8574039520 | |
Lennart Poettering | 43c3fb4680 | |
Dan Streetman | 426654d728 | |
Dan Streetman | 7471bcb06e | |
Dan Streetman | 856423f14d | |
Lennart Poettering | dfaf16ebed | |
Lennart Poettering | 0e06a03165 | |
Lennart Poettering | eb2cfa81b0 | |
Lennart Poettering | 6e0a388854 |
|
@ -662,15 +662,12 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) {
|
int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) {
|
||||||
|
|
||||||
if (inotify_add_watch(fd, pathname, mask) < 0) {
|
if (inotify_add_watch(fd, pathname, mask) < 0) {
|
||||||
const char *reason;
|
|
||||||
|
|
||||||
if (errno == ENOSPC)
|
if (errno == ENOSPC)
|
||||||
reason = "inotify watch limit reached";
|
return log_error_errno(errno, "Failed to add a watch for %s: inotify watch limit reached", pathname);
|
||||||
else
|
|
||||||
reason = strerror_safe(errno);
|
|
||||||
|
|
||||||
return log_error_errno(errno, "Failed to add a watch for %s: %s", pathname, reason);
|
return log_error_errno(errno, "Failed to add a watch for %s: %m", pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -40,8 +40,8 @@ typedef struct StaticDestructor {
|
||||||
extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[];
|
extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[];
|
||||||
extern const struct StaticDestructor _weak_ __stop_SYSTEMD_STATIC_DESTRUCT[];
|
extern const struct StaticDestructor _weak_ __stop_SYSTEMD_STATIC_DESTRUCT[];
|
||||||
|
|
||||||
/* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in the same
|
/* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in
|
||||||
* linking unit as the variables we want to destroy. */
|
* the same linking unit as the variables we want to destroy.) */
|
||||||
static inline void static_destruct(void) {
|
static inline void static_destruct(void) {
|
||||||
const StaticDestructor *d;
|
const StaticDestructor *d;
|
||||||
|
|
||||||
|
|
|
@ -409,8 +409,10 @@ char* gid_to_name(gid_t gid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int in_gid(gid_t gid) {
|
int in_gid(gid_t gid) {
|
||||||
gid_t *gids;
|
_cleanup_free_ gid_t *allocated = NULL;
|
||||||
int ngroups, r, i;
|
gid_t local[16], *p = local;
|
||||||
|
int ngroups = ELEMENTSOF(local);
|
||||||
|
unsigned attempt = 0;
|
||||||
|
|
||||||
if (getgid() == gid)
|
if (getgid() == gid)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -421,23 +423,39 @@ int in_gid(gid_t gid) {
|
||||||
if (!gid_is_valid(gid))
|
if (!gid_is_valid(gid))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ngroups = getgroups(ngroups, p);
|
||||||
|
if (ngroups >= 0)
|
||||||
|
break;
|
||||||
|
if (errno != EINVAL)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
/* Give up eventually */
|
||||||
|
if (attempt++ > 10)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Get actual size needed, and size the array explicitly. Note that this is potentially racy
|
||||||
|
* to use (in multi-threaded programs), hence let's call this in a loop. */
|
||||||
ngroups = getgroups(0, NULL);
|
ngroups = getgroups(0, NULL);
|
||||||
if (ngroups < 0)
|
if (ngroups < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (ngroups == 0)
|
if (ngroups == 0)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
gids = newa(gid_t, ngroups);
|
free(allocated);
|
||||||
|
|
||||||
r = getgroups(ngroups, gids);
|
allocated = new(gid_t, ngroups);
|
||||||
if (r < 0)
|
if (!allocated)
|
||||||
return -errno;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < r; i++)
|
p = allocated;
|
||||||
if (gids[i] == gid)
|
}
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
for (int i = 0; i < ngroups; i++)
|
||||||
|
if (p[i] == gid)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int in_group(const char *name) {
|
int in_group(const char *name) {
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
#include "static-destruct.h"
|
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
@ -49,11 +48,8 @@
|
||||||
|
|
||||||
int saved_argc = 0;
|
int saved_argc = 0;
|
||||||
char **saved_argv = NULL;
|
char **saved_argv = NULL;
|
||||||
char **saved_env = NULL;
|
|
||||||
static int saved_in_initrd = -1;
|
static int saved_in_initrd = -1;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(saved_env, strv_freep);
|
|
||||||
|
|
||||||
bool kexec_loaded(void) {
|
bool kexec_loaded(void) {
|
||||||
_cleanup_free_ char *s = NULL;
|
_cleanup_free_ char *s = NULL;
|
||||||
|
|
||||||
|
@ -301,7 +297,3 @@ void disable_coredumps(void) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
|
log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_env(void) {
|
|
||||||
saved_env = strv_copy(environ);
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,9 +13,6 @@ static inline void save_argc_argv(int argc, char **argv) {
|
||||||
saved_argv = argv;
|
saved_argv = argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char **saved_env;
|
|
||||||
void save_env(void);
|
|
||||||
|
|
||||||
bool kexec_loaded(void);
|
bool kexec_loaded(void);
|
||||||
|
|
||||||
int prot_from_flags(int flags) _const_;
|
int prot_from_flags(int flags) _const_;
|
||||||
|
|
|
@ -146,6 +146,9 @@ static OOMPolicy arg_default_oom_policy;
|
||||||
static CPUSet arg_cpu_affinity;
|
static CPUSet arg_cpu_affinity;
|
||||||
static NUMAPolicy arg_numa_policy;
|
static NUMAPolicy arg_numa_policy;
|
||||||
|
|
||||||
|
/* A copy of the original environment block */
|
||||||
|
static char **saved_env = NULL;
|
||||||
|
|
||||||
static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
|
static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
|
||||||
const struct rlimit *saved_rlimit_memlock);
|
const struct rlimit *saved_rlimit_memlock);
|
||||||
|
|
||||||
|
@ -2353,6 +2356,17 @@ static bool early_skip_setup_check(int argc, char *argv[]) {
|
||||||
return found_deserialize; /* When we are deserializing, then we are reexecuting, hence avoid the extensive setup */
|
return found_deserialize; /* When we are deserializing, then we are reexecuting, hence avoid the extensive setup */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int save_env(void) {
|
||||||
|
char **l;
|
||||||
|
|
||||||
|
l = strv_copy(environ);
|
||||||
|
if (!l)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
strv_free_and_replace(saved_env, l);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL, userspace_timestamp = DUAL_TIMESTAMP_NULL, kernel_timestamp = DUAL_TIMESTAMP_NULL,
|
dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL, userspace_timestamp = DUAL_TIMESTAMP_NULL, kernel_timestamp = DUAL_TIMESTAMP_NULL,
|
||||||
|
@ -2391,9 +2405,13 @@ int main(int argc, char *argv[]) {
|
||||||
/* Save the original command line */
|
/* Save the original command line */
|
||||||
save_argc_argv(argc, argv);
|
save_argc_argv(argc, argv);
|
||||||
|
|
||||||
/* Save the original environment as we might need to restore it if we're requested to
|
/* Save the original environment as we might need to restore it if we're requested to execute another
|
||||||
* execute another system manager later. */
|
* system manager later. */
|
||||||
save_env();
|
r = save_env();
|
||||||
|
if (r < 0) {
|
||||||
|
error_message = "Failed to copy environment block";
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure that if the user says "syslog" we actually log to the journal. */
|
/* Make sure that if the user says "syslog" we actually log to the journal. */
|
||||||
log_set_upgrade_syslog_to_journal(true);
|
log_set_upgrade_syslog_to_journal(true);
|
||||||
|
@ -2681,6 +2699,8 @@ finish:
|
||||||
arg_serialization = safe_fclose(arg_serialization);
|
arg_serialization = safe_fclose(arg_serialization);
|
||||||
fds = fdset_free(fds);
|
fds = fdset_free(fds);
|
||||||
|
|
||||||
|
saved_env = strv_free(saved_env);
|
||||||
|
|
||||||
#if HAVE_VALGRIND_VALGRIND_H
|
#if HAVE_VALGRIND_VALGRIND_H
|
||||||
/* If we are PID 1 and running under valgrind, then let's exit
|
/* If we are PID 1 and running under valgrind, then let's exit
|
||||||
* here explicitly. valgrind will only generate nice output on
|
* here explicitly. valgrind will only generate nice output on
|
||||||
|
|
|
@ -103,6 +103,7 @@
|
||||||
#include "terminal-util.h"
|
#include "terminal-util.h"
|
||||||
#include "tmpfile-util.h"
|
#include "tmpfile-util.h"
|
||||||
#include "umask-util.h"
|
#include "umask-util.h"
|
||||||
|
#include "unit-name.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -891,13 +892,17 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
arg_settings_mask |= SETTING_MACHINE_ID;
|
arg_settings_mask |= SETTING_MACHINE_ID;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S': {
|
||||||
r = free_and_strdup(&arg_slice, optarg);
|
_cleanup_free_ char *mangled = NULL;
|
||||||
|
|
||||||
|
r = unit_name_mangle_with_suffix(optarg, NULL, UNIT_NAME_MANGLE_WARN, ".slice", &mangled);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
free_and_replace(arg_slice, mangled);
|
||||||
arg_settings_mask |= SETTING_SLICE;
|
arg_settings_mask |= SETTING_SLICE;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
if (isempty(optarg))
|
if (isempty(optarg))
|
||||||
|
@ -2385,7 +2390,8 @@ static int drop_capabilities(uid_t uid) {
|
||||||
/* If we're not using OCI, proceed with mangled capabilities (so we don't error out)
|
/* If we're not using OCI, proceed with mangled capabilities (so we don't error out)
|
||||||
* in order to maintain the same behavior as systemd < 242. */
|
* in order to maintain the same behavior as systemd < 242. */
|
||||||
if (capability_quintet_mangle(&q))
|
if (capability_quintet_mangle(&q))
|
||||||
log_warning("Some capabilities will not be set because they are not in the current bounding set.");
|
log_full(arg_quiet ? LOG_DEBUG : LOG_WARNING,
|
||||||
|
"Some capabilities will not be set because they are not in the current bounding set.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,6 +286,15 @@ static void test_make_salt(void) {
|
||||||
assert(!streq(s, t));
|
assert(!streq(s, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_in_gid(void) {
|
||||||
|
|
||||||
|
assert(in_gid(getgid()) >= 0);
|
||||||
|
assert(in_gid(getegid()) >= 0);
|
||||||
|
|
||||||
|
assert(in_gid(GID_INVALID) < 0);
|
||||||
|
assert(in_gid(TTY_GID) == 0); /* The TTY gid is for owning ttys, it would be really really weird if we were in it. */
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
test_uid_to_name_one(0, "root");
|
test_uid_to_name_one(0, "root");
|
||||||
test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME);
|
test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME);
|
||||||
|
@ -320,5 +329,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
test_make_salt();
|
test_make_salt();
|
||||||
|
|
||||||
|
test_in_gid();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,16 @@ network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
|
||||||
dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
|
dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
|
||||||
dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
|
dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
|
||||||
|
|
||||||
networkd_bin='/usr/lib/systemd/systemd-networkd'
|
systemd_lib_paths=['/usr/lib/systemd', '/lib/systemd']
|
||||||
resolved_bin='/usr/lib/systemd/systemd-resolved'
|
which_paths=':'.join(systemd_lib_paths + os.getenv('PATH', os.defpath).lstrip(':').split(':'))
|
||||||
wait_online_bin='/usr/lib/systemd/systemd-networkd-wait-online'
|
|
||||||
networkctl_bin='/usr/bin/networkctl'
|
networkd_bin=shutil.which('systemd-networkd', path=which_paths)
|
||||||
resolvectl_bin='/usr/bin/resolvectl'
|
resolved_bin=shutil.which('systemd-resolved', path=which_paths)
|
||||||
timedatectl_bin='/usr/bin/timedatectl'
|
wait_online_bin=shutil.which('systemd-networkd-wait-online', path=which_paths)
|
||||||
|
networkctl_bin=shutil.which('networkctl', path=which_paths)
|
||||||
|
resolvectl_bin=shutil.which('resolvectl', path=which_paths)
|
||||||
|
timedatectl_bin=shutil.which('timedatectl', path=which_paths)
|
||||||
|
|
||||||
use_valgrind=False
|
use_valgrind=False
|
||||||
enable_debug=True
|
enable_debug=True
|
||||||
env = {}
|
env = {}
|
||||||
|
@ -53,7 +57,7 @@ def run(*command, **kwargs):
|
||||||
def is_module_available(module_name):
|
def is_module_available(module_name):
|
||||||
lsmod_output = check_output('lsmod')
|
lsmod_output = check_output('lsmod')
|
||||||
module_re = re.compile(rf'^{re.escape(module_name)}\b', re.MULTILINE)
|
module_re = re.compile(rf'^{re.escape(module_name)}\b', re.MULTILINE)
|
||||||
return module_re.search(lsmod_output) or not call('modprobe', module_name)
|
return module_re.search(lsmod_output) or not call('modprobe', module_name, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
def expectedFailureIfModuleIsNotAvailable(module_name):
|
def expectedFailureIfModuleIsNotAvailable(module_name):
|
||||||
def f(func):
|
def f(func):
|
||||||
|
@ -65,7 +69,7 @@ def expectedFailureIfModuleIsNotAvailable(module_name):
|
||||||
|
|
||||||
def expectedFailureIfERSPANModuleIsNotAvailable():
|
def expectedFailureIfERSPANModuleIsNotAvailable():
|
||||||
def f(func):
|
def f(func):
|
||||||
rc = call('ip link add dev erspan99 type erspan seq key 30 local 192.168.1.4 remote 192.168.1.1 erspan_ver 1 erspan 123')
|
rc = call('ip link add dev erspan99 type erspan seq key 30 local 192.168.1.4 remote 192.168.1.1 erspan_ver 1 erspan 123', stderr=subprocess.DEVNULL)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
call('ip link del erspan99')
|
call('ip link del erspan99')
|
||||||
return func
|
return func
|
||||||
|
@ -76,7 +80,7 @@ def expectedFailureIfERSPANModuleIsNotAvailable():
|
||||||
|
|
||||||
def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
|
def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
|
||||||
def f(func):
|
def f(func):
|
||||||
rc = call('ip rule add from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
|
rc = call('ip rule add from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7', stderr=subprocess.DEVNULL)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
call('ip rule del from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
|
call('ip rule del from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
|
||||||
return func
|
return func
|
||||||
|
@ -87,7 +91,7 @@ def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
|
||||||
|
|
||||||
def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
|
def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
|
||||||
def f(func):
|
def f(func):
|
||||||
rc = call('ip rule add not from 192.168.100.19 ipproto tcp table 7')
|
rc = call('ip rule add not from 192.168.100.19 ipproto tcp table 7', stderr=subprocess.DEVNULL)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
call('ip rule del not from 192.168.100.19 ipproto tcp table 7')
|
call('ip rule del not from 192.168.100.19 ipproto tcp table 7')
|
||||||
return func
|
return func
|
||||||
|
@ -99,7 +103,7 @@ def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
|
||||||
def expectedFailureIfLinkFileFieldIsNotSet():
|
def expectedFailureIfLinkFileFieldIsNotSet():
|
||||||
def f(func):
|
def f(func):
|
||||||
support = False
|
support = False
|
||||||
rc = call('ip link add name dummy99 type dummy')
|
rc = call('ip link add name dummy99 type dummy', stderr=subprocess.DEVNULL)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
ret = run('udevadm info -w10s /sys/class/net/dummy99', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
ret = run('udevadm info -w10s /sys/class/net/dummy99', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
if ret.returncode == 0 and 'E: ID_NET_LINK_FILE=' in ret.stdout.rstrip():
|
if ret.returncode == 0 and 'E: ID_NET_LINK_FILE=' in ret.stdout.rstrip():
|
||||||
|
@ -115,7 +119,7 @@ def expectedFailureIfLinkFileFieldIsNotSet():
|
||||||
|
|
||||||
def expectedFailureIfNexthopIsNotAvailable():
|
def expectedFailureIfNexthopIsNotAvailable():
|
||||||
def f(func):
|
def f(func):
|
||||||
rc = call('ip nexthop list')
|
rc = call('ip nexthop list', stderr=subprocess.DEVNULL)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
return func
|
return func
|
||||||
else:
|
else:
|
||||||
|
@ -510,12 +514,12 @@ class NetworkctlTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
output = check_output(*networkctl_cmd, 'status', 'test1')
|
output = check_output(*networkctl_cmd, 'status', 'test1')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, r'Link File: (?:/usr)/lib/systemd/network/99-default.link')
|
self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
|
||||||
self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
|
self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
|
||||||
|
|
||||||
output = check_output(*networkctl_cmd, 'status', 'lo')
|
output = check_output(*networkctl_cmd, 'status', 'lo')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, r'Link File: (?:/usr)/lib/systemd/network/99-default.link')
|
self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
|
||||||
self.assertRegex(output, r'Network File: n/a')
|
self.assertRegex(output, r'Network File: n/a')
|
||||||
|
|
||||||
def test_delete_links(self):
|
def test_delete_links(self):
|
||||||
|
@ -748,7 +752,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
self.wait_online(['bridge99', 'test1:degraded'], bool_any=True)
|
self.wait_online(['bridge99', 'test1:degraded'], bool_any=True)
|
||||||
|
|
||||||
self.check_operstate('bridge99', '(?:off|no-carrier)', setup_state='configuring')
|
self.check_operstate('bridge99', '(off|no-carrier)', setup_state='configuring')
|
||||||
self.check_operstate('test1', 'degraded')
|
self.check_operstate('test1', 'degraded')
|
||||||
|
|
||||||
def test_bridge(self):
|
def test_bridge(self):
|
||||||
|
@ -921,7 +925,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||||
output = check_output('ip -d link show tun99')
|
output = check_output('ip -d link show tun99')
|
||||||
print(output)
|
print(output)
|
||||||
# Old ip command does not support IFF_ flags
|
# Old ip command does not support IFF_ flags
|
||||||
self.assertRegex(output, 'tun (?:type tun pi on vnet_hdr on multi_queue|addrgenmode) ')
|
self.assertRegex(output, 'tun (type tun pi on vnet_hdr on multi_queue|addrgenmode) ')
|
||||||
|
|
||||||
def test_tap(self):
|
def test_tap(self):
|
||||||
copy_unit_to_networkd_unit_path('25-tap.netdev')
|
copy_unit_to_networkd_unit_path('25-tap.netdev')
|
||||||
|
@ -932,7 +936,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||||
output = check_output('ip -d link show tap99')
|
output = check_output('ip -d link show tap99')
|
||||||
print(output)
|
print(output)
|
||||||
# Old ip command does not support IFF_ flags
|
# Old ip command does not support IFF_ flags
|
||||||
self.assertRegex(output, 'tun (?:type tap pi on vnet_hdr on multi_queue|addrgenmode) ')
|
self.assertRegex(output, 'tun (type tap pi on vnet_hdr on multi_queue|addrgenmode) ')
|
||||||
|
|
||||||
@expectedFailureIfModuleIsNotAvailable('vrf')
|
@expectedFailureIfModuleIsNotAvailable('vrf')
|
||||||
def test_vrf(self):
|
def test_vrf(self):
|
||||||
|
@ -1010,16 +1014,16 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
output = check_output('ip -d link show ipiptun99')
|
output = check_output('ip -d link show ipiptun99')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'ipip (?:ipip |)remote 192.169.224.239 local 192.168.223.238 dev dummy98')
|
self.assertRegex(output, 'ipip (ipip )?remote 192.169.224.239 local 192.168.223.238 dev dummy98')
|
||||||
output = check_output('ip -d link show ipiptun98')
|
output = check_output('ip -d link show ipiptun98')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'ipip (?:ipip |)remote 192.169.224.239 local any dev dummy98')
|
self.assertRegex(output, 'ipip (ipip )?remote 192.169.224.239 local any dev dummy98')
|
||||||
output = check_output('ip -d link show ipiptun97')
|
output = check_output('ip -d link show ipiptun97')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'ipip (?:ipip |)remote any local 192.168.223.238 dev dummy98')
|
self.assertRegex(output, 'ipip (ipip )?remote any local 192.168.223.238 dev dummy98')
|
||||||
output = check_output('ip -d link show ipiptun96')
|
output = check_output('ip -d link show ipiptun96')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'ipip (?:ipip |)remote any local any dev dummy98')
|
self.assertRegex(output, 'ipip (ipip )?remote any local any dev dummy98')
|
||||||
|
|
||||||
def test_gre_tunnel(self):
|
def test_gre_tunnel(self):
|
||||||
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretun.network',
|
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretun.network',
|
||||||
|
@ -1159,10 +1163,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||||
self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
|
self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
|
||||||
output = check_output('ip -d link show vti6tun98')
|
output = check_output('ip -d link show vti6tun98')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local (?:any|::) dev dummy98')
|
self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local (any|::) dev dummy98')
|
||||||
output = check_output('ip -d link show vti6tun97')
|
output = check_output('ip -d link show vti6tun97')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'vti6 remote (?:any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
|
self.assertRegex(output, 'vti6 remote (any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
|
||||||
|
|
||||||
def test_ip6tnl_tunnel(self):
|
def test_ip6tnl_tunnel(self):
|
||||||
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6tnl.network',
|
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6tnl.network',
|
||||||
|
@ -1177,10 +1181,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||||
self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
|
self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
|
||||||
output = check_output('ip -d link show ip6tnl98')
|
output = check_output('ip -d link show ip6tnl98')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local (?:any|::) dev dummy98')
|
self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local (any|::) dev dummy98')
|
||||||
output = check_output('ip -d link show ip6tnl97')
|
output = check_output('ip -d link show ip6tnl97')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'ip6tnl ip6ip6 remote (?:any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
|
self.assertRegex(output, 'ip6tnl ip6ip6 remote (any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
|
||||||
|
|
||||||
def test_sit_tunnel(self):
|
def test_sit_tunnel(self):
|
||||||
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'sit.network',
|
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'sit.network',
|
||||||
|
@ -1193,16 +1197,16 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
output = check_output('ip -d link show sittun99')
|
output = check_output('ip -d link show sittun99')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, "sit (?:ip6ip |)remote 10.65.223.239 local 10.65.223.238 dev dummy98")
|
self.assertRegex(output, "sit (ip6ip )?remote 10.65.223.239 local 10.65.223.238 dev dummy98")
|
||||||
output = check_output('ip -d link show sittun98')
|
output = check_output('ip -d link show sittun98')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, "sit (?:ip6ip |)remote 10.65.223.239 local any dev dummy98")
|
self.assertRegex(output, "sit (ip6ip )?remote 10.65.223.239 local any dev dummy98")
|
||||||
output = check_output('ip -d link show sittun97')
|
output = check_output('ip -d link show sittun97')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, "sit (?:ip6ip |)remote any local 10.65.223.238 dev dummy98")
|
self.assertRegex(output, "sit (ip6ip )?remote any local 10.65.223.238 dev dummy98")
|
||||||
output = check_output('ip -d link show sittun96')
|
output = check_output('ip -d link show sittun96')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, "sit (?:ip6ip |)remote any local any dev dummy98")
|
self.assertRegex(output, "sit (ip6ip )?remote any local any dev dummy98")
|
||||||
|
|
||||||
def test_isatap_tunnel(self):
|
def test_isatap_tunnel(self):
|
||||||
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'isatap.network',
|
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'isatap.network',
|
||||||
|
@ -1596,7 +1600,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, '111:')
|
self.assertRegex(output, '111:')
|
||||||
self.assertRegex(output, 'from 192.168.100.18')
|
self.assertRegex(output, 'from 192.168.100.18')
|
||||||
self.assertRegex(output, r'tos (?:0x08|throughput)\s')
|
self.assertRegex(output, r'tos (0x08|throughput)\s')
|
||||||
self.assertRegex(output, 'iif test1')
|
self.assertRegex(output, 'iif test1')
|
||||||
self.assertRegex(output, 'oif test1')
|
self.assertRegex(output, 'oif test1')
|
||||||
self.assertRegex(output, 'lookup 7')
|
self.assertRegex(output, 'lookup 7')
|
||||||
|
@ -1634,11 +1638,11 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
output = check_output('ip rule list table 7')
|
output = check_output('ip rule list table 7')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, '111: from 192.168.100.18 tos (?:0x08|throughput) iif test1 oif test1 lookup 7')
|
self.assertRegex(output, '111: from 192.168.100.18 tos (0x08|throughput) iif test1 oif test1 lookup 7')
|
||||||
|
|
||||||
output = check_output('ip rule list table 8')
|
output = check_output('ip rule list table 8')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, '112: from 192.168.101.18 tos (?:0x08|throughput) iif dummy98 oif dummy98 lookup 8')
|
self.assertRegex(output, '112: from 192.168.101.18 tos (0x08|throughput) iif dummy98 oif dummy98 lookup 8')
|
||||||
|
|
||||||
stop_networkd(remove_state_files=False)
|
stop_networkd(remove_state_files=False)
|
||||||
|
|
||||||
|
@ -2109,7 +2113,7 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
||||||
self.assertRegex(data, r'LLMNR=no')
|
self.assertRegex(data, r'LLMNR=no')
|
||||||
self.assertRegex(data, r'MDNS=yes')
|
self.assertRegex(data, r'MDNS=yes')
|
||||||
self.assertRegex(data, r'DNSSEC=no')
|
self.assertRegex(data, r'DNSSEC=no')
|
||||||
self.assertRegex(data, r'ADDRESSES=192.168.(?:10.10|12.12)/24 192.168.(?:12.12|10.10)/24')
|
self.assertRegex(data, r'ADDRESSES=192.168.(10.10|12.12)/24 192.168.(12.12|10.10)/24')
|
||||||
|
|
||||||
check_output(*resolvectl_cmd, 'dns', 'dummy98', '10.10.10.12', '10.10.10.13', env=env)
|
check_output(*resolvectl_cmd, 'dns', 'dummy98', '10.10.10.12', '10.10.10.13', env=env)
|
||||||
check_output(*resolvectl_cmd, 'domain', 'dummy98', 'hogehogehoge', '~foofoofoo', env=env)
|
check_output(*resolvectl_cmd, 'domain', 'dummy98', 'hogehogehoge', '~foofoofoo', env=env)
|
||||||
|
@ -2379,7 +2383,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
|
||||||
print('### ip -6 route list table all dev bridge99')
|
print('### ip -6 route list table all dev bridge99')
|
||||||
output = check_output('ip -6 route list table all dev bridge99')
|
output = check_output('ip -6 route list table all dev bridge99')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'ff00::/8 table local metric 256 (?:linkdown |)pref medium')
|
self.assertRegex(output, 'ff00::/8 table local metric 256 (linkdown )?pref medium')
|
||||||
|
|
||||||
def test_bridge_ignore_carrier_loss(self):
|
def test_bridge_ignore_carrier_loss(self):
|
||||||
copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
|
copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
|
||||||
|
@ -2645,7 +2649,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
# link become 'routable' when at least one protocol provide an valid address.
|
# link become 'routable' when at least one protocol provide an valid address.
|
||||||
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
||||||
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
||||||
|
|
||||||
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
|
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
|
||||||
print(output)
|
print(output)
|
||||||
|
@ -2824,7 +2828,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
output = check_output('ip address show dev veth99 scope global')
|
output = check_output('ip address show dev veth99 scope global')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, r'inet6 2600::[0-9a-f]*/128 scope global (?:noprefixroute dynamic|dynamic noprefixroute)')
|
self.assertRegex(output, r'inet6 2600::[0-9a-f]*/128 scope global (noprefixroute dynamic|dynamic noprefixroute)')
|
||||||
|
|
||||||
output = check_output('ip -6 route show dev veth99')
|
output = check_output('ip -6 route show dev veth99')
|
||||||
print(output)
|
print(output)
|
||||||
|
@ -2933,7 +2937,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
# link become 'routable' when at least one protocol provide an valid address.
|
# link become 'routable' when at least one protocol provide an valid address.
|
||||||
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
||||||
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
||||||
|
|
||||||
output = check_output('ip address show dev veth99 scope global')
|
output = check_output('ip address show dev veth99 scope global')
|
||||||
print(output)
|
print(output)
|
||||||
|
@ -2976,7 +2980,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
# link become 'routable' when at least one protocol provide an valid address.
|
# link become 'routable' when at least one protocol provide an valid address.
|
||||||
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
||||||
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
||||||
|
|
||||||
print('## ip -d link show dev vrf99')
|
print('## ip -d link show dev vrf99')
|
||||||
output = check_output('ip -d link show dev vrf99')
|
output = check_output('ip -d link show dev vrf99')
|
||||||
|
@ -2988,7 +2992,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
|
self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
|
||||||
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
|
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
|
||||||
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)')
|
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
|
||||||
self.assertRegex(output, 'inet6 .* scope link')
|
self.assertRegex(output, 'inet6 .* scope link')
|
||||||
|
|
||||||
print('## ip address show dev veth99')
|
print('## ip address show dev veth99')
|
||||||
|
@ -2996,7 +3000,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
|
self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
|
||||||
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
|
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
|
||||||
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)')
|
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
|
||||||
self.assertRegex(output, 'inet6 .* scope link')
|
self.assertRegex(output, 'inet6 .* scope link')
|
||||||
|
|
||||||
print('## ip route show vrf vrf99')
|
print('## ip route show vrf vrf99')
|
||||||
|
@ -3145,7 +3149,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
# link become 'routable' when at least one protocol provide an valid address.
|
# link become 'routable' when at least one protocol provide an valid address.
|
||||||
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
||||||
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
||||||
|
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
|
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
|
||||||
|
@ -3163,7 +3167,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
# link become 'routable' when at least one protocol provide an valid address.
|
# link become 'routable' when at least one protocol provide an valid address.
|
||||||
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
||||||
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
||||||
|
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
|
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
|
||||||
|
@ -3181,7 +3185,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
# link become 'routable' when at least one protocol provide an valid address.
|
# link become 'routable' when at least one protocol provide an valid address.
|
||||||
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
||||||
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
||||||
|
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
|
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
|
||||||
|
@ -3199,7 +3203,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||||
|
|
||||||
# link become 'routable' when at least one protocol provide an valid address.
|
# link become 'routable' when at least one protocol provide an valid address.
|
||||||
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
||||||
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
||||||
|
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
|
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
|
||||||
|
|
Loading…
Reference in New Issue