assert_rc 1 busctl call org.freedesktop.hostname1 /org/freedesktop/hostname1 org.freedesktop.hostname1 GetMachineInfo s CHASSIS
}
+testcase_tags() {
+ if [[ -f /etc/machine-info ]]; then
+ cp /etc/machine-info /tmp/machine-info.bak
+ fi
+
+ trap restore_machine_info RETURN
+
+ # Start from a clean slate.
+ hostnamectl tags ""
+ assert_eq "$(hostnamectl tags)" ""
+
+ # Plain arguments replace the whole list; each argument may itself be a colon-separated list, and the
+ # result is deduplicated and sorted.
+ hostnamectl tags foo bar:baz
+ assert_eq "$(hostnamectl tags)" "bar:baz:foo"
+
+ # A leading '+' adds, a leading '-' removes, and the prefix applies to all (colon-separated) tags of
+ # the argument.
+ hostnamectl tags +quux
+ assert_eq "$(hostnamectl tags)" "bar:baz:foo:quux"
+ hostnamectl tags -- -foo
+ assert_eq "$(hostnamectl tags)" "bar:baz:quux"
+ hostnamectl tags -- +alpha:beta -bar:baz
+ assert_eq "$(hostnamectl tags)" "alpha:beta:quux"
+
+ # Adding an existing tag and removing a non-existing one are no-ops.
+ hostnamectl tags +alpha
+ assert_eq "$(hostnamectl tags)" "alpha:beta:quux"
+ hostnamectl tags -- -nonexistent
+ assert_eq "$(hostnamectl tags)" "alpha:beta:quux"
+
+ # Plain and prefixed arguments may not be mixed.
+ (! hostnamectl tags foo +bar)
+ (! hostnamectl tags +bar foo)
+ # Invalid tag characters are refused.
+ (! hostnamectl tags "in valid")
+ (! hostnamectl tags "+in/valid")
+
+ # The AddAndRemoveTags() D-Bus method directly.
+ hostnamectl tags ""
+ busctl call org.freedesktop.hostname1 /org/freedesktop/hostname1 org.freedesktop.hostname1 \
+ AddAndRemoveTags asas 2 one two 0
+ assert_eq "$(hostnamectl tags)" "one:two"
+ busctl call org.freedesktop.hostname1 /org/freedesktop/hostname1 org.freedesktop.hostname1 \
+ AddAndRemoveTags asas 1 three 1 one
+ assert_eq "$(hostnamectl tags)" "three:two"
+
+ # The SetTags() Varlink method: 'set' resets the list, then 'add'/'remove' are applied on top.
+ varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags \
+ '{"set":["x","y"],"add":["z"],"remove":["x"]}'
+ assert_eq "$(hostnamectl tags)" "y:z"
+ # An explicit empty 'set' clears the list first.
+ varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags '{"set":[]}'
+ assert_eq "$(hostnamectl tags)" ""
+ # Without 'set' the current list is the basis.
+ varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags '{"add":["aaa","bbb"]}'
+ assert_eq "$(hostnamectl tags)" "aaa:bbb"
+ varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags '{"remove":["aaa"]}'
+ assert_eq "$(hostnamectl tags)" "bbb"
+ # Invalid tags are refused.
+ (! varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags '{"add":["in valid"]}')
+
+ hostnamectl tags ""
+}
+
+testcase_varlink_setters() {
+ local bus=/run/systemd/io.systemd.Hostname
+
+ if [[ -f /etc/hostname ]]; then
+ cp /etc/hostname /tmp/hostname.bak
+ fi
+ if [[ -f /etc/machine-info ]]; then
+ cp /etc/machine-info /tmp/machine-info.bak
+ fi
+
+ trap 'restore_hostname; restore_machine_info' RETURN
+
+ # Static hostname.
+ varlinkctl call "$bus" io.systemd.Hostname.SetStaticHostname '{"newValue":"vl-static"}'
+ assert_eq "$(cat /etc/hostname)" "vl-static"
+ assert_in "Static hostname: vl-static" "$(hostnamectl)"
+
+ varlinkctl call "$bus" io.systemd.Hostname.SetStaticHostname '{"newValue":null}'
+ test ! -e /etc/hostname
+
+ # Transient hostname; a null value resets it back to the fallback
+ varlinkctl call "$bus" io.systemd.Hostname.SetHostname '{"newValue":"vl-transient"}'
+ assert_eq "$(hostname)" "vl-transient"
+ varlinkctl call "$bus" io.systemd.Hostname.SetHostname '{"newValue":null}'
+ assert_neq "$(hostname)" "vl-transient"
+
+ # Machine-info fields.
+ varlinkctl call "$bus" io.systemd.Hostname.SetPrettyHostname '{"newValue":"Pretty VL"}'
+ assert_eq "$(hostnamectl --json=short | jq --raw-output .PrettyHostname)" "Pretty VL"
+
+ varlinkctl call "$bus" io.systemd.Hostname.SetIconName '{"newValue":"computer-vl"}'
+ assert_eq "$(hostnamectl --json=short | jq --raw-output .IconName)" "computer-vl"
+
+ varlinkctl call "$bus" io.systemd.Hostname.SetChassis '{"newValue":"tablet"}'
+ assert_eq "$(hostnamectl chassis)" "tablet"
+
+ varlinkctl call "$bus" io.systemd.Hostname.SetDeployment '{"newValue":"staging"}'
+ assert_eq "$(hostnamectl --json=short | jq --raw-output .Deployment)" "staging"
+
+ varlinkctl call "$bus" io.systemd.Hostname.SetLocation '{"newValue":"Rack 7"}'
+ assert_eq "$(hostnamectl --json=short | jq --raw-output .Location)" "Rack 7"
+
+ # A null value removes the field again.
+ varlinkctl call "$bus" io.systemd.Hostname.SetLocation '{"newValue":null}'
+ assert_eq "$(hostnamectl --json=short | jq --raw-output .Location)" "null"
+
+ # Invalid values are refused.
+ (! varlinkctl call "$bus" io.systemd.Hostname.SetChassis '{"newValue":"nonsense"}')
+ (! varlinkctl call "$bus" io.systemd.Hostname.SetIconName '{"newValue":"in/valid"}')
+ (! varlinkctl call "$bus" io.systemd.Hostname.SetStaticHostname '{"newValue":"invalid hostname"}')
+}
+
run_testcases
touch /testok