diff --git a/README.md b/README.md index fdff7a9055..47b63375a1 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ interfaces over it. --- -| ![Software page](https://raw.githubusercontent.com/agama-project/agama-project.github.io/refs/heads/main/static/img/user/software.png) | ![Storage settings](https://raw.githubusercontent.com/agama-project/agama-project.github.io/refs/heads/main/static/img/storage.png) | +| ![Software page](https://raw.githubusercontent.com/agama-project/agama-project.github.io/refs/heads/main/static/img/user/software.png) | ![Storage settings](https://raw.githubusercontent.com/agama-project/agama-project.github.io/refs/heads/main/static/img/user/storage-overview.png) | | --- | --- | | ![Installing](./doc/images/screenshots/installing.png) | ![Installation finished](./doc/images/screenshots/finished.png) | diff --git a/devel/xgettext/Dockerfile b/devel/xgettext/Dockerfile new file mode 100644 index 0000000000..4d7d4f1ec0 --- /dev/null +++ b/devel/xgettext/Dockerfile @@ -0,0 +1,12 @@ +FROM registry.opensuse.org/opensuse/tumbleweed:latest + +# install gettext-tools and then clean the libzypp caches to keep the image small +RUN zypper --non-interactive install --no-recommends gettext-tools \ + && zypper clean -a + +# by default run the xgettext tool when starting the container +ENTRYPOINT [ "/usr/bin/xgettext" ] + +# define a volume so it can used for accessing files outside the container +VOLUME [ "/root/run" ] +WORKDIR /root/run diff --git a/devel/xgettext/README.md b/devel/xgettext/README.md new file mode 100644 index 0000000000..22527dc97f --- /dev/null +++ b/devel/xgettext/README.md @@ -0,0 +1,32 @@ +# Xgettext Container + +This directory contains the definition of a container containing the latest +version of the GNU gettext from the openSUSE Tumbleweed distribution. + +It can be used for extracting the translatable texts from the web frontend. +That requires a newer GNU gettext which supports TSX input file format. + +## Building the container + +To build the container run the `./build.sh` script. It uses Podman so make sure +it is installed in the system. + +## Using the container + +To run the container use the `./xgettext.sh` script. All parameters are passed +to the `xgettext` tool inside the container. + +## Clean up + +If you do not need the container anymore you can delete the image: + +```sh +podman rmi agama-xgettext +``` + +The container is based on the openSUSE Tumbleweed base image. If you do not use +it in other containers you can delete it as well: + +```sh +podman rmi registry.opensuse.org/opensuse/tumbleweed:latest +``` diff --git a/devel/xgettext/build.sh b/devel/xgettext/build.sh new file mode 100755 index 0000000000..cbda7c740d --- /dev/null +++ b/devel/xgettext/build.sh @@ -0,0 +1,4 @@ +#! /bin/sh + +# use the Dockerfile relative to this script +podman build -t agama-xgettext "$(dirname "$0")" diff --git a/devel/xgettext/xgettext.sh b/devel/xgettext/xgettext.sh new file mode 100755 index 0000000000..2fccb57d65 --- /dev/null +++ b/devel/xgettext/xgettext.sh @@ -0,0 +1,7 @@ +#! /bin/sh + +# Run xgettext from a container and pass all arguments to it. +# E.g. "./xgettext.sh --version" prints the version of the xgettext +# included in the container. + +podman run -i --rm -v .:/root/run agama-xgettext "$@" diff --git a/live/README.md b/live/README.md index b2296fcca2..03283d7b4b 100644 --- a/live/README.md +++ b/live/README.md @@ -148,8 +148,6 @@ The main Kiwi source files are located in the [src](src) subdirectory: resources (enough free disk space). - [_multibuild](src/_multibuild) defines the image flavors (KIWI profiles) which are available to build -- [images.sh](src/images.sh) - injects a script which checks whether the machine has enough RAM when - booting the Live ISO - [fix_bootconfig](src/fix_bootconfig) - a special KIWI hook script which sets the boot configuration on S390 and PPC64 architectures. diff --git a/live/config-cdroot/fix_bootconfig.aarch64 b/live/config-cdroot/fix_bootconfig.aarch64 index fae91360fa..834f47a94e 100755 --- a/live/config-cdroot/fix_bootconfig.aarch64 +++ b/live/config-cdroot/fix_bootconfig.aarch64 @@ -82,7 +82,7 @@ menuentry "Boot from Hard Disk" --class opensuse --class gnu-linux --class gnu - menuentry "Install $label" --class os --unrestricted { set gfxpayload=keep echo Loading kernel... - linux (\$root)/boot/aarch64/loader/linux \${extra_cmdline} \${isoboot} + linux (\$root)/boot/aarch64/loader/linux \${extra_cmdline} \${isoboot} splash=silent echo Loading initrd... initrd (\$root)/boot/aarch64/loader/initrd } diff --git a/live/config-cdroot/fix_bootconfig.ppc64le b/live/config-cdroot/fix_bootconfig.ppc64le index ef896a7677..db79af9b8c 100755 --- a/live/config-cdroot/fix_bootconfig.ppc64le +++ b/live/config-cdroot/fix_bootconfig.ppc64le @@ -101,7 +101,7 @@ menuentry "Boot from Hard Disk" --class opensuse --class gnu-linux --class gnu - menuentry "Install $label" --class os --unrestricted { echo 'Loading kernel...' - linux /boot/ppc64le/linux + linux /boot/ppc64le/linux splash=silent echo 'Loading initrd...' initrd /boot/ppc64le/initrd } diff --git a/live/config-cdroot/fix_bootconfig.x86_64 b/live/config-cdroot/fix_bootconfig.x86_64 index 3fbadfbe61..13790df722 100755 --- a/live/config-cdroot/fix_bootconfig.x86_64 +++ b/live/config-cdroot/fix_bootconfig.x86_64 @@ -90,7 +90,7 @@ menuentry "Boot from Hard Disk" --class opensuse --class gnu-linux --class gnu - menuentry "Install $label" --class os --unrestricted { set gfxpayload=keep echo Loading kernel... - linux (\$root)/boot/x86_64/loader/linux \${extra_cmdline} \${isoboot} + linux (\$root)/boot/x86_64/loader/linux \${extra_cmdline} \${isoboot} splash=silent echo Loading initrd... initrd (\$root)/boot/x86_64/loader/initrd } diff --git a/live/live-root/etc/systemd/system/agama-hostname.service b/live/live-root/etc/systemd/system/agama-hostname.service index b1f7496660..b39da3a1e5 100644 --- a/live/live-root/etc/systemd/system/agama-hostname.service +++ b/live/live-root/etc/systemd/system/agama-hostname.service @@ -6,7 +6,8 @@ After=systemd-hostnamed.target Before=avahi-daemon.service # run only if the hostname has the default value, if it has been changed # by the kernel command line or systemd then keep it -ConditionHost=localhost +ConditionHost=|localhost +ConditionHost=|localhost.localdomain [Service] ExecStart=hostnamectl hostname --transient agama diff --git a/live/live-root/etc/systemd/system/agama-self-update.service b/live/live-root/etc/systemd/system/agama-self-update.service deleted file mode 100644 index 5d425d0354..0000000000 --- a/live/live-root/etc/systemd/system/agama-self-update.service +++ /dev/null @@ -1,28 +0,0 @@ -[Unit] -Description=Agama self-update - -After=network-online.target - -# and after we process agama params like info which can contain password -After=agama-cmdline-process.service - -# before starting the Agama servers so they use the new packages -Before=agama-web-server.service -Before=agama.service -# before interactive password services -Before=live-password-dialog.service -Before=live-password-systemd.service - -[Service] -Type=oneshot -Environment=TERM=linux -ExecStartPre=dmesg --console-off -ExecStart=agama-self-update -ExecStartPost=dmesg --console-on -TTYReset=yes -TTYVHangup=yes -StandardInput=tty -TimeoutStartSec=infinity - -[Install] -WantedBy=multi-user.target diff --git a/live/live-root/etc/systemd/system/live-self-update.service b/live/live-root/etc/systemd/system/live-self-update.service new file mode 100644 index 0000000000..ecd6e570b5 --- /dev/null +++ b/live/live-root/etc/systemd/system/live-self-update.service @@ -0,0 +1,29 @@ +[Unit] +Description=Live system self update +DefaultDependencies=no + +# see https://man7.org/linux/man-pages/man7/dracut.bootup.7.html +# for the dependency order of the dracut services + +# after network is configured +After=network-online.target +# after /sysroot is mounted +After=initrd-fs.target +# before running the pre-pivot dracut hooks (before the driver update) +Before=dracut-pre-pivot.service +# flag to skip the self-update +ConditionPathExists=!/run/live-self-update/skip + +[Service] +Type=oneshot +ExecStart=live-self-update +StandardOutput=journal+console +# always wait until the self update is fully finished, booting a half updated +# system could have nasty side effects, if the service gets stuck it can be +# manually disabled with the "inst.self_update=0" boot parameter +TimeoutStartSec=infinity +SyslogIdentifier=live-self-update +RemainAfterExit=true + +[Install] +WantedBy=initrd.target diff --git a/live/live-root/root/.bash_history b/live/live-root/root/.bash_history index 976fc64fb8..09b67dd593 100644 --- a/live/live-root/root/.bash_history +++ b/live/live-root/root/.bash_history @@ -5,5 +5,6 @@ journalctl -u agama-web-server.service journalctl -u agama.service systemctl status agama-web-server.service systemctl status agama.service +journalctl -t live-self-update agama config show | jq agama logs store diff --git a/live/live-root/usr/bin/agama-self-update b/live/live-root/usr/bin/agama-self-update deleted file mode 100755 index 147371d12a..0000000000 --- a/live/live-root/usr/bin/agama-self-update +++ /dev/null @@ -1,31 +0,0 @@ -#! /bin/sh - -# Experimental Agama self-update script -# -# This script updates the Agama packages in the Live system from the -# Agama Devel OBS project. - -# check if self-update is required -if ! grep -q "\b\(inst\|agama\)\.self_update=1\b" /run/agama/cmdline.d/agama.conf; then - exit 0 -fi - -# first try a quick and simple solution, refreshing the distributions repository takes a -# lot of time so try using only the agama-devel for update -zypper modifyrepo --disable --all -zypper modifyrepo --enable agama-devel -zypper refresh -zypper --non-interactive dup --details --from agama-devel -STATUS=$? - -# enable all repositories back -zypper modifyrepo --enable --all - -# if it failed try it again with all the repos enabled, maybe there was some -# dependency problem which hopefully will be OK now -if [ "$?" != "0" ]; then - zypper --non-interactive dup --details --from agama-devel -fi - -# clean all repository caches to save space in RAM disk -zypper clean --all diff --git a/live/live-root/usr/bin/live-self-update b/live/live-root/usr/bin/live-self-update new file mode 100755 index 0000000000..a9354f18b6 --- /dev/null +++ b/live/live-root/usr/bin/live-self-update @@ -0,0 +1,322 @@ +#! /bin/bash + +shopt -s nullglob + +[ -e /dracut-state.sh ] && . /dracut-state.sh + +# Later we could disable "-x" or enable it on request, let's be more verbose in +# the initial implementation. Since we have enabled using the plymouth splash +# screen the verbose details will not be visible to users by default. +set -ex + +. "$(dirname "$0")"/../lib/live-self-update/conf.sh + +RESPONSE_FILE="$RUN_DIR/server_response" +REG_REPO_FILE="$RUN_DIR/reg_repos" +OSR="/etc/os-release" +ARCH=$(uname -m) + +# do the cleanup at the end, trap ensures it runs even if something fails +trap cleanup_chroot EXIT + +# helper function to log important steps (highlighted in the journalctl output) +# use "set +x" to avoid logging the message again (it is already logged in the +# original caller place so it would be actually logged three times...) +# see https://www.freedesktop.org/software/systemd/man/latest/sd-daemon.html +# for the log level numbers +milestone() { + ({ set +x; } 2>/dev/null; echo "<5>$1") +} + +# log warning +warning() { + ({ set +x; } 2>/dev/null; echo "<4>$1") +} + +# log error +error() { + ({ set +x; } 2>/dev/null; echo "<3>$1") +} + +# normal message +info() { + ({ set +x; } 2>/dev/null; echo "<6>$1") +} + +# the proxy might contain a password, make sure it is not displayed or logged +# when processing it +set +x +# get the configured network proxy (empty string if not configured) +# see ../lib/dracut/modules.d/98dracut-menu/dracut-cmdline-menu.sh +# get the last found, it has the highest priority +PROXY=$(grep "\bproxy=" /proc/cmdline /etc/cmdline.d/* | tail -n 1 | sed "s/.*\bproxy=\([^ \t]*\).*/\1/") + +if [ -n "$PROXY" ]; then + if [[ "$PROXY" == *@* ]]; then + # looks like there is a username or password in the URL, do not print it + milestone "Using authenticated HTTP proxy" + else + milestone "Using proxy server $PROXY" + fi + + # set the proxy for all zypper and curl calls, for security reasons curl + # uses only the lower case name, zypper accepts that as well, + # see https://everything.curl.dev/usingcurl/proxies/env.html + export http_proxy="$PROXY" + export https_proxy="$PROXY" + + # hide the original URL to avoid leaking the password in URL later + PROXY=1 +fi +set -x + +# helper for running a command in the live root system, works both when running +# in initramfs ($NEWROOT is set) and in already mounted root ($NEWROOT unset) +run_command() { + if [ -z "$NEWROOT" ]; then + "$@" + else + "$NEWROOT/usr/bin/chroot" "$NEWROOT" "$@" + fi +} + +# Prepare the system root to be used by scripts before switching to it. +prepare_chroot() { + if [ -n "$NEWROOT" ]; then + milestone "Preparing for the self update..." + + # make system directories active also in the chroot directory + mount -o bind /run "$NEWROOT"/run + mount -o bind /sys "$NEWROOT"/sys + mount -o bind /proc "$NEWROOT"/proc + mount -o bind /dev "$NEWROOT"/dev + [ -f /run/NetworkManager/resolv.conf ] && cp /run/NetworkManager/resolv.conf "$NEWROOT"/etc/resolv.conf + fi + # remove any existing self-update repositories, probably left-overs from the previous run + rm -f "$NEWROOT"/etc/zypp/repos.d/self-update-*.repo +} + +# Revert the changes done by prepare_chroot() and restore the system to the +# original state, called from bash "trap" handler +cleanup_chroot() { + local result="$?" + + if [ "$result" != "0" ]; then + error "Error: Self update failed! (exit status: $result)" + else + milestone "Self update successfully finished" + fi + + # log the result to be checked by openQA or Agama itself + echo "$result" > "$RESULT_FILE" + + if [ -n "$NEWROOT" ]; then + rm -f "$NEWROOT"/etc/resolv.conf + # do not fail if not mounted + findmnt "$NEWROOT"/run > /dev/null && umount "$NEWROOT"/run + findmnt "$NEWROOT"/sys > /dev/null && umount "$NEWROOT"/sys + findmnt "$NEWROOT"/proc > /dev/null && umount "$NEWROOT"/proc + findmnt "$NEWROOT"/dev > /dev/null && umount "$NEWROOT"/dev + fi +} + +# read the data from /etc/os-release file (source it) +read_os_release() { + # get the product data + if [ -f "$OSR" ]; then + . "$OSR" + else + error "File $OSR is missing!" + exit 1 + fi +} + +# ask the registration server (SCC or RMT) for the self-update URL +query_reg_server() { + local server + # custom server (RMT) + if [ -f "$SERVER_FILE" ]; then + server=$(< "$SERVER_FILE") + # default server (SCC) + elif [ -f "$CONFIG_DEFAULT_REG_SERVER_FILE" ]; then + server=$(< "$CONFIG_DEFAULT_REG_SERVER_FILE") + fi + + if [ -n "$server" ]; then + read_os_release + + local query + query="$server/connect/repositories/installer?identifier=$NAME&version=$VERSION_ID&arch=$ARCH" + info "Running query $query...." + + local curl_options + curl_options=(--silent --globoff --location --retry 3 --retry-connrefused \ + --connect-timeout 20 --max-time 10 --fail --show-error --output "$RESPONSE_FILE") + + if grep -q "\binst.self_update_ssl=0\b" /run/agama/cmdline.d/agama.conf; then + warning "Disabling SSL check for $server" + curl_options+=("--insecure") + fi + + if [ -n "$PROXY" ]; then + # automatically detect the proxy authentication method (basic/digest) + curl_options+=("--proxy-anyauth") + fi + + if curl "${curl_options[@]}" -- "$query" && [ -s "$RESPONSE_FILE" ]; then + info "Found self-update repository: $(jq -r ".[] | select(.installer_updates==true) | .description" "$RESPONSE_FILE") " + jq -r ".[] | select(.installer_updates==true) | .url" "$RESPONSE_FILE" > "$REG_REPO_FILE" + else + warning "Contacting the registration server failed" + # SCC/RMT query failed and no fallback configured + if [ ! -s "$CONFIG_FALLBACK_FILE" ]; then + error "Cannot obtain the self-update repository" + exit 1 + fi + fi + else + milestone "Registration server not defined" + fi +} + +# add the self-update repositories into the system +add_update_repos() { + milestone "Adding self update repositories..." + # add the self-update repositories + while read -r update_url; do + if [ -n "$update_url" ]; then + local repo + repo="self-update-$index" + + if grep -q "\binst.self_update_ssl=0\b" /run/agama/cmdline.d/agama.conf; then + warning "Disabling SSL check for repository $update_url" + # add "ssl_verify=no" query to the repository URL + update_url=$(url_add_query "$update_url" "ssl_verify=no") + fi + + local zypper_options + zypper_options=() + # allow using unsigned repository + if grep -q "\binst.self_update_unsigned_repo=1\b" /run/agama/cmdline.d/agama.conf; then + warning "Unsigned repository is allowed" + zypper_options+=("--gpgcheck-allow-unsigned-repo") + fi + + # completely disable GPG checks, not recommended, if possible the options + # above should be preferred + if grep -q "\binst.self_update_gpg=0\b" /run/agama/cmdline.d/agama.conf; then + warning "Disabling all GPG checks!" + zypper_options+=("--no-gpgcheck") + fi + + run_command zypper addrepo "${zypper_options[@]}" -f "$update_url" "$repo" + self_update_repos+=("$repo") + ((++index)) + fi + done < "$1" +} + +# Reads the configured fallback repository, the URL might contain several +# placeholders. This way, it works across multiple architectures and does not +# contain a hardcoded version (the fallback URL should work with SLES-16.0, +# SLES-16.1, SLES-16.2...) +read_fallback_repos() { + # Substituting $arch pattern with the architecture of the current system. + # Substituting these variables with the /etc/os-release content: + # $os_release_name => NAME + # $os_release_id => ID + # $os_release_version => VERSION + # $os_release_version_id => VERSION_ID + # IMPORTANT NOTE: the "VERSION_ID" replacement must happen *before* + # the "VERSION" replacement because it partially matches that string! + sed -e "s/\$os_release_name/$NAME/g" -e "s/\$os_release_id/$ID/g" \ + -e "s/\$os_release_version_id/$VERSION_ID/g" \ + -e "s/\$os_release_version/$VERSION/g" \ + -e "s/\$arch/$ARCH/g" "$CONFIG_FALLBACK_FILE" > "$FALLBACK_REPOS_FILE" +} + +# Applies all the updates +# +# Reads the URL of the updates from $AGAMA_DUD_INFO and process each one. +install_updates() { + index=0 + self_update_repos=() + + if [ -f "$REPO_FILE" ]; then + prepare_chroot + add_update_repos "$REPO_FILE" + else + # try SCC/RMT + query_reg_server + + # repo from the registration server + if [ -s "$REG_REPO_FILE" ]; then + prepare_chroot + add_update_repos "$REG_REPO_FILE" + # use a fallback URL + elif [ -s "$CONFIG_FALLBACK_FILE" ]; then + milestone "Using fallback repository" + read_fallback_repos + prepare_chroot + add_update_repos "$FALLBACK_REPOS_FILE" + # no self-update repo found, exit (in the openSUSE installer) + else + milestone "No self-update repository configured, skipping self-update" + exit 0 + fi + fi + + local zypper_options + # automatically import the repository GPG key + if grep -q "\binst.self_update_import_key=1\b" /run/agama/cmdline.d/agama.conf; then + warning "Enabled GPG key autoimport" + zypper_options="--gpg-auto-import-keys" + fi + + milestone "Loading repositories..." + run_command zypper $zypper_options refresh "${self_update_repos[@]}" + + # build the list of repository options passed to zypper + repo_options=() + for repo in "${self_update_repos[@]}"; do + repo_options+=("--repo" "$repo") + done + + milestone "Updating packages..." + # update the system only using the predefined self-update repositories, + # allow downgrading and changing vendor (can be useful for testing) + run_command zypper --non-interactive update --allow-downgrade --allow-vendor-change --details --no-recommends "${repo_options[@]}" + + milestone "Cleaning the system..." + # delete the repository caches, not needed anymore, saves space in RAM disk + run_command zypper clean --all + + # disable the self update repositories (keep them for debugging purposes) + for repo in "${self_update_repos[@]}"; do + run_command zypper modifyrepo --disable "$repo" + done +} + +# add a query parameter to URL +# $1 - base URL ("http://example.com") +# $2 - the query part ("foo=bar") +# returns "http://example.com?foo=bar" +url_add_query() { + local base + local query + + # split the string at the "?" separator + query="${1#*\?}" + base="${1%\?*}" + + # if the "?" separator is missing then "$query" equals to "$base" + if [ -z "$query" ] || [ "$query" = "$base" ]; then + # no query present, add a query part to the URL + echo "${base}?${2}" + else + # a query is already present, append the new part + echo "${base}?${query}&${2}" + fi +} + +install_updates diff --git a/live/live-root/usr/lib/dracut/modules.d/99agama-dud/agama-dud-apply.sh b/live/live-root/usr/lib/dracut/modules.d/99agama-dud/agama-dud-apply.sh index e866613b1e..3db275b13f 100644 --- a/live/live-root/usr/lib/dracut/modules.d/99agama-dud/agama-dud-apply.sh +++ b/live/live-root/usr/lib/dracut/modules.d/99agama-dud/agama-dud-apply.sh @@ -245,7 +245,7 @@ update_kernel_modules() { setup_from_modules_order() { dud_modules_dir=$1 - module_order=$(<"${dud_modules_dir}/module.order") + readarray -t module_order <"${dud_modules_dir}/module.order" # unload the modules in reverse order local idx idx=("${!module_order[@]}") @@ -253,7 +253,7 @@ setup_from_modules_order() { rmmod "${module_order[$i]}" 2>&1 done - cp "${dud_modules_dir}/module.order" "${NEWROOT}/etc/modules-load.d/99-agama.conf" + cat "${dud_modules_dir}/module.order" >>"${NEWROOT}/etc/modules-load.d/99-agama.conf" } # Sets up the kernel modules. diff --git a/live/live-root/usr/lib/dracut/modules.d/99live-self-update/live-self-update-parser.sh b/live/live-root/usr/lib/dracut/modules.d/99live-self-update/live-self-update-parser.sh new file mode 100755 index 0000000000..0ddc47fb23 --- /dev/null +++ b/live/live-root/usr/lib/dracut/modules.d/99live-self-update/live-self-update-parser.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# redirect stdout/stderr to systemd journal using the "live-self-update" +# identifier, later the self-update logs can be filtered by using command +# "journalctl -t live-self-update" which includes the output from this dracut +# hook and the self-update service as well +exec > >(systemd-cat -t live-self-update) 2>&1 + +. /lib/dracut-lib.sh +# generate Dracut command line options +FILE="/etc/cmdline.d/live-self-update-generated.conf" + +# source the shared self-update configuration variables +. ./lib/live-self-update/conf.sh + +mkdir -p "$RUN_DIR" + +configure_network() { + # skip the network configuration if "rd.neednet=0" option was used by user + if getargbool 1 rd.neednet; then + echo "<5>Enabling network configuration" + echo "rd.neednet=1" > "$FILE" + # use DHCP if there is no network configuration provided by user + if ! getarg "ip="; then + echo "Using default DHCP network configuration" + echo "ip=dhcp" >> "$FILE" + fi + else + echo "<5>Network configuration disabled by the rd.neednet=0 boot parameter" + fi +} + +# skip self-update, either it was explicitly disabled by user or is not +# configured in the product (like openSUSE) +skip() { + echo "<5>$1" + # create a skip file + true > "$SKIP_FILE" +} + +# evaluate the registration server (SCC or RMT) +get_reg_server() { + local url + url=$(getargs "inst.register_url=") + + if [ -n "$url" ]; then + echo "<5>Will use a custom registration server $url for obtaining the self-update repository" + echo "$url" > "$SERVER_FILE" + configure_network + elif [ -s "$CONFIG_DEFAULT_REG_SERVER_FILE" ]; then + echo "<5>Will use the default registration server $(cat "$CONFIG_DEFAULT_REG_SERVER_FILE") for obtaining the self-update repository" + configure_network + elif [ -s "$CONFIG_FALLBACK_FILE" ]; then + echo "<5>Will use the fallback self-update URL $(cat "$CONFIG_FALLBACK_FILE")" + configure_network + else + skip "Self update not configured" + fi +} + +# evaluate the self-update URL: +# 1. explicitly set with the "inst.self_update" boot option +# 2. SCC or RMT server is configured (it will be asked later) +# 3. fallback URL if present +# 4. if no URL is set self-update is skipped +get_url() { + local url + url=$(getargs "inst.self_update=") + + if [ "$url" == "0" ]; then + skip "Self update disabled via boot parameter" + elif [ -z "$url" ]; then + get_reg_server + else + echo "<5>Using custom self update repository: $url" + echo "$url" > "$REPO_FILE" + + # automatically configure network when a remote self-update repository is used, + # match all remote protocols supported by zypper (see "man zypper"), + if grep -q -s -E -e "https?://" -e "ftp://" -e "smb://" -e "cifs://" -e "nfs4?://" -e "obs://" "$REPO_FILE"; then + configure_network + fi + fi +} + +get_url diff --git a/live/live-root/usr/lib/dracut/modules.d/99live-self-update/module-setup.sh b/live/live-root/usr/lib/dracut/modules.d/99live-self-update/module-setup.sh new file mode 100755 index 0000000000..9b920f1375 --- /dev/null +++ b/live/live-root/usr/lib/dracut/modules.d/99live-self-update/module-setup.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# module-setup.sh for Agama self-update +# see https://www.man7.org/linux/man-pages/man7/dracut.modules.7.html + +# called by dracut +check() { + # always include this dracut module in the initramfs + return 0 +} + +# called by dracut +depends() { + echo network + return 0 +} + +installkernel() { + return 0 +} + +# install hook for dracut +install() { + # install the hook for processing the boot parameters + inst_hook cmdline 99 "$moddir/live-self-update-parser.sh" + + # needed by the live-self-update-parser.sh script + inst_multiple systemd-cat dirname /usr/lib/live-self-update/conf.sh jq + + # install the systemd service and the self-update script to the initramfs + inst_multiple "$systemdsystemconfdir"/live-self-update.service live-self-update + + # needed by the live-self-update script + inst_multiple grep tail sed + + # include the self-update configuration if present + if [ -d /etc/live-self-update ]; then + . /usr/lib/live-self-update/conf.sh + + if [ -f "$CONFIG_DEFAULT_REG_SERVER_FILE" ]; then + inst_simple "$CONFIG_DEFAULT_REG_SERVER_FILE" + fi + + if [ -f "$CONFIG_FALLBACK_FILE" ]; then + inst_simple "$CONFIG_FALLBACK_FILE" + fi + fi + + # enable the self-update service in the initramfs + $SYSTEMCTL -q --root "$initdir" enable live-self-update.service +} diff --git a/live/live-root/usr/lib/live-self-update/conf.sh b/live/live-root/usr/lib/live-self-update/conf.sh new file mode 100644 index 0000000000..d4b9918760 --- /dev/null +++ b/live/live-root/usr/lib/live-self-update/conf.sh @@ -0,0 +1,17 @@ +# this is a shared configuration for the live-self-update script, the +# live-self-update-parser.sh dracut hook script and the Kiwi config.sh + +RUN_DIR="/run/live-self-update" +REPO_FILE="$RUN_DIR/repositories" +SERVER_FILE="$RUN_DIR/server" +SKIP_FILE="$RUN_DIR/skip" +RESULT_FILE="$RUN_DIR/result" + +CONFIG_DIR="/etc/live-self-update" +# file with fallback repositories (template URLs) +CONFIG_FALLBACK_FILE="$CONFIG_DIR/fallback_url" +# default registration server URL (SCC in SLE, undefined in openSUSE) +CONFIG_DEFAULT_REG_SERVER_FILE="$CONFIG_DIR/default_reg_server_url" + +# fallback repositories with expanded variables +FALLBACK_REPOS_FILE="${CONFIG_FALLBACK_FILE}_expanded" diff --git a/live/src/agama-installer.changes b/live/src/agama-installer.changes index b40e4dbe00..2bc6e82019 100644 --- a/live/src/agama-installer.changes +++ b/live/src/agama-installer.changes @@ -1,3 +1,71 @@ +------------------------------------------------------------------- +Wed Nov 12 15:42:29 UTC 2025 - Imobach Gonzalez Sosa + +- Version 18 + +------------------------------------------------------------------- +Wed Nov 5 09:17:43 UTC 2025 - Ladislav Slezák + +- Include the AMD GPU firmware files (bsc#1250952) + +------------------------------------------------------------------- +Mon Nov 3 07:54:50 UTC 2025 - Ladislav Slezák + +- Improved installer self-update (jsc#PED-12506): + - Enable using an HTTP proxy for the self-update process + (specified via the "proxy=" boot parameter or configured + interactively using the "rd.cmdline=menu") + - Fixed fallback to the default self-update URL when contacting + the registration server (SCC/RMT) fails + +------------------------------------------------------------------- +Fri Oct 31 10:17:41 UTC 2025 - Ladislav Slezák + +- Added installer self-update support (jsc#PED-12506) + - Supports SCC/RMT server (SCC is the default, RMT via + inst.register_url= option) + - Custom repository is supported (inst.self_update=) + - Can be skipped optionally (inst.self_update=0) + +------------------------------------------------------------------- +Fri Oct 24 11:09:56 UTC 2025 - Ladislav Slezák + +- Dump some Live ISO root image data directly to the ISO image, + added files: + /LiveOS/.info - a copy of the /var/log/build/info file from + the root image + /LiveOS/.packages.gz - list of installed package (plain text, + basically a `rpm -qa` dump) + /LiveOS/.packages.json.gz - list of installed packages (JSON + format, better suitable for processing by scripts or tools) + (gh#agama-project/agama#2717) + +------------------------------------------------------------------- +Wed Oct 22 05:34:43 UTC 2025 - Imobach Gonzalez Sosa + +- Remove kernel-default-extra and kernel-default-optional from + SLES 16 images (bsc#1249690). + +------------------------------------------------------------------- +Tue Oct 21 20:10:44 UTC 2025 - Josef Reidinger + +- Enable plymouth bootsplash for agama and also propose it for + target systems if user keep it for agama on kernel command line + (bsc#1248507) + +------------------------------------------------------------------- +Tue Oct 14 08:19:36 UTC 2025 - Imobach Gonzalez Sosa + +- Properly unload files in module.order file (bsc#1251898). +- Append modules name to /etc/modules-load.d/99-agama.conf instead + of overwriting the file. + +------------------------------------------------------------------- +Fri Oct 3 08:19:08 UTC 2025 - Ancor Gonzalez Sosa + +- Backport of a fix when deleting repofiles for disabled + repositories (see gh#agama-project/agama#2771). + ------------------------------------------------------------------- Tue Sep 30 14:54:18 UTC 2025 - Ladislav Slezák diff --git a/live/src/agama-installer.kiwi b/live/src/agama-installer.kiwi index ebcf36233e..1c44f36eea 100644 --- a/live/src/agama-installer.kiwi +++ b/live/src/agama-installer.kiwi @@ -24,9 +24,17 @@ Europe/Berlin true false - bgrt + + + openSUSE + + SLE + @@ -115,6 +123,9 @@ + + + @@ -140,6 +151,7 @@ + @@ -160,8 +172,6 @@ - - diff --git a/live/src/config.sh b/live/src/config.sh index d1cdd761e7..bacbac0ed6 100644 --- a/live/src/config.sh +++ b/live/src/config.sh @@ -68,10 +68,15 @@ systemctl enable agama-welcome-issue.service systemctl enable agama-avahi-issue.service systemctl enable agama-url-issue.service systemctl enable agama-ssh-issue.service -systemctl enable agama-self-update.service systemctl enable live-free-space.service systemctl enable live-password.service systemctl enable live-root-shell.service + +# the self-update actually runs in the initramfs system, but the exit status +# is lost if it is not enabled in the root image as well, +# it runs only once in the initramfs because of "WantedBy=initrd.target" +systemctl enable live-self-update.service + systemctl enable checkmedia.service systemctl enable qemu-guest-agent.service systemctl enable setup-systemd-proxy-env.path @@ -105,6 +110,18 @@ touch /etc/udev/rules.d/64-md-raid-assembly.rules # the "eurlatgr" is the default font for the English locale echo -e "\nFONT=eurlatgr.psfu" >> /etc/vconsole.conf +# configure self-update in SLES +if [[ "$kiwi_profiles" == *SLE* ]]; then + echo "Configuring the installer self-update..." + # read the self-update configuration variables + . /usr/lib/live-self-update/conf.sh + mkdir -p "$CONFIG_DIR" + # the default registration server (SCC) if RMT is not set + echo "https://scc.suse.com" > "$CONFIG_DEFAULT_REG_SERVER_FILE" + # fallback URL when contacting SCC/RMT fails or no self-update is returned + echo 'https://installer-updates.suse.com/SUSE/Products/SLE-INSTALLER/$os_release_version_id/$arch/product/' > "$CONFIG_FALLBACK_FILE" +fi + ### setup dracut for live system arch=$(uname -m) # keep in sync with ISO Volume ID set in the fix_bootconfig script @@ -116,7 +133,7 @@ mkdir /etc/cmdline.d echo "root=live:LABEL=$label" >/etc/cmdline.d/10-liveroot.conf echo "root_disk=live:LABEL=$label" >>/etc/cmdline.d/10-liveroot.conf echo 'install_items+=" /etc/cmdline.d/10-liveroot.conf "' >/etc/dracut.conf.d/10-liveroot-file.conf -echo 'add_dracutmodules+=" dracut-menu agama-cmdline agama-dud "' >>/etc/dracut.conf.d/10-liveroot-file.conf +echo 'add_dracutmodules+=" dracut-menu agama-cmdline agama-dud live-self-update "' >>/etc/dracut.conf.d/10-liveroot-file.conf # decrease the kernel logging on the console, use a dracut module to do it early in the boot process echo 'add_dracutmodules+=" agama-logging "' > /etc/dracut.conf.d/10-agama-logging.conf @@ -316,9 +333,6 @@ if [ "$(arch)" == "aarch64" ]; then echo 'install_items+=" /lib/firmware/qcom/sc8280xp/LENOVO/21BX/qcadsp8280.mbn.xz /lib/firmware/qcom/sc8280xp/LENOVO/21BX/qccdsp8280.mbn.xz "' >> /etc/dracut.conf.d/x13s_modules.conf fi -# delete some AMD GPU firmware -rm -rf /lib/firmware/amdgpu/{gc_,isp,psp}* - # Decompress kernel modules, better for squashfs (boo#1192457) find /lib/modules/*/kernel -name '*.ko.xz' -exec xz -d {} + find /lib/modules/*/kernel -name '*.ko.zst' -exec zstd --rm -d {} + diff --git a/products.d/agama-products.changes b/products.d/agama-products.changes index a426958406..0b91a3d9d4 100644 --- a/products.d/agama-products.changes +++ b/products.d/agama-products.changes @@ -1,10 +1,24 @@ +------------------------------------------------------------------- +Thu Nov 13 09:39:58 UTC 2025 - Josef Reidinger + +- Fix removal of kalpa to work also in SLE + +------------------------------------------------------------------- +Wed Nov 12 15:42:28 UTC 2025 - Imobach Gonzalez Sosa + +- Version 18 + +------------------------------------------------------------------- +Fri Oct 17 19:50:58 UTC 2025 - Shawn Dunn + +- Remove Kalpa from multi-distribution installation image. + ------------------------------------------------------------------- Mon Sep 29 04:56:47 UTC 2025 - Lubos Kocman - Update patterns and packages Leap Micro 6.2 Fixes install issues of Leap Micro 6.2 (boo#1250435) - Explicitly add opensuse-migration-tool - ------------------------------------------------------------------- Fri Sep 12 14:30:16 UTC 2025 - Ladislav Slezák diff --git a/products.d/agama-products.spec b/products.d/agama-products.spec index dae5732fd4..9081e45f58 100644 --- a/products.d/agama-products.spec +++ b/products.d/agama-products.spec @@ -42,15 +42,17 @@ env \ %{_builddir}/agama/install.sh +# for now remove kalpa from all builds until it is fixed +rm -f %{buildroot}%{_datadir}/agama/products.d/kalpa.yaml + # Keep only Leap based distros on Leap %if 0%{?is_opensuse} && 0%{?suse_version} == 1600 -rm -f %{buildroot}%{_datadir}/agama/products.d/kalpa.yaml rm -f %{buildroot}%{_datadir}/agama/products.d/microos.yaml rm -f %{buildroot}%{_datadir}/agama/products.d/tumbleweed.yaml rm -f %{buildroot}%{_datadir}/agama/products.d/slowroll.yaml %endif -# Keep TW-based distros on TW (drop Leap + Leap Micro) +# Keep TW-based distros on TW (drop Kalpa + Leap + Leap Micro) %if 0%{?is_opensuse} && 0%{?suse_version} > 1600 rm -f %{buildroot}%{_datadir}/agama/products.d/leap*.yaml %endif @@ -71,7 +73,6 @@ Definition of openSUSE products (Tumbleweed, Leap, MicroOS and Slowroll) for the %{_datadir}/agama/products.d/microos.yaml %{_datadir}/agama/products.d/tumbleweed.yaml %{_datadir}/agama/products.d/slowroll.yaml -%{_datadir}/agama/products.d/kalpa.yaml %endif %if !0%{?is_opensuse} || 0%{?suse_version} == 1600 %{_datadir}/agama/products.d/leap_160.yaml @@ -90,7 +91,7 @@ Definition of SLE-based products (e.g., SUSE Linux Enterprise Server) for the Ag %license LICENSE %dir %{_datadir}/agama %dir %{_datadir}/agama/products.d -%{_datadir}/agama/products.d/sles_160.yaml -%{_datadir}/agama/products.d/sles_sap_160.yaml +%{_datadir}/agama/products.d/sles_161.yaml +%{_datadir}/agama/products.d/sles_sap_161.yaml %changelog diff --git a/products.d/kalpa.yaml b/products.d/kalpa.yaml index 5434add196..fb3d0affef 100644 --- a/products.d/kalpa.yaml +++ b/products.d/kalpa.yaml @@ -20,7 +20,7 @@ translations: Pro doručování aplikací používá Flatpak, dále má základ systému pouze pro čtení s atomickými aktualizacemi, které probíhají automaticky de: Ein rollierend veröffentlichtes unveränderliches Desktop-Produkt, welches - den Plasma Desktop und Flatpak für die Anwendungsbereitstellung nutzt, + den Plasma-Desktop und Flatpak für die Anwendungsbereitstellung nutzt, eine Basis mit ausschließlich Lesezugriff besitzt und atomare Aktualisierungen durchführt. es: Un producto inmutable de escritorio de actualización continua, utilizando el diff --git a/products.d/sles_160.yaml b/products.d/sles_161.yaml similarity index 99% rename from products.d/sles_160.yaml rename to products.d/sles_161.yaml index ff7ac7f13a..19fddb5880 100644 --- a/products.d/sles_160.yaml +++ b/products.d/sles_161.yaml @@ -1,7 +1,7 @@ id: SLES -name: SUSE Linux Enterprise Server 16.0 +name: SUSE Linux Enterprise Server 16.1 registration: true -version: "16.0" +version: "16.1" license: "license.final" # ------------------------------------------------------------------------------ # WARNING: When changing the product description delete the translations located diff --git a/products.d/sles_sap_160.yaml b/products.d/sles_sap_161.yaml similarity index 95% rename from products.d/sles_sap_160.yaml rename to products.d/sles_sap_161.yaml index 1ecbfe5817..227a3b0f4e 100644 --- a/products.d/sles_sap_160.yaml +++ b/products.d/sles_sap_161.yaml @@ -1,8 +1,8 @@ id: SLES_SAP -name: SUSE Linux Enterprise Server for SAP applications 16.0 +name: SUSE Linux Enterprise Server for SAP applications 16.1 archs: x86_64,ppc registration: true -version: "16.0" +version: "16.1" license: "license.final" # ------------------------------------------------------------------------------ # WARNING: When changing the product description delete the translations located @@ -65,6 +65,10 @@ translations: Godkänd för SAP utrullningar, SUSE Linux Enterprise Server för SAP-applikationer framtidssäkrar SAP-projektet, erbjuder oavbrutna affärer och minimerar operativa risker och kostnader. + tr: Güvenli ve sağlam bir SAP platformu için önde gelen işletim sistemi. SAP + dağıtımları için onaylanan SUSE Linux Enterprise Server for SAP, + uygulamaları SAP projesini geleceğe hazır hale getirir, kesintisiz işleyiş + sağlar ve operasyonel riskleri ve maliyetleri en aza indirir. uk: "Провідна ОС для безпечної та надійної роботи SAP: сертифікована для SAP, забезпечує стабільність, знижує ризики та витрати." zh_CN: 作为SAP平台安全可靠的优选操作系统, SUSE Linux Enterprise Server for SAP diff --git a/rust/Cargo.lock b/rust/Cargo.lock index b201f0e9ae..02517278e1 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.0" @@ -25,7 +16,7 @@ dependencies = [ "agama-utils", "anyhow", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "url", ] @@ -49,7 +40,7 @@ dependencies = [ "reqwest", "serde_json", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "url", ] @@ -65,7 +56,7 @@ dependencies = [ "gettext-rs", "regex", "test-context", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-test", @@ -103,7 +94,7 @@ dependencies = [ "serde_with", "strum", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-native-tls", "tokio-stream", @@ -124,7 +115,7 @@ dependencies = [ "quick-xml", "regex", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "utoipa", ] @@ -141,7 +132,7 @@ dependencies = [ "merge-struct", "serde_json", "test-context", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-test", "tracing", @@ -163,7 +154,7 @@ dependencies = [ "serde", "serde_with", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-test", @@ -213,7 +204,7 @@ dependencies = [ "subprocess", "tempfile", "test-context", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-openssl", "tokio-stream", @@ -245,7 +236,7 @@ dependencies = [ "serde_with", "serde_yaml", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -262,7 +253,7 @@ dependencies = [ "serde", "serde_json", "test-context", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-test", @@ -285,7 +276,7 @@ dependencies = [ "serde_yaml", "strum", "test-context", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-test", @@ -401,9 +392,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arraydeque" @@ -778,21 +769,6 @@ dependencies = [ "syn 2.0.101", ] -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base64" version = "0.21.7" @@ -1025,7 +1001,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link 0.1.3", + "windows-link 0.1.1", ] [[package]] @@ -1356,9 +1332,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ "darling_core", "darling_macro", @@ -1366,9 +1342,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", @@ -1380,9 +1356,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", @@ -1876,12 +1852,6 @@ dependencies = [ "temp-dir", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "glob" version = "0.3.2" @@ -2428,17 +2398,6 @@ dependencies = [ "unicode-width 0.1.14", ] -[[package]] -name = "io-uring" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" -dependencies = [ - "bitflags 2.9.0", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -2659,7 +2618,7 @@ dependencies = [ "once_cell", "serde", "sha2", - "thiserror 2.0.16", + "thiserror 2.0.17", "uuid", ] @@ -3067,15 +3026,6 @@ dependencies = [ "objc", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -3258,7 +3208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" dependencies = [ "memchr", - "thiserror 2.0.16", + "thiserror 2.0.17", "ucd-trie", ] @@ -3765,12 +3715,6 @@ dependencies = [ "trim-in-place", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -3892,9 +3836,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" dependencies = [ "dyn-clone", "ref-cast", @@ -3978,14 +3922,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -4042,9 +3987,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "10574371d41b0d9b2cff89418eda27da52bcaff2cc8741db26382a77c29131f1" dependencies = [ "base64 0.22.1", "chrono", @@ -4052,9 +3997,8 @@ dependencies = [ "indexmap 1.9.3", "indexmap 2.9.0", "schemars 0.9.0", - "schemars 1.0.4", - "serde", - "serde_derive", + "schemars 1.1.0", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -4062,9 +4006,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "08a72d8216842fdd57820dc78d840bef99248e35fb2554ff923319e60f2d686b" dependencies = [ "darling", "proc-macro2", @@ -4166,7 +4110,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", ] @@ -4420,11 +4364,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -4440,9 +4384,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -4511,29 +4455,26 @@ dependencies = [ [[package]] name = "tokio" -version = "1.47.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio 1.0.3", "pin-project-lite", "signal-hook-registry", - "slab", "socket2 0.6.0", "tokio-macros", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -4840,7 +4781,7 @@ dependencies = [ "native-tls", "rand 0.9.1", "sha1", - "thiserror 2.0.16", + "thiserror 2.0.17", "utf-8", ] @@ -4953,9 +4894,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utoipa" -version = "5.4.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" +checksum = "435c6f69ef38c9017b4b4eea965dfb91e71e53d869e896db40d1cf2441dd75c0" dependencies = [ "indexmap 2.9.0", "serde", @@ -4965,9 +4906,9 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "5.4.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" +checksum = "a77d306bc75294fd52f3e99b13ece67c02c1a2789190a6f31d32f736624326f7" dependencies = [ "proc-macro2", "quote", @@ -5216,7 +5157,7 @@ checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.1.3", + "windows-link 0.1.1", "windows-result", "windows-strings 0.4.0", ] @@ -5245,9 +5186,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.3" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-link" @@ -5263,7 +5204,7 @@ checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ "windows-result", "windows-strings 0.3.1", - "windows-targets 0.53.3", + "windows-targets 0.53.0", ] [[package]] @@ -5272,7 +5213,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ - "windows-link 0.1.3", + "windows-link 0.1.1", ] [[package]] @@ -5281,7 +5222,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-link 0.1.3", + "windows-link 0.1.1", ] [[package]] @@ -5290,7 +5231,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" dependencies = [ - "windows-link 0.1.3", + "windows-link 0.1.1", ] [[package]] @@ -5322,11 +5263,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.60.2" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.53.3", + "windows-link 0.2.1", ] [[package]] @@ -5362,11 +5303,10 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" dependencies = [ - "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -5594,9 +5534,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7" +checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91" dependencies = [ "async-broadcast", "async-executor", @@ -5619,7 +5559,8 @@ dependencies = [ "tokio", "tracing", "uds_windows", - "windows-sys 0.60.2", + "uuid", + "windows-sys 0.61.2", "winnow", "zbus_macros", "zbus_names", @@ -5628,9 +5569,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca" +checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314" dependencies = [ "proc-macro-crate", "proc-macro2", diff --git a/rust/agama-cli/src/cli_input.rs b/rust/agama-cli/src/cli_input.rs index f54cb1ec36..61fa559d6b 100644 --- a/rust/agama-cli/src/cli_input.rs +++ b/rust/agama-cli/src/cli_input.rs @@ -21,11 +21,10 @@ use agama_lib::utils::Transfer; use anyhow::Context; use std::{ - io, + collections::HashMap, io::Read, path::{Path, PathBuf}, }; -use url::Url; /// Represents the ways user can specify the input on the command line /// and passes appropriate representations to the web API @@ -58,26 +57,28 @@ impl From for CliInput { } impl CliInput { - /// If *self* has a path or URL value, append a `path=...` or `url=...` - /// query parameter to *url*, properly escaped. The path is made absolute - /// so that it works (on localhost) even if server's working directory is different. - /// See also: [`body_for_web`](Self::body_for_web). - pub fn add_query(&self, base_url: &mut Url) -> io::Result<()> { + /// Creates a HashMap from *self* content. + /// If *self* is stdin or the full text, provide it as String. + /// + /// NOTE that this will consume the standard input + /// if self is `Stdin` + pub fn to_map(&self) -> HashMap { + let mut map = HashMap::new(); + match self { - Self::Url(url) => { - base_url.query_pairs_mut().append_pair("url", url); - } - Self::Path(path) => { - let pathbuf = Self::absolute(Path::new(path))?; - let pathstr = pathbuf - .to_str() - .ok_or(std::io::Error::other("Stringifying current directory"))?; - base_url.query_pairs_mut().append_pair("path", pathstr); - } - Self::Stdin => (), - Self::Full(_) => (), + Self::Url(url) => map.insert(String::from("url"), url.to_string()), + Self::Path(path) => map.insert( + String::from("path"), + Self::absolute(path).unwrap().display().to_string(), + ), + Self::Stdin => map.insert( + String::from("profile"), + Self::stdin_to_string().expect("Reading profile from stdin failed"), + ), + Self::Full(s) => map.insert(String::from("profile"), s.to_string()), }; - Ok(()) + + map } /// Make *path* absolute by prepending the current directory @@ -92,19 +93,6 @@ impl CliInput { } } - /// If *self* is stdin or the full text, provide it as String. - /// See also: `add_query` - /// - /// NOTE that this will consume the standard input - /// if self is `Stdin` - pub fn body_for_web(self) -> std::io::Result { - match self { - Self::Stdin => Self::stdin_to_string(), - Self::Full(s) => Ok(s), - _ => Ok("".to_owned()), - } - } - /// Consume standard input and return it as String. fn stdin_to_string() -> std::io::Result { let mut slurp = String::new(); diff --git a/rust/agama-cli/src/config.rs b/rust/agama-cli/src/config.rs index 975e819a7f..291ea08f0e 100644 --- a/rust/agama-cli/src/config.rs +++ b/rust/agama-cli/src/config.rs @@ -20,6 +20,7 @@ use std::{io::Write, path::PathBuf, process::Command}; +use agama_lib::profile::ProfileHTTPClient; use agama_lib::{ context::InstallationContext, http::BaseHTTPClient, install_settings::InstallSettings, profile::ProfileValidator, profile::ValidationOutcome, utils::FileFormat, @@ -116,7 +117,7 @@ pub async fn run(subcommand: ConfigCommands, opts: GlobalOpts) -> anyhow::Result destination.write(&json)?; eprintln!(); - validate(&http_client, CliInput::Full(json.clone())).await?; + validate(&http_client, CliInput::Full(json.clone()), false).await?; Ok(()) } ConfigCommands::Load { url_or_path } => { @@ -124,7 +125,7 @@ pub async fn run(subcommand: ConfigCommands, opts: GlobalOpts) -> anyhow::Result let store = SettingsStore::new(http_client.clone()).await?; let url_or_path = url_or_path.unwrap_or(CliInput::Stdin); let contents = url_or_path.read_to_string(opts.insecure)?; - let valid = validate(&http_client, CliInput::Full(contents.clone())).await?; + let valid = validate(&http_client, CliInput::Full(contents.clone()), false).await?; if matches!(valid, ValidationOutcome::Valid) { let result = @@ -140,7 +141,7 @@ pub async fn run(subcommand: ConfigCommands, opts: GlobalOpts) -> anyhow::Result ConfigCommands::Validate { url_or_path, local } => { let _ = if !local { let (http_client, _monitor) = build_clients(api_url, opts.insecure).await?; - validate(&http_client, url_or_path).await + validate(&http_client, url_or_path, false).await } else { validate_local(url_or_path, opts.insecure) }; @@ -192,33 +193,19 @@ fn validate_local(url_or_path: CliInput, insecure: bool) -> anyhow::Result anyhow::Result { - // unwrap OK: joining a parsable constant to a valid Url - let mut url = client.base_url.join("profile/validate").unwrap(); - url_or_path.add_query(&mut url)?; - - let body = url_or_path.body_for_web()?; - // we use plain text .body instead of .json - let response = client - .client - .request(reqwest::Method::POST, url) - .body(body) - .send() + let request = url_or_path.to_map(); + let validity = ProfileHTTPClient::new(client.clone()) + .validate(&request) .await?; - Ok(client.deserialize_or_error(response).await?) -} - -async fn validate( - client: &BaseHTTPClient, - url_or_path: CliInput, -) -> anyhow::Result { - let validity = validate_client(client, url_or_path).await?; - let _ = validation_msg(&validity); + if !silent { + let _ = validation_msg(&validity); + } Ok(validity) } @@ -271,13 +258,19 @@ async fn generate( let config_string = match url_or_path { CliInput::Url(url_string) => { let url = Uri::parse(url_string)?; - autoyast_client(client, &url).await? + + ProfileHTTPClient::new(client.clone()) + .from_autoyast(&url) + .await? } CliInput::Path(pathbuf) => { let canon_path = pathbuf.canonicalize()?; let url_string = format!("file://{}", canon_path.display()); let url = Uri::parse(url_string)?; - autoyast_client(client, &url).await? + + ProfileHTTPClient::new(client.clone()) + .from_autoyast(&url) + .await? } _ => panic!("is_autoyast returned true on unnamed input"), }; @@ -286,15 +279,13 @@ async fn generate( from_json_or_jsonnet(client, url_or_path, insecure).await? }; - let validity = validate_client(client, CliInput::Full(profile_json.clone())).await?; - match validity { - ValidationOutcome::NotValid(_) => { - // invalid before InstallSettings processing: print profile and validation result - println!("{}", &profile_json); - eprintln!("{} {}", style("\u{2717}").bold().red(), validity); - return Ok(()); - } - ValidationOutcome::Valid => {} + let validity = validate(client, CliInput::Full(profile_json.clone()), true).await?; + + if matches!(validity, ValidationOutcome::NotValid(_)) { + println!("{}", &profile_json); + let _ = validation_msg(&validity); + + return Ok(()); } // resolves relative URL references @@ -302,42 +293,24 @@ async fn generate( let config_json = serde_json::to_string_pretty(&model)?; println!("{}", &config_json); - let validity = validate_client(client, CliInput::Full(config_json.clone())).await?; - match validity { - ValidationOutcome::Valid => { - eprintln!("{} {}", style("\u{2713}").bold().green(), validity); - } - ValidationOutcome::NotValid(_) => { - let red_x = style("\u{2717}").bold().red(); - eprintln!("{} {}", red_x, validity); - eprintln!( - "{} Internal error: the profile was made invalid by InstallSettings round trip", - red_x - ); - } + let validity = validate(client, CliInput::Full(config_json.clone()), false).await?; + + if matches!(validity, ValidationOutcome::NotValid(_)) { + eprintln!( + "{} Internal error: the profile was made invalid by InstallSettings round trip", + style("\u{2717}").bold().red() + ); } Ok(()) } -/// Process AutoYaST profile (*url* ending with .xml, .erb, or dir/) by doing a HTTP client request. -/// Note that this client does not act on this *url*, it passes it as a parameter -/// to our web backend. -/// Return well-formed Agama JSON on success. -async fn autoyast_client(client: &BaseHTTPClient, url: &Uri) -> anyhow::Result { - // FIXME: how to escape it? - let api_url = format!("/profile/autoyast?url={}", url); - let output: Box = client.post(&api_url, &()).await?; - let config_string = format!("{}", output); - Ok(config_string) -} - -// Retrieve and preprocess the profile. -// -// The profile can be a JSON or a Jsonnet file. -// -// * If it is a JSON file, no preprocessing is needed. -// * If it is a Jsonnet file, it is converted to JSON. +/// Retrieve and preprocess the profile. +/// +/// The profile can be a JSON or a Jsonnet file. +/// +/// * If it is a JSON file, no preprocessing is needed. +/// * If it is a Jsonnet file, it is converted to JSON. async fn from_json_or_jsonnet( client: &BaseHTTPClient, url_or_path: CliInput, @@ -347,7 +320,12 @@ async fn from_json_or_jsonnet( match FileFormat::from_string(&any_profile) { FileFormat::Jsonnet => { - let json_string = evaluate_client(client, CliInput::Full(any_profile)).await?; + let full_profile = CliInput::Full(any_profile); + let request = full_profile.to_map(); + let json_string = ProfileHTTPClient::new(client.clone()) + .from_jsonnet(&request) + .await?; + Ok(json_string) } FileFormat::Json => Ok(any_profile), @@ -357,27 +335,6 @@ async fn from_json_or_jsonnet( } } -/// Evaluate a Jsonnet profile, by doing a HTTP client request. -/// Return well-formed Agama JSON on success. -async fn evaluate_client(client: &BaseHTTPClient, url_or_path: CliInput) -> anyhow::Result { - // unwrap OK: joining a parsable constant to a valid Url - let mut url = client.base_url.join("profile/evaluate").unwrap(); - url_or_path.add_query(&mut url)?; - - let body = url_or_path.body_for_web()?; - // we use plain text .body instead of .json - let response: Result = client - .client - .request(reqwest::Method::POST, url) - .body(body) - .send() - .await - .map_err(|e| e.into()); - - let output: Box = client.deserialize_or_error(response?).await?; - Ok(output.to_string()) -} - /// Edit the installation settings using an external editor. /// /// If the editor does not return a successful error code, it returns an error. @@ -403,7 +360,7 @@ async fn edit( // FIXME: invalid profile still gets loaded let contents = std::fs::read_to_string(&path).context(format!("Reading from file {:?}", path))?; - validate(&http_client, CliInput::Full(contents)).await?; + validate(&http_client, CliInput::Full(contents), false).await?; return Ok(InstallSettings::from_file( path, &InstallationContext::from_env()?, diff --git a/rust/agama-lib/src/profile.rs b/rust/agama-lib/src/profile.rs index a955386293..7d7fc8cb4f 100644 --- a/rust/agama-lib/src/profile.rs +++ b/rust/agama-lib/src/profile.rs @@ -31,6 +31,9 @@ use std::{ use tempfile::{tempdir, TempDir}; use url::Url; +pub mod http_client; +pub use http_client::ProfileHTTPClient; + pub const DEFAULT_SCHEMA_DIR: &str = "/usr/share/agama-cli"; /// Downloads and converts autoyast profile. diff --git a/rust/agama-lib/src/profile/http_client.rs b/rust/agama-lib/src/profile/http_client.rs new file mode 100644 index 0000000000..be05f1d464 --- /dev/null +++ b/rust/agama-lib/src/profile/http_client.rs @@ -0,0 +1,65 @@ +// Copyright (c) [2024] SUSE LLC +// +// All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, contact SUSE LLC. +// +// To contact SUSE LLC about this file by physical or electronic mail, you may +// find current contact information at www.suse.com. + +use crate::http::BaseHTTPClient; +use crate::profile::ValidationOutcome; +use fluent_uri::Uri; +use serde::Serialize; +use std::collections::HashMap; + +pub struct ProfileHTTPClient { + client: BaseHTTPClient, +} + +impl ProfileHTTPClient { + pub fn new(base: BaseHTTPClient) -> Self { + Self { client: base } + } + + /// Validate a JSON profile, by doing a HTTP client request. + pub async fn validate(&self, request: &impl Serialize) -> anyhow::Result { + Ok(self.client.post("profile/validate", request).await?) + } + + /// Evaluate a Jsonnet profile, by doing a HTTP client request. + /// Return well-formed Agama JSON on success. + pub async fn from_jsonnet(&self, request: &impl Serialize) -> anyhow::Result { + let output: Box = + self.client.post("profile/evaluate", request).await?; + + Ok(output.to_string()) + } + + /// Process AutoYaST profile (*url* ending with .xml, .erb, or dir/) by doing a HTTP client request. + /// Note that this client does not act on this *url*, it passes it as a parameter + /// to our web backend. + /// Return well-formed Agama JSON on success. + pub async fn from_autoyast(&self, url: &Uri) -> anyhow::Result { + let mut map = HashMap::new(); + + map.insert(String::from("url"), url.to_string()); + + // FIXME: how to escape it? + let output: Box = + self.client.post("/profile/autoyast", &map).await?; + let config_string = format!("{}", output); + Ok(config_string) + } +} diff --git a/rust/agama-network/src/nm/client.rs b/rust/agama-network/src/nm/client.rs index 2268dd014d..38678a4140 100644 --- a/rust/agama-network/src/nm/client.rs +++ b/rust/agama-network/src/nm/client.rs @@ -542,8 +542,8 @@ impl<'a> NetworkManagerClient<'a> { wireless.password = get_optional_property(&secret, "psk")?; } } - Err(error) => { - tracing::error!("Could not read connection secrets: {:?}", error); + Err(_) => { + tracing::error!("Could not read connection secrets"); } } } diff --git a/rust/agama-network/src/nm/dbus.rs b/rust/agama-network/src/nm/dbus.rs index 13dd8c66c3..b80e437001 100644 --- a/rust/agama-network/src/nm/dbus.rs +++ b/rust/agama-network/src/nm/dbus.rs @@ -434,12 +434,21 @@ fn ip_config_to_ipv4_dbus<'a>( .collect::>() .into(); + let link_local = if ip_config.link_local4 == LinkLocal::Fallback + && VersionReq::parse("<1.52.0").unwrap().matches(nm_version) + { + LinkLocal::Enabled + } else { + ip_config.link_local4 + }; + let mut ipv4_dbus = HashMap::from([ ("address-data", address_data), ("dns-data", dns_data), ("dns-search", ip_config.dns_searchlist.clone().into()), ("ignore-auto-dns", ip_config.ignore_auto_dns.into()), ("method", ip_config.method4.to_string().into()), + ("link-local", (link_local as i32).into()), ]); if !ip_config.routes4.is_empty() { @@ -1083,6 +1092,10 @@ fn ip_config_from_dbus(conn: &OwnedNestedHash) -> Result { ip_config.dns_priority4 = Some(dns_priority4); } + if let Some(link_local4) = get_optional_property::(ipv4, "link-local")? { + ip_config.link_local4 = link_local4.try_into().unwrap_or_default(); + } + let mut dhcp4_settings = Dhcp4Settings::default(); if let Some(dhcp_send_hostname) = get_optional_property(ipv4, "dhcp-send-hostname-v2")? { dhcp4_settings.send_hostname = match dhcp_send_hostname { diff --git a/rust/agama-server/src/profile/web.rs b/rust/agama-server/src/profile/web.rs index 343f5aeae6..4535d8d57d 100644 --- a/rust/agama-server/src/profile/web.rs +++ b/rust/agama-server/src/profile/web.rs @@ -26,7 +26,6 @@ use agama_lib::{ profile::{AutoyastProfileImporter, ProfileEvaluator, ProfileValidator, ValidationOutcome}, }; use axum::{ - extract::Query, http::StatusCode, response::{IntoResponse, Response}, routing::post, @@ -34,6 +33,7 @@ use axum::{ }; use serde::Deserialize; use serde_json::json; +use std::collections::HashMap; use thiserror::Error; use url::Url; @@ -99,28 +99,29 @@ pub async fn profile_service() -> Result { /// 2. pathname (server side) /// 3. URL #[derive(Deserialize, utoipa::IntoParams, Debug)] -struct ProfileQuery { +struct ProfileBody { path: Option, url: Option, + json: Option, } -impl ProfileQuery { - /// Check that exactly one of url=, path=, request body, has been provided. - fn check(&self, request_has_body: bool) -> Result<(), ProfileServiceError> { - // `^` is called Bitwise Xor but it does work correctly on bools - if request_has_body ^ self.path.is_some() ^ self.url.is_some() { - return Ok(()); +impl ProfileBody { + /// Parses given string as a JSON and fills ProfileBody accordingly + /// + /// Expected format is a HashMap, expecte keys are + /// path, url or profile + fn from_string(string: String) -> Self { + let map: HashMap = serde_json::from_str(&string).unwrap_or_default(); + + Self { + path: map.get("path").cloned(), + url: map.get("url").cloned(), + json: map.get("profile").cloned(), } - Err(anyhow::anyhow!( - "Only one of (url=, path=, request body) is expected. Seen: url {}, path {}, body {}", - self.url.is_some(), - self.path.is_some(), - request_has_body - ) - .into()) } - /// Retrieve a profile if specified by one of *url*, *path* + /// Retrieve a profile if specified by one of *url*, *path* or + /// pass already obtained *json* file content fn retrieve_profile(&self) -> Result, ProfileServiceError> { if let Some(url_string) = &self.url { let mut bytebuf = Vec::new(); @@ -133,7 +134,7 @@ impl ProfileQuery { let s = std::fs::read_to_string(path).context(format!("Reading from file {}", path))?; Ok(Some(s)) } else { - Ok(None) + Ok(self.json.clone()) } } } @@ -142,28 +143,23 @@ impl ProfileQuery { post, path = "/validate", context_path = "/api/profile", - params(ProfileQuery), responses( (status = 200, description = "Validation result", body = ValidationOutcome), (status = 400, description = "Some error has occurred") ) )] -async fn validate( - query: Query, - profile: String, // json_or_empty -) -> Result, ProfileServiceError> { - let request_has_body = !profile.is_empty() && profile != "null"; - query.check(request_has_body)?; - let profile_string = match query.retrieve_profile()? { +async fn validate(body: String) -> Result, ProfileServiceError> { + let profile = ProfileBody::from_string(body); + let profile_string = match profile.retrieve_profile()? { Some(retrieved) => retrieved, - None => profile, + None => profile.json.expect("Missing profile"), }; - let validator = ProfileValidator::default_schema().context("Setting up profile validator")?; let result = validator .validate_str(&profile_string) - .context(format!("Could not validate the profile {:?}", *query)) + .context(format!("Could not validate the profile")) .map_err(make_internal)?; + Ok(Json(result)) } @@ -171,27 +167,22 @@ async fn validate( post, path = "/evaluate", context_path = "/api/profile", - params(ProfileQuery), responses( (status = 200, description = "Evaluated profile", body = String, content_type = "application/json"), (status = 400, description = "Some error has occurred") ) )] -async fn evaluate( - query: Query, - profile: String, // jsonnet_or_empty -) -> Result { - let request_has_body = !profile.is_empty() && profile != "null"; - query.check(request_has_body)?; - let profile_string = match query.retrieve_profile()? { +async fn evaluate(body: String) -> Result { + let profile = ProfileBody::from_string(body); + let profile_string = match profile.retrieve_profile()? { Some(retrieved) => retrieved, - None => profile, + None => profile.json.expect("Missing profile"), }; - let evaluator = ProfileEvaluator {}; let output = evaluator .evaluate_string(&profile_string) .context("Could not evaluate the profile".to_string())?; + Ok(output) } @@ -199,28 +190,24 @@ async fn evaluate( post, path = "/autoyast", context_path = "/api/profile", - params(ProfileQuery), responses( (status = 200, description = "AutoYaST profile conversion", body = String, content_type = "application/json"), (status = 400, description = "Some error has occurred") ) )] -async fn autoyast( - query: Query, - profile: String, // xml_or_erb_or_empty -) -> Result { - let request_has_body = !profile.is_empty() && profile != "null"; - if query.url.is_none() || query.path.is_some() || request_has_body { +async fn autoyast(body: String) -> Result { + let profile = ProfileBody::from_string(body); + if profile.url.is_none() || profile.path.is_some() || profile.json.is_some() { return Err(anyhow::anyhow!( "Only url= is expected, no path= or request body. Seen: url {}, path {}, body {}", - query.url.is_some(), - query.path.is_some(), - request_has_body + profile.url.is_some(), + profile.path.is_some(), + profile.json.is_some() ) .into()); } - let url = Url::parse(query.url.as_ref().unwrap()).map_err(anyhow::Error::new)?; + let url = Url::parse(profile.url.as_ref().unwrap()).map_err(anyhow::Error::new)?; let importer_res = AutoyastProfileImporter::read(&url).await; match importer_res { Ok(importer) => Ok(importer.content), diff --git a/rust/agama-server/src/web/docs/config.rs b/rust/agama-server/src/web/docs/config.rs index 98bc110bbe..a31a3baa94 100644 --- a/rust/agama-server/src/web/docs/config.rs +++ b/rust/agama-server/src/web/docs/config.rs @@ -92,6 +92,7 @@ impl ApiDocBuilder for ConfigApiDocBuilder { .schema_from::() .schema_from::() .schema_from::() + .schema_from::() .schema_from::() .schema_from::() .schema_from::() diff --git a/rust/agama-utils/src/api/network/types.rs b/rust/agama-utils/src/api/network/types.rs index 29115dcc1a..ebc7ed5ea5 100644 --- a/rust/agama-utils/src/api/network/types.rs +++ b/rust/agama-utils/src/api/network/types.rs @@ -128,6 +128,36 @@ impl From for zbus::fdo::Error { } } +#[derive(Debug, Default, Copy, Clone, PartialEq, Deserialize, Serialize, utoipa::ToSchema)] +#[serde(rename_all = "camelCase")] +pub enum LinkLocal { + #[default] + Default = 0, + Auto = 1, + Disabled = 2, + Enabled = 3, + Fallback = 4, +} + +#[derive(Debug, Error)] +#[error("Invalid link-local value: {0}")] +pub struct InvalidLinkLocalValue(i32); + +impl TryFrom for LinkLocal { + type Error = InvalidLinkLocalValue; + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(LinkLocal::Default), + 1 => Ok(LinkLocal::Auto), + 2 => Ok(LinkLocal::Disabled), + 3 => Ok(LinkLocal::Enabled), + 4 => Ok(LinkLocal::Fallback), + _ => Err(InvalidLinkLocalValue(value)), + } + } +} + #[skip_serializing_none] #[derive(Default, Debug, PartialEq, Clone, Deserialize, Serialize, utoipa::ToSchema)] #[serde(rename_all = "camelCase")] @@ -156,6 +186,7 @@ pub struct IpConfig { pub ip6_privacy: Option, pub dns_priority4: Option, pub dns_priority6: Option, + pub link_local4: LinkLocal, } #[skip_serializing_none] diff --git a/rust/package/agama.changes b/rust/package/agama.changes index 7a6ce19574..ec7c9f8017 100644 --- a/rust/package/agama.changes +++ b/rust/package/agama.changes @@ -1,44 +1,39 @@ ------------------------------------------------------------------- -Mon Nov 3 14:36:55 UTC 2025 - José Iván López González +Tue Nov 18 08:47:11 UTC 2025 - Michal Filka -- Add storage service to support the new HTTP API - (gh#agama-project/agama#2816). +- Fixed passing arguments when "agama config generate" with an + AutoYast profile. +- Removed unhandled unwrap, reorganized validation result reporting + (gh#agama-project/agama#2893). ------------------------------------------------------------------- -Fri Oct 17 13:14:31 UTC 2025 - Imobach Gonzalez Sosa +Wed Nov 12 15:42:27 UTC 2025 - Imobach Gonzalez Sosa -- Add a new HTTP resource to register questions (gh#agama-project/agama#2813). +- Version 18 ------------------------------------------------------------------- -Thu Oct 16 04:46:20 UTC 2025 - José Iván López González +Wed Nov 12 13:14:21 UTC 2025 - Michal Filka -- Move API types to agama-utils, simplify events code, emit event - when the installation state changes, and add progress information - to the progress changed event (gh#agama-project/agama#2801). +- Fixed output of "agama config generate" ------------------------------------------------------------------- -Thu Oct 9 10:24:03 UTC 2025 - José Iván López González +Mon Nov 10 14:35:25 UTC 2025 - Michal Filka -- Extract supervisor to agama-manager package (gh#agama-project/agama#2793). +- Created ProfileClient based on HTTP API base client for profile + validation requests and refactored / cleaned relevant code + (gh#agama-project/agaam#2778). ------------------------------------------------------------------- -Wed Oct 8 06:48:47 UTC 2025 - Imobach Gonzalez Sosa +Tue Oct 14 10:36:49 UTC 2025 - Imobach Gonzalez Sosa -- Introduce a new "installation issues" API. The issues for all - services are exposed through a /issues resource (gh#agama-project/agama#2775). +- Do not log errors when retrieving NetworkManager secrets to prevent + leaking them (bsc#1251898). ------------------------------------------------------------------- -Wed Oct 8 06:27:14 UTC 2025 - José Iván López González +Tue Oct 7 09:55:46 UTC 2025 - Clemens Famulla-Conrad -- Add service for reporting progress and extend HTTP API to allow - getting the installation status (gh#agama-project/agama#2787). - -------------------------------------------------------------------- -Fri Oct 3 20:11:26 UTC 2025 - Imobach Gonzalez Sosa - -- Introduce the new HTTP API (gh#agama-project/agama#2715). -- Reimplement the localization service as part of the new API, - following the new actors-based approach. +- Add IpConfig.link_local4 to specify ZeroConf/AutoIP behavior. + (gh#agama-project/agama#2792). ------------------------------------------------------------------- Wed Oct 1 13:45:23 UTC 2025 - Ladislav Slezák diff --git a/service/Gemfile.lock b/service/Gemfile.lock index db2512f684..97d3844e0f 100755 --- a/service/Gemfile.lock +++ b/service/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - agama-yast (19.pre) + agama-yast (19.devel95.39d953111) cfa (~> 1.0.2) cfa_grub2 (~> 2.0.0) cheetah (~> 1.0.0) diff --git a/service/lib/agama/storage/iscsi/adapter.rb b/service/lib/agama/storage/iscsi/adapter.rb index 412e426365..8df5d5ea48 100644 --- a/service/lib/agama/storage/iscsi/adapter.rb +++ b/service/lib/agama/storage/iscsi/adapter.rb @@ -44,10 +44,6 @@ def activate sleep(0.5) Yast::IscsiClientLib.getConfig Yast::IscsiClientLib.autoLogOn - # We are already logged into the iSCSI targets. But device detection in the kernel is - # asynchronous, so let's wait until the corresponding iSCSI devices really appear in - # the system (so yast-storage-ng can handle them). - Yast::Execute.locally("/usr/bin/udevadm", "settle", "--timeout=20") end # Performs an iSCSI discovery. diff --git a/service/lib/y2storage/proposal/agama_md_creator.rb b/service/lib/y2storage/proposal/agama_md_creator.rb index 15b5f1e7d6..b56dfe60a0 100644 --- a/service/lib/y2storage/proposal/agama_md_creator.rb +++ b/service/lib/y2storage/proposal/agama_md_creator.rb @@ -52,7 +52,13 @@ def create(planned) devices = md_members(planned) devices.map(&:remove_descendants) md.sorted_devices = devices - planned.format!(md) if planned.partitions.empty? + if planned.partitions.empty? + planned.format!(md) + else + # FIXME: This modifies the original planned device object. That looks like the safer + # approach as a hotfix for bsc#1253145. + planned.partitions.each { |p| p.disk = md.name } + end creator_result.merge!(CreatorResult.new(devicegraph, md.name => planned)) diff --git a/service/package/gem2rpm.yml b/service/package/gem2rpm.yml index fa6eb2f194..085d88ab3a 100644 --- a/service/package/gem2rpm.yml +++ b/service/package/gem2rpm.yml @@ -19,7 +19,7 @@ Requires: yast2-country Requires: yast2-hardware-detection Requires: yast2-installation - Requires: yast2-iscsi-client >= 5.0.8 + Requires: yast2-iscsi-client >= 5.0.11 Requires: yast2-network Requires: yast2-proxy Requires: yast2-storage-ng >= 5.0.31 diff --git a/service/package/rubygem-agama-yast.changes b/service/package/rubygem-agama-yast.changes index 39ab434ca8..e03f0bbbbe 100644 --- a/service/package/rubygem-agama-yast.changes +++ b/service/package/rubygem-agama-yast.changes @@ -1,19 +1,19 @@ ------------------------------------------------------------------- -Mon Nov 3 14:34:26 UTC 2025 - José Iván López González +Wed Nov 12 15:42:26 UTC 2025 - Imobach Gonzalez Sosa -- Adapt the storage D-Bus API to support the new HTTP API - (gh#agama-project/agama#2816). +- Version 18 ------------------------------------------------------------------- -Fri Oct 17 13:15:00 UTC 2025 - Imobach Gonzalez Sosa +Fri Nov 7 15:14:51 UTC 2025 - Ancor Gonzalez Sosa -- Adapt to the new questions HTTP API (gh#agama-project/agama#2813). +- Fixed an error in the calculation of partitions when several + MD RAIDs are created (bsc#1253145). ------------------------------------------------------------------- -Fri Oct 3 20:11:33 UTC 2025 - Imobach Gonzalez Sosa +Fri Oct 31 13:48:46 UTC 2025 - Ancor Gonzalez Sosa -- Use the new HTTP API to write the localization configuration - to the target system (gh#agama-project/agama#2715). +- Use a version of yast2-iscsi-client that fixes the errors + reported at bsc#1247711. ------------------------------------------------------------------- Mon Sep 15 13:50:54 UTC 2025 - José Iván López González diff --git a/service/po/ast.po b/service/po/ast.po index 28527f9e69..c78e0da9eb 100644 --- a/service/po/ast.po +++ b/service/po/ast.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-28 02:56+0000\n" +"POT-Creation-Date: 2025-10-12 02:50+0000\n" "PO-Revision-Date: 2025-09-11 02:48+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" diff --git a/service/po/ca.po b/service/po/ca.po index 73cee26c05..7dd3a857b8 100644 --- a/service/po/ca.po +++ b/service/po/ca.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-28 02:56+0000\n" +"POT-Creation-Date: 2025-10-12 02:50+0000\n" "PO-Revision-Date: 2025-09-02 12:59+0000\n" "Last-Translator: David Medina \n" "Language-Team: Catalan \n" "Language-Team: Czech \n" "Language-Team: German \n" "Language-Team: Spanish \n" "Language-Team: Finnish \n" "Language-Team: French \n" +"POT-Creation-Date: 2025-10-12 02:50+0000\n" +"PO-Revision-Date: 2025-10-05 17:59+0000\n" +"Last-Translator: \"James \\\"Jim\\\" Ed Randson\" \n" "Language-Team: Indonesian \n" "Language: id\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.12.2\n" +"X-Generator: Weblate 5.13.3\n" #. Reports the problems and decide whether to continue or not. #. @@ -353,7 +353,7 @@ msgstr "Sidik Jari SHA256: " #. label followed by the SSL certificate identification #: service/lib/agama/ssl/certificate_details.rb:46 msgid "Common Name (CN): " -msgstr "Common Name (CN): " +msgstr "Nama Umum (CN): " #. label followed by the SSL certificate identification #: service/lib/agama/ssl/certificate_details.rb:48 diff --git a/service/po/it.po b/service/po/it.po index b9b8dc2953..c629aea388 100644 --- a/service/po/it.po +++ b/service/po/it.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-28 02:56+0000\n" +"POT-Creation-Date: 2025-10-12 02:50+0000\n" "PO-Revision-Date: 2025-08-01 13:59+0000\n" "Last-Translator: Davide Aiello \n" "Language-Team: Italian \n" "Language-Team: Japanese \n" "Language-Team: Georgian \n" "Language-Team: Kabyle \n" "Language-Team: Norwegian Bokmål \n" "Language-Team: Dutch \n" "Language-Team: Portuguese (Brazil) \n" "Language-Team: Russian \n" "Language-Team: Swedish \n" +"POT-Creation-Date: 2025-10-12 02:50+0000\n" +"PO-Revision-Date: 2025-10-05 22:59+0000\n" +"Last-Translator: Emin Tufan Çetin \n" "Language-Team: Turkish \n" "Language: tr\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.12.2\n" +"X-Generator: Weblate 5.13.3\n" #. Reports the problems and decide whether to continue or not. #. @@ -33,7 +33,7 @@ msgstr "AutoYaST Profilinde desteklenmeyen elemanlar bulundu: %{keys}." #. @param data [Hash] Extra data provided to the D-Bus calls. #: service/lib/agama/manager.rb:98 msgid "Analyze disks" -msgstr "Diskleri analiz et" +msgstr "Diskleri incele" #: service/lib/agama/manager.rb:98 msgid "Configure software" diff --git a/service/po/uk.po b/service/po/uk.po index 9ebc57d60e..98413f5756 100644 --- a/service/po/uk.po +++ b/service/po/uk.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-09-28 02:56+0000\n" +"POT-Creation-Date: 2025-10-12 02:50+0000\n" "PO-Revision-Date: 2025-07-10 16:59+0000\n" "Last-Translator: Eugene Krater \n" "Language-Team: Ukrainian \n" "Language-Team: Chinese (China) \n" "Language-Team: Chinese (Taiwan) =18" }, "devDependencies": { - "@agama-project/eslint-plugin-agama-i18n": "^1.0.0", + "@agama-project/eslint-plugin-agama-i18n": "^1.1.0", "@babel/core": "^7.28.3", "@babel/eslint-parser": "^7.28.0", "@babel/preset-env": "^7.28.3", diff --git a/web/package/agama-web-ui.changes b/web/package/agama-web-ui.changes index 37f0828d27..82671b1592 100644 --- a/web/package/agama-web-ui.changes +++ b/web/package/agama-web-ui.changes @@ -1,23 +1,30 @@ ------------------------------------------------------------------- -Fri Oct 17 13:14:52 UTC 2025 - Imobach Gonzalez Sosa +Wed Nov 12 15:42:28 UTC 2025 - Imobach Gonzalez Sosa -- Adapt to the new questions HTTP API (gh#agama-project/agama#2813). +- Version 18 ------------------------------------------------------------------- -Thu Oct 16 04:52:55 UTC 2025 - José Iván López González +Tue Oct 28 16:34:22 UTC 2025 - Ancor Gonzalez Sosa -- Adapt to the changes in the HTTP API (gh#agama-project/agama#2801). +- Rearrange the information in the storage page + (gh#agama-project/agama#2767). ------------------------------------------------------------------- -Mon Oct 6 08:16:06 UTC 2025 - Imobach Gonzalez Sosa +Mon Oct 27 15:51:48 UTC 2025 - Ladislav Slezák -- Adapt to the new "installation issues" API (gh#agama-project/agama#2775). +- Use the JavaScript/TypeScript parser to extract strings for + translation (gh#agama-project/agama#2748). ------------------------------------------------------------------- -Fri Oct 3 20:11:40 UTC 2025 - Imobach Gonzalez Sosa +Fri Oct 17 12:30:56 UTC 2025 - David Diaz -- Start adapting the UI to the new HTTP API - (gh#agama-project/agama#2715). +- Preserve installer options values after successful submission + (bsc#1249636). + +------------------------------------------------------------------- +Tue Oct 14 14:01:15 UTC 2025 - Ancor Gonzalez Sosa + +- Fixed the check about which DASDs can be formatted (bsc#1243795). ------------------------------------------------------------------- Thu Sep 18 08:57:11 UTC 2025 - David Diaz diff --git a/web/src/assets/styles/index.scss b/web/src/assets/styles/index.scss index 30ff2f3bc2..6e648de6c9 100644 --- a/web/src/assets/styles/index.scss +++ b/web/src/assets/styles/index.scss @@ -502,6 +502,27 @@ label.pf-m-disabled + .pf-v6-c-check__description { --pf-v6-c-table__sort-indicator--MarginInlineStart: var(--pf-t--global--spacer--xs); } +// Temporary workaround for a recently introduced issue in PatternFly's +// ExpandableSection, where the parent container displays scrollbars when the +// section is collapsed. This issue has been fixed in PatternFly core on September +// 23, 2025 (PR #7843): https://github.com/patternfly/patternfly/pull/7843 +// +// Applying the fix directly didn’t work in our case, as nested expandable +// sections still take up space when collapsed. As a result, we’ve added an +// extra `height: 0` rule, specifically targeting the collapsed [hidden] +// content. +// +// This workaround should be removed once the updated PatternFly version +// includes the upstream fix for this issue. +// +// TODO: Re-test and remove this workaround once the next PatternFly release +// includes the fix. +.pf-v6-c-expandable-section:where(:not(.pf-m-truncate)) + .pf-v6-c-expandable-section__content:where([hidden]) { + overflow: hidden; + height: 0; +} + // Some utilities not found at PF .w-14ch { inline-size: 14ch; @@ -527,11 +548,22 @@ button:focus-visible { outline-offset: 3px; } +.agm-three-dots-icon { + font-size: 1.1rem; + vertical-align: text-top; +} + .agm-strong-icon { font-size: 1.6rem; vertical-align: middle; } +.no-default-icon { + .pf-v6-c-button__icon { + display: none; + } +} + // FIXME: make ir more generic, if possible, or even without CSS but not // rendering such a label if "storage instructions" are more than one .storage-structure:has(> li:nth-child(2)) span.action-text { diff --git a/web/src/components/core/IssuesAlert.test.tsx b/web/src/components/core/IssuesAlert.test.tsx index 4c198f71a2..af838230e1 100644 --- a/web/src/components/core/IssuesAlert.test.tsx +++ b/web/src/components/core/IssuesAlert.test.tsx @@ -22,7 +22,7 @@ import React from "react"; import { screen } from "@testing-library/react"; -import { plainRender } from "~/test-utils"; +import { installerRender } from "~/test-utils"; import { IssuesAlert } from "~/components/core"; import { Issue, IssueSeverity, IssueSource } from "~/api/issue"; import { SOFTWARE } from "~/routes/paths"; @@ -36,7 +36,7 @@ describe("IssueAlert", () => { kind: "generic", scope: "software", }; - plainRender(); + installerRender(); expect(screen.getByText(issue.description)).toBeInTheDocument(); }); @@ -48,7 +48,7 @@ describe("IssueAlert", () => { kind: "solver", scope: "software", }; - plainRender(); + installerRender(); const link = screen.getByRole("link", { name: "Review and fix" }); expect(link).toHaveAttribute("href", SOFTWARE.conflicts); }); diff --git a/web/src/components/core/Link.test.tsx b/web/src/components/core/Link.test.tsx index a0d6000fce..e52a81e91a 100644 --- a/web/src/components/core/Link.test.tsx +++ b/web/src/components/core/Link.test.tsx @@ -22,80 +22,100 @@ import React from "react"; import { screen } from "@testing-library/react"; -import { plainRender } from "~/test-utils"; +import { installerRender } from "~/test-utils"; import { Link } from "~/components/core"; describe("Link", () => { it("renders an HTML `a` tag with the `href` attribute set to given `to` prop", () => { - plainRender(Agama Link); + installerRender(Agama Link); const link = screen.getByRole("link", { name: "Agama Link" }) as HTMLLinkElement; // NOTE: Link uses ReactRouter#useHref hook which is mocked in test-utils.js expect(link).toHaveAttribute("href", "somewhere"); }); - it("renders it as primary when either, using a truthy `isPrimary` prop or `variant` is set to primary", () => { - const { rerender } = plainRender(Agama Link); + it("does not render as primary when not using a truthy `isPrimary` prop or `variant` is set to primary", () => { + installerRender(Agama Link); const link = screen.getByRole("link", { name: "Agama Link" }); - expect(link.classList.contains("pf-m-primary")).not.toBe(true); + }); - rerender( + it("renders as primary if `isPrimary` is given", () => { + installerRender( Agama Link , ); + const link = screen.getByRole("link", { name: "Agama Link" }); expect(link.classList.contains("pf-m-primary")).toBe(true); + }); - rerender( + it("does not render as primary when `isPrimary` is false", () => { + installerRender( {" "} Agama Link , ); + const link = screen.getByRole("link", { name: "Agama Link" }); expect(link.classList.contains("pf-m-primary")).not.toBe(true); + }); - rerender( + it("renders as primary if `variant` is 'primary'", () => { + installerRender( Agama Link , ); + const link = screen.getByRole("link", { name: "Agama Link" }); expect(link.classList.contains("pf-m-primary")).toBe(true); + }); - rerender( + it("render as primary `variant` is 'primary' even if isPrimary is false", () => { + installerRender( {" "} Agama Link , ); + const link = screen.getByRole("link", { name: "Agama Link" }); expect(link.classList.contains("pf-m-primary")).toBe(true); }); it("renders it as secondary when neither is given, a truthy `isPrimary` nor `variant`", () => { - const { rerender } = plainRender(Agama Link); + installerRender(Agama Link); const link = screen.getByRole("link", { name: "Agama Link" }); expect(link.classList.contains("pf-m-secondary")).toBe(true); + }); - rerender( + it("renders it as secondary when isPrimary is false and variant primary is not given", () => { + installerRender( Agama Link , ); + const link = screen.getByRole("link", { name: "Agama Link" }); expect(link.classList.contains("pf-m-secondary")).toBe(true); + }); - rerender( + it("does not render it as secondary when variant is primary", () => { + installerRender( // Unexpected, but possible since isPrimary is just a "helper" Agama Link , ); + const link = screen.getByRole("link", { name: "Agama Link" }); expect(link.classList.contains("pf-m-secondary")).not.toBe(true); + }); - rerender( + it("does not render it as secondary when variant is link", () => { + installerRender( Agama Link , ); + const link = screen.getByRole("link", { name: "Agama Link" }); expect(link.classList.contains("pf-m-secondary")).not.toBe(true); }); }); diff --git a/web/src/components/core/Link.tsx b/web/src/components/core/Link.tsx index 05847470c9..62fbf54b15 100644 --- a/web/src/components/core/Link.tsx +++ b/web/src/components/core/Link.tsx @@ -22,7 +22,7 @@ import React from "react"; import { Button, ButtonProps } from "@patternfly/react-core"; -import { To, useHref, useLinkClickHandler } from "react-router"; +import { To, useHref, useLinkClickHandler, useLocation } from "react-router"; export type LinkProps = Omit & { /** The target route */ @@ -31,6 +31,8 @@ export type LinkProps = Omit & { replace?: boolean; /** Whether use PF/Button primary variant */ isPrimary?: boolean; + /** Whether preserve the URL query string or not */ + keepQuery?: boolean; }; /** @@ -45,12 +47,18 @@ export default function Link({ isPrimary, variant, children, + state, + keepQuery = false, onClick, ...props }: LinkProps) { + const location = useLocation(); const href = useHref(to); const linkVariant = isPrimary ? "primary" : variant || "secondary"; - const handleClick = useLinkClickHandler(to, { replace }); + const destination = keepQuery ? ({ pathname: to, search: location.search } as To) : to; + const options = { replace }; + const handleClick = useLinkClickHandler(destination, options); + return ( + ); + }, +); + /** * Internal component that renders generic actions available for a Drive device. */ @@ -41,7 +78,14 @@ const DriveDeviceMenu = ({ drive, selected }: DriveDeviceMenuProps) => { const deleteDrive = useDeleteDrive(); const deleteFn = (device: model.Drive) => deleteDrive(device.name); - return ; + return ( + } + /> + ); }; export type DriveEditorProps = { drive: model.Drive; driveDevice: storage.Device }; @@ -52,10 +96,8 @@ export type DriveEditorProps = { drive: model.Drive; driveDevice: storage.Device */ export default function DriveEditor({ drive, driveDevice }: DriveEditorProps) { return ( - } - content={} - actions={} - /> + }> + + ); } diff --git a/web/src/components/storage/EncryptionSection.test.tsx b/web/src/components/storage/EncryptionSection.test.tsx index 4ecc9e7a87..1d83c8aa4e 100644 --- a/web/src/components/storage/EncryptionSection.test.tsx +++ b/web/src/components/storage/EncryptionSection.test.tsx @@ -22,7 +22,7 @@ import React from "react"; import { screen } from "@testing-library/react"; -import { plainRender } from "~/test-utils"; +import { installerRender } from "~/test-utils"; import EncryptionSection from "./EncryptionSection"; import { STORAGE } from "~/routes/paths"; @@ -46,7 +46,7 @@ describe("EncryptionSection", () => { }); it("renders encryption as enabled", () => { - plainRender(); + installerRender(); screen.getByText(/is enabled/); }); @@ -61,7 +61,7 @@ describe("EncryptionSection", () => { }); it("renders encryption as TPM enabled", () => { - plainRender(); + installerRender(); screen.getByText(/using TPM/); }); }); @@ -73,14 +73,14 @@ describe("EncryptionSection", () => { }); it("renders encryption as disabled", () => { - plainRender(); + installerRender(); screen.getByText(/is disabled/); }); }); it("renders a link for navigating to encryption settings", () => { - plainRender(); - const editLink = screen.getByRole("link", { name: "Edit" }); + installerRender(); + const editLink = screen.getByRole("link", { name: "Change" }); expect(editLink).toHaveAttribute("href", STORAGE.editEncryption); }); }); diff --git a/web/src/components/storage/EncryptionSection.tsx b/web/src/components/storage/EncryptionSection.tsx index 753c9a9f53..e8ef5830c6 100644 --- a/web/src/components/storage/EncryptionSection.tsx +++ b/web/src/components/storage/EncryptionSection.tsx @@ -21,8 +21,10 @@ */ import React from "react"; -import { Card, CardBody, Content } from "@patternfly/react-core"; -import { Link, Page } from "~/components/core"; +import { Content, Flex, Split, Stack } from "@patternfly/react-core"; +import textStyles from "@patternfly/react-styles/css/utilities/Text/text"; +import { Link } from "~/components/core"; +import Icon from "~/components/layout/Icon"; import { useEncryption } from "~/queries/storage/config-model"; import { apiModel } from "~/api/storage"; import { STORAGE } from "~/routes/paths"; @@ -42,21 +44,22 @@ export default function EncryptionSection() { const password = encryption?.password; return ( - {_("Edit")}} - > - - - {encryptionLabel(method)} - {password && } - - - + +
+ {_( + "Protection for the information stored at \ + the new file systems, including data, programs, and system files.", + )} +
+ {encryptionLabel(method)} + {password && } + + + + {_("Change")} + + + +
); } diff --git a/web/src/components/storage/EncryptionSettingsPage.tsx b/web/src/components/storage/EncryptionSettingsPage.tsx index 4bd8aa03fb..4ed8253285 100644 --- a/web/src/components/storage/EncryptionSettingsPage.tsx +++ b/web/src/components/storage/EncryptionSettingsPage.tsx @@ -21,7 +21,7 @@ */ import React, { useEffect, useState, useRef } from "react"; -import { useNavigate } from "react-router"; +import { useLocation, useNavigate } from "react-router"; import { ActionGroup, Alert, Checkbox, Content, Form } from "@patternfly/react-core"; import { NestedContent, Page, PasswordAndConfirmationInput } from "~/components/core"; import PasswordCheck from "~/components/users/PasswordCheck"; @@ -36,6 +36,7 @@ import { _ } from "~/i18n"; */ export default function EncryptionSettingsPage() { const navigate = useNavigate(); + const location = useLocation(); const { encryption: encryptionConfig, enable, disable } = useEncryption(); const methods = useEncryptionMethods(); @@ -83,7 +84,7 @@ export default function EncryptionSettingsPage() { const commit = () => (isEnabled ? enable(method, password) : disable()); commit(); - navigate(".."); + navigate({ pathname: "..", search: location.search }); }; // TRANSLATORS: "Trusted Platform Module" is the name of the technology and TPM its abbreviation diff --git a/web/src/components/storage/FilesystemMenu.tsx b/web/src/components/storage/FilesystemMenu.tsx index 1853000f4d..c8842079bc 100644 --- a/web/src/components/storage/FilesystemMenu.tsx +++ b/web/src/components/storage/FilesystemMenu.tsx @@ -20,19 +20,19 @@ * find current contact information at www.suse.com. */ -import React, { useId } from "react"; -import { Divider, Flex } from "@patternfly/react-core"; +import React, { forwardRef } from "react"; +import { Button, Flex, FlexItem } from "@patternfly/react-core"; +import Icon from "~/components/layout/Icon"; import { generatePath, useNavigate } from "react-router"; -import Text from "~/components/core/Text"; -import MenuHeader from "~/components/core/MenuHeader"; -import MenuButton from "~/components/core/MenuButton"; +import MenuButton, { CustomToggleProps } from "~/components/core/MenuButton"; import { STORAGE as PATHS } from "~/routes/paths"; import { model } from "~/types/storage"; -import * as driveUtils from "~/components/storage/utils/drive"; import { filesystemType, formattedPath } from "~/components/storage/utils"; import { sprintf } from "sprintf-js"; import { _ } from "~/i18n"; +type FilesystemMenuProps = { deviceModel: model.Drive | model.MdRaid }; + function deviceDescription(deviceModel: FilesystemMenuProps["deviceModel"]): string { const fs = filesystemType(deviceModel.filesystem); const mountPath = deviceModel.mountPath; @@ -53,49 +53,56 @@ function deviceDescription(deviceModel: FilesystemMenuProps["deviceModel"]): str return sprintf(_("The device will be formatted as %1$s and mounted at %2$s"), fs, path); } -type FilesystemMenuProps = { deviceModel: model.Drive | model.MdRaid }; +type FilesystemMenuToggleProps = CustomToggleProps & { + deviceModel: model.Drive | model.MdRaid; +}; + +const FilesystemMenuToggle = forwardRef( + ({ deviceModel, ...props }: FilesystemMenuToggleProps, ref) => { + return ( + + ); + }, +); export default function FilesystemMenu({ deviceModel }: FilesystemMenuProps): React.ReactNode { const navigate = useNavigate(); - const ariaLabelId = useId(); - const toggleTextId = useId(); const { list, listIndex } = deviceModel; const editFilesystemPath = generatePath(PATHS.formatDevice, { list, listIndex }); - // TRANSLATORS: %s is the name of device, like '/dev/sda'. - const detailsAriaLabel = sprintf(_("Details for %s"), deviceModel.name); - return ( - - - {detailsAriaLabel} - - - {_("Details")} - - , - , - navigate(editFilesystemPath)} - > - {_("Edit")} - , - ]} - > - {driveUtils.contentDescription(deviceModel)} - - + navigate(editFilesystemPath)} + > + {_("Edit")} + , + ]} + customToggle={} + /> ); } diff --git a/web/src/components/storage/MdRaidEditor.tsx b/web/src/components/storage/MdRaidEditor.tsx index c0741369ff..5678e06908 100644 --- a/web/src/components/storage/MdRaidEditor.tsx +++ b/web/src/components/storage/MdRaidEditor.tsx @@ -20,20 +20,57 @@ * find current contact information at www.suse.com. */ -import React from "react"; +import React, { forwardRef } from "react"; +import Icon from "~/components/layout/Icon"; import ConfigEditorItem from "~/components/storage/ConfigEditorItem"; import MdRaidHeader from "~/components/storage/MdRaidHeader"; import DeviceEditorContent from "~/components/storage/DeviceEditorContent"; import SearchedDeviceMenu from "~/components/storage/SearchedDeviceMenu"; import { model } from "~/types/storage"; import { storage } from "~/api/system"; +import { CustomToggleProps } from "~/components/core/MenuButton"; import { useDeleteMdRaid } from "~/hooks/storage/md-raid"; +import { Button, Flex, FlexItem } from "@patternfly/react-core"; +import textStyles from "@patternfly/react-styles/css/utilities/Text/text"; type MdRaidDeviceMenuProps = { raid: model.MdRaid; selected: storage.Device; }; +type MdRaidDeviceMenuToggleProps = CustomToggleProps & { + raid: model.MdRaid; + device: storage.Device; +}; + +const MdRaidDeviceMenuToggle = forwardRef( + ({ raid, device, ...props }: MdRaidDeviceMenuToggleProps, ref) => { + return ( + + ); + }, +); + /** * Internal component that renders generic actions available for an MdRaid device. */ @@ -41,7 +78,14 @@ const MdRaidDeviceMenu = ({ raid, selected }: MdRaidDeviceMenuProps): React.Reac const deleteMdRaid = useDeleteMdRaid(); const deleteFn = (device: model.MdRaid) => deleteMdRaid(device.name); - return ; + return ( + } + /> + ); }; type MdRaidEditorProps = { raid: model.MdRaid; raidDevice: storage.Device }; @@ -52,10 +96,8 @@ type MdRaidEditorProps = { raid: model.MdRaid; raidDevice: storage.Device }; */ export default function MdRaidEditor({ raid, raidDevice }: MdRaidEditorProps) { return ( - } - content={} - actions={} - /> + }> + + ); } diff --git a/web/src/components/storage/PartitionPage.tsx b/web/src/components/storage/PartitionPage.tsx index 1d747b7eeb..69c40a9952 100644 --- a/web/src/components/storage/PartitionPage.tsx +++ b/web/src/components/storage/PartitionPage.tsx @@ -21,7 +21,7 @@ */ import React, { useId } from "react"; -import { useParams, useNavigate } from "react-router"; +import { useParams, useNavigate, useLocation } from "react-router"; import { ActionGroup, Content, @@ -690,6 +690,7 @@ function AutoSizeInfo({ value }: AutoSizeInfoProps): React.ReactNode { */ const PartitionPageForm = () => { const navigate = useNavigate(); + const location = useLocation(); const headingId = useId(); const [mountPoint, setMountPoint] = React.useState(NO_VALUE); const [target, setTarget] = React.useState(NEW_PARTITION); @@ -794,7 +795,7 @@ const PartitionPageForm = () => { if (initialValue) editPartition(list, listIndex, initialValue.mountPoint, partitionConfig); else addPartition(list, listIndex, partitionConfig); - navigate(PATHS.root); + navigate({ pathname: PATHS.root, search: location.search }); }; const isFormValid = errors.length === 0; diff --git a/web/src/components/storage/PartitionsMenu.tsx b/web/src/components/storage/PartitionsMenu.tsx deleted file mode 100644 index a2aa579eb7..0000000000 --- a/web/src/components/storage/PartitionsMenu.tsx +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) [2024-2025] SUSE LLC - * - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, contact SUSE LLC. - * - * To contact SUSE LLC about this file by physical or electronic mail, you may - * find current contact information at www.suse.com. - */ - -import React, { useId } from "react"; -import { Divider, Stack, Flex } from "@patternfly/react-core"; -import { generatePath, useNavigate } from "react-router"; -import Text from "~/components/core/Text"; -import MenuButton from "~/components/core/MenuButton"; -import MenuHeader from "~/components/core/MenuHeader"; -import MountPathMenuItem from "~/components/storage/MountPathMenuItem"; -import { Partition } from "~/api/storage/model"; -import { STORAGE as PATHS } from "~/routes/paths"; -import { useDeletePartition } from "~/hooks/storage/partition"; -import * as driveUtils from "~/components/storage/utils/drive"; -import { sprintf } from "sprintf-js"; -import { _, n_ } from "~/i18n"; - -const PartitionMenuItem = ({ device, mountPath }) => { - const partition = device.getPartition(mountPath); - const { list, listIndex } = device; - const editPath = generatePath(PATHS.editPartition, { - list, - listIndex, - partitionId: mountPath, - }); - const deletePartition = useDeletePartition(); - - return ( - deletePartition(list, listIndex, mountPath)} - /> - ); -}; - -const partitionsLabelText = (device) => { - const { isBoot, isTargetDevice, isAddingPartitions, isReusingPartitions } = device; - const num = device.partitions.filter((p: Partition) => p.mountPath).length; - - if (isBoot || isTargetDevice) { - if (isAddingPartitions && isReusingPartitions) - return _("Moreover, the following partitions will be created or mounted"); - - if (isAddingPartitions) - return n_( - "Moreover, the following partition will be created.", - "Moreover, the following partitions will be created.", - num, - ); - - return n_( - "Moreover, the following partition will be mounted.", - "Moreover, the following partitions will be mounted.", - num, - ); - } - - if (isAddingPartitions && isReusingPartitions) - return _("The following partitions will be created or mounted"); - - if (isAddingPartitions) - return n_( - "The following partition will be created.", - "The following partitions will be created.", - num, - ); - - return n_( - "The following partition will be mounted.", - "The following partitions will be mounted.", - num, - ); -}; - -// This function (and maybe the following ones) only makes sense with the current temporary -// organization of the information, see FIXME at PartitionsMenu -const PartitionsMenuHeader = ({ texts, device }) => { - const hasPartitions = device.partitions.some((p: Partition) => p.mountPath); - - const textsContent = texts.length ? ( - - {texts.map((text, idx) => ( - {text} - ))} - - ) : null; - - if (textsContent) { - if (hasPartitions) - return ( - - {textsContent} - {partitionsLabelText(device)} - - } - /> - ); - - return ; - } - - return ; -}; - -const optionalPartitionsTexts = (device) => { - const { isBoot, isTargetDevice } = device; - - const texts = []; - if (isBoot) texts.push(_("Any partition needed to boot will be configured.")); - if (isTargetDevice) texts.push(_('Partitions to host "system" will be created if needed.')); - - return texts; -}; - -export default function PartitionsMenu({ device }) { - const navigate = useNavigate(); - const ariaLabelId = useId(); - const toggleTextId = useId(); - const { list, listIndex } = device; - const newPartitionPath = generatePath(PATHS.addPartition, { list, listIndex }); - // TRANSLATORS: %s is the name of device, like '/dev/sda'. - const detailsAriaLabel = sprintf(_("Details for %s"), device.name); - const hasPartitions = device.partitions.some((p: Partition) => p.mountPath); - - // FIXME: All strings and widgets are now calculated and assembled here. But we are actually - // aiming for a different organization of the widgets (eg. using a MenuGroup with a label to - // render the list of partition). At that point we will be able to better distribute the logic. - - const optionalTexts = optionalPartitionsTexts(device); - const items = []; - if (!!optionalTexts.length || hasPartitions) - items.push( - , - , - ); - - if (hasPartitions) { - items.push( - device.partitions - .filter((p: Partition) => p.mountPath) - .map((p: Partition) => { - return ; - }), - ); - } - - items.push( - navigate(newPartitionPath)} - > - {_("Add or use partition")} - , - ); - - return ( - - - {detailsAriaLabel} - - - {_("Details")} - - - {driveUtils.contentDescription(device)} - - - ); -} diff --git a/web/src/components/storage/PartitionsMenu.test.tsx b/web/src/components/storage/PartitionsSection.test.tsx similarity index 68% rename from web/src/components/storage/PartitionsMenu.test.tsx rename to web/src/components/storage/PartitionsSection.test.tsx index 0f7f39695d..eb8ba3b855 100644 --- a/web/src/components/storage/PartitionsMenu.test.tsx +++ b/web/src/components/storage/PartitionsSection.test.tsx @@ -21,9 +21,9 @@ */ import React from "react"; -import { screen, within } from "@testing-library/react"; -import { plainRender, mockNavigateFn } from "~/test-utils"; -import PartitionsMenu from "~/components/storage/PartitionsMenu"; +import { screen } from "@testing-library/react"; +import { installerRender, mockNavigateFn } from "~/test-utils"; +import PartitionsSection from "~/components/storage/PartitionsSection"; import { apiModel } from "~/api/storage/types"; import { model } from "~/types/storage"; @@ -89,43 +89,38 @@ jest.mock("~/hooks/storage/partition", () => ({ useDeletePartition: () => mockDeletePartition, })); +async function openMenu(path) { + const { user } = installerRender(); + + const detailsButton = screen.getByRole("button", { name: /New partitions/ }); + await user.click(detailsButton); + const partitionMenu = screen.getByRole("button", { name: `Options for partition ${path}` }); + await user.click(partitionMenu); + + return { user }; +} + describe("PartitionMenuItem", () => { it("allows users to delete a not required partition", async () => { - const { user } = plainRender(); - - const detailsButton = screen.getByRole("button", { name: /Details for .*sda/ }); - await user.click(detailsButton); - const partitionsMenu = screen.getByRole("menu"); - const deleteSwapButton = within(partitionsMenu).getByRole("menuitem", { - name: "Delete swap", - }); + const { user } = await openMenu("swap"); + const deleteSwapButton = screen.getByRole("menuitem", { name: "Delete swap" }); await user.click(deleteSwapButton); expect(mockDeletePartition).toHaveBeenCalled(); }); it("allows users to delete a required partition", async () => { - const { user } = plainRender(); - - const detailsButton = screen.getByRole("button", { name: /Details for .*sda/ }); - await user.click(detailsButton); - const partitionsMenu = screen.getByRole("menu"); - const deleteRootButton = within(partitionsMenu).getByRole("menuitem", { - name: "Delete /", - }); + const { user } = await openMenu("/"); + const deleteRootButton = screen.getByRole("menuitem", { name: "Delete /" }); await user.click(deleteRootButton); expect(mockDeletePartition).toHaveBeenCalled(); }); it("allows users to edit a partition", async () => { - const { user } = plainRender(); - - const detailsButton = screen.getByRole("button", { name: /Details for .*sda/ }); - await user.click(detailsButton); - const partitionsMenu = screen.getByRole("menu"); - const editSwapButton = within(partitionsMenu).getByRole("menuitem", { - name: "Edit swap", - }); + const { user } = await openMenu("swap"); + const editSwapButton = screen.getByRole("menuitem", { name: "Edit swap" }); await user.click(editSwapButton); - expect(mockNavigateFn).toHaveBeenCalledWith("/storage/drives/0/partitions/swap/edit"); + expect(mockNavigateFn).toHaveBeenCalledWith( + expect.objectContaining({ pathname: "/storage/drives/0/partitions/swap/edit" }), + ); }); }); diff --git a/web/src/components/storage/PartitionsSection.tsx b/web/src/components/storage/PartitionsSection.tsx new file mode 100644 index 0000000000..e93a3c82e2 --- /dev/null +++ b/web/src/components/storage/PartitionsSection.tsx @@ -0,0 +1,290 @@ +/* + * Copyright (c) [2024-2025] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React, { useId } from "react"; +import { + ExpandableSection, + Content, + DataListItem, + DataListItemRow, + DataListItemCells, + DataListCell, + DataListAction, + DataList, + Flex, + ExpandableSectionToggle, + ExpandableSectionProps, +} from "@patternfly/react-core"; +import { useStorageUiState } from "~/context/storage-ui-state"; +import Text from "~/components/core/Text"; +import MenuButton from "~/components/core/MenuButton"; +import MountPathMenuItem from "~/components/storage/MountPathMenuItem"; +import { model } from "~/types/storage"; +import { STORAGE as PATHS } from "~/routes/paths"; +import { useDeletePartition } from "~/hooks/storage/partition"; +import * as driveUtils from "~/components/storage/utils/drive"; +import { generateEncodedPath } from "~/utils"; +import * as partitionUtils from "~/components/storage/utils/partition"; +import { _, n_ } from "~/i18n"; +import { Link, NestedContent } from "../core"; +import { Icon } from "../layout"; +import { IconProps } from "../layout/Icon"; +import { sprintf } from "sprintf-js"; +import spacingStyles from "@patternfly/react-styles/css/utilities/Spacing/spacing"; +import { toggle } from "radashi"; + +const PartitionMenuItem = ({ device, mountPath }) => { + const partition = device.getPartition(mountPath); + const { list, listIndex } = device; + const editPath = generateEncodedPath(PATHS.editPartition, { + list, + listIndex, + partitionId: mountPath, + }); + const deletePartition = useDeletePartition(); + + return ( + deletePartition(list, listIndex, mountPath)} + /> + ); +}; + +const partitionsLabelText = (device) => { + const { isBoot, isTargetDevice, isAddingPartitions, isReusingPartitions } = device; + const num = device.partitions.filter((p: model.Partition) => p.mountPath).length; + + if (isBoot || isTargetDevice) { + if (isAddingPartitions && isReusingPartitions) + return _("Moreover, the following partitions will be created or mounted"); + + if (isAddingPartitions) + return n_( + "Moreover, the following partition will be created.", + "Moreover, the following partitions will be created.", + num, + ); + + return n_( + "Moreover, the following partition will be mounted.", + "Moreover, the following partitions will be mounted.", + num, + ); + } + + if (isAddingPartitions && isReusingPartitions) + return _("The following partitions will be created or mounted"); + + if (isAddingPartitions) + return n_( + "The following partition will be created.", + "The following partitions will be created.", + num, + ); + + return n_( + "The following partition will be mounted.", + "The following partitions will be mounted.", + num, + ); +}; + +const optionalPartitionsTexts = (device) => { + const { isBoot, isTargetDevice } = device; + + const texts = []; + if (isBoot) texts.push(_("Any partition needed to boot will be configured.")); + if (isTargetDevice) texts.push(_('Partitions to host "system" will be created if needed.')); + + return texts; +}; + +const PartitionRow = ({ partition, device }) => { + // const partition = device.getPartition(mountPath); + const { list, listIndex } = device; + const editPath = generateEncodedPath(PATHS.editPartition, { + list, + listIndex, + partitionId: partition.mountPath, + }); + const deletePartition = useDeletePartition(); + const description = partitionUtils.typeWithSize(partition); + + return ( + + + + {partition.mountPath} + , + + {description} + , + ]} + /> + + + {_("Edit")} + , + deletePartition(list, listIndex, partition.mountPath)} + isDanger + > + {_("Delete")} + , + ]} + > + + + + + + ); +}; + +const PartitionsSectionHeader = ({ device }) => { + const texts = optionalPartitionsTexts(device); + const hasPartitions = device.partitions.some((p: model.Partition) => p.mountPath); + if (hasPartitions) { + texts.push(partitionsLabelText(device)); + } + + // FIXME: not really i18n friendly. + const textsContent = texts.map((text, idx) => {text} ); + return {textsContent}; +}; + +type PartitionsSectionProps = { + device: model.Drive | model.MdRaid; +}; + +export default function PartitionsSection({ device }: PartitionsSectionProps) { + const { uiState, setUiState } = useStorageUiState(); + const toggleId = useId(); + const contentId = useId(); + const { list, listIndex } = device; + const index = `${list[0]}${listIndex}`; + const expanded = uiState.get("expanded")?.split(","); + const isExpanded = expanded?.includes(index); + const newPartitionPath = generateEncodedPath(PATHS.addPartition, { list, listIndex }); + const hasPartitions = device.partitions.some((p: model.Partition) => p.mountPath); + + const onToggle = () => { + setUiState((state) => { + const nextExpanded = toggle(expanded, index); + state.set("expanded", nextExpanded.join(",")); + return state; + }); + }; + const iconName: IconProps["name"] = isExpanded ? "unfold_less" : "unfold_more"; + const commonProps: Pick = { + toggleId, + contentId, + isExpanded, + }; + + // FIXME: All strings and widgets are now calculated and assembled here. But we are actually + // aiming for a different organization of the widgets (eg. using a MenuGroup with a label to + // render the list of partition). At that point we will be able to better distribute the logic. + + const items = []; + + if (hasPartitions) { + items.push( + device.partitions + .filter((p: model.Partition) => p.mountPath) + .map((p: model.Partition) => { + return ; + }), + ); + } + + return ( + + + + {driveUtils.contentDescription(device)} + + + + + + + + + {device.partitions + .filter((p: model.Partition) => p.mountPath) + .map((p: model.Partition) => { + return ; + })} + + + + + {/** TODO: choose one, "add" or "add_circle", and remove the other at Icon.tsx */} + {_("Add or use partition")} + + + + + + + + ); +} diff --git a/web/src/components/storage/ProposalPage.test.tsx b/web/src/components/storage/ProposalPage.test.tsx index 7c69a65e90..11ae21080e 100644 --- a/web/src/components/storage/ProposalPage.test.tsx +++ b/web/src/components/storage/ProposalPage.test.tsx @@ -112,8 +112,8 @@ jest.mock("./ProposalFailedInfo", () => () =>
failed info
); jest.mock("./UnsupportedModelInfo", () => () =>
unsupported info
); jest.mock("./ProposalResultSection", () => () =>
result
); jest.mock("./ConfigEditor", () => () =>
installation devices
); -jest.mock("./ConfigureDeviceMenu", () => () =>
add device menu
); -jest.mock("./ConfigEditorMenu", () => () =>
config editor menu
); +jest.mock("./EncryptionSection", () => () =>
encryption section
); +jest.mock("./BootSection", () => () =>
boot section
); jest.mock("~/components/product/ProductRegistrationAlert", () => () => (
registration alert
)); diff --git a/web/src/components/storage/ProposalPage.tsx b/web/src/components/storage/ProposalPage.tsx index e92b7be888..545c45fbc9 100644 --- a/web/src/components/storage/ProposalPage.tsx +++ b/web/src/components/storage/ProposalPage.tsx @@ -20,7 +20,7 @@ * find current contact information at www.suse.com. */ -import React from "react"; +import React, { useState } from "react"; import { Button, Content, @@ -28,18 +28,25 @@ import { GridItem, Split, SplitItem, + Stack, EmptyState, EmptyStateBody, EmptyStateFooter, List, ListItem, + Flex, + FlexItem, + Tab, + Tabs, + TabTitleText, } from "@patternfly/react-core"; -import { Page, Link } from "~/components/core/"; +import textStyles from "@patternfly/react-styles/css/utilities/Text/text"; +import { Page, Link, NestedContent } from "~/components/core/"; import { Icon } from "~/components/layout"; import ConfigEditor from "./ConfigEditor"; -import ConfigEditorMenu from "./ConfigEditorMenu"; -import ConfigureDeviceMenu from "./ConfigureDeviceMenu"; +import ConnectedDevicesMenu from "./ConnectedDevicesMenu"; import EncryptionSection from "./EncryptionSection"; +import BootSection from "./BootSection"; import FixableConfigInfo from "./FixableConfigInfo"; import ProposalFailedInfo from "./ProposalFailedInfo"; import ProposalResultSection from "./ProposalResultSection"; @@ -55,7 +62,10 @@ import { useDASDSupported } from "~/queries/storage/dasd"; import { STORAGE as PATHS } from "~/routes/paths"; import { _, n_ } from "~/i18n"; import { useProgress, useProgressChanges } from "~/queries/progress"; -import { useNavigate } from "react-router"; +import { useNavigate, useLocation } from "react-router"; +import { useStorageUiState } from "~/context/storage-ui-state"; +import MenuButton from "../core/MenuButton"; +import spacingStyles from "@patternfly/react-styles/css/utilities/Spacing/spacing"; function InvalidConfigEmptyState(): React.ReactNode { const errors = useScopeIssues("storage"); @@ -175,8 +185,28 @@ function ProposalEmptyState(): React.ReactNode { } function ProposalSections(): React.ReactNode { + const { uiState, setUiState } = useStorageUiState(); const model = useConfigModel({ suspense: true }); const proposal = useProposal(); + const reset = useResetConfig(); + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: number, + ) => { + setUiState((state) => { + state.set("st", tabIndex.toString()); + return state; + }); + }; + + const onReset = () => { + reset(); + setUiState((state) => { + state.delete("expanded"); + state.delete("st"); + return state; + }); + }; return ( @@ -186,29 +216,78 @@ function ProposalSections(): React.ReactNode { {model && ( <> - + + + + {_("Reset to defaults")} + , + ]} + > + + + + } description={_( - "Structure of the new system, including disks to use and additional devices like LVM volume groups.", + "Changes in these settings will immediately update the 'Result' section below.", )} - actions={ - <> - - - - - - - - } > - + + {_("Installation devices")}} + > + + +
+ {_( + "Structure of the new system, including disks to use and additional devices like LVM volume groups.", + )} +
+ +
+
+
+ {_("Encryption")}} + > + + + + + {_("Boot options")}} + > + + + + +
- - - )} {proposal && } @@ -227,6 +306,10 @@ export default function ProposalPage(): React.ReactNode { const issues = useScopeIssues("storage"); const progress = useProgress("storage"); const navigate = useNavigate(); + const location = useLocation(); + // Hopefully this could be removed in the future. See rationale at UseStorageUiState + const [resetNeeded, setResetNeeded] = useState(location.state?.resetStorageUiState); + const { setUiState } = useStorageUiState(); useProgressChanges(); @@ -234,6 +317,13 @@ export default function ProposalPage(): React.ReactNode { if (progress && !progress.finished) navigate(PATHS.progress); }, [progress, navigate]); + React.useEffect(() => { + if (resetNeeded) { + setResetNeeded(false); + setUiState(new Map()); + } + }, [resetNeeded, setUiState]); + const fixable = ["no_root", "required_filesystems", "vg_target_devices", "reused_md_member"]; const unfixableErrors = issues.filter((e) => !fixable.includes(e.kind)); const isModelEditable = model && !unfixableErrors.length; @@ -241,10 +331,20 @@ export default function ProposalPage(): React.ReactNode { const hasResult = proposal !== null; const showSections = hasDevices && (isModelEditable || hasResult); + if (resetNeeded) return; + return ( - {_("Storage")} + + + {_("Storage")} + + + + + + {!showSections && } diff --git a/web/src/components/storage/ProposalResultSection.test.tsx b/web/src/components/storage/ProposalResultSection.test.tsx index 4dd2e1fb2e..502c1f6d49 100644 --- a/web/src/components/storage/ProposalResultSection.test.tsx +++ b/web/src/components/storage/ProposalResultSection.test.tsx @@ -22,7 +22,7 @@ import React from "react"; import { screen, within } from "@testing-library/react"; -import { plainRender } from "~/test-utils"; +import { installerRender } from "~/test-utils"; import { ProposalResultSection } from "~/components/storage"; import { devices, actions } from "./test-data/full-result-example"; @@ -51,8 +51,8 @@ describe("ProposalResultSection", () => { }); it("does not render a warning when there are not delete actions", () => { - plainRender(); - expect(screen.queryByText(/Warning alert:/)).toBeNull(); + installerRender(); + expect(screen.queryByText(/destructive/)).not.toBeInTheDocument(); }); }); @@ -66,19 +66,21 @@ describe("ProposalResultSection", () => { }); it("renders the affected systems in the deletion reminder, if any", () => { - plainRender(); + installerRender(); expect(screen.queryByText(/affecting openSUSE/)).toBeInTheDocument(); }); }); it("renders a reminder about the delete actions", () => { - plainRender(); - expect(screen.queryByText(/Warning alert:/)).toBeInTheDocument(); + installerRender(); expect(screen.queryByText(/4 destructive/)).toBeInTheDocument(); }); - it("renders a treegrid including all relevant information about final result", () => { - plainRender(); + it("renders a treegrid including all relevant information about final result", async () => { + const { user } = installerRender(); + const tab = screen.getByRole("tab", { name: /Final layout/ }); + + await user.click(tab); const treegrid = screen.getByRole("treegrid"); /** * Expected rows for full-result-example @@ -113,13 +115,4 @@ describe("ProposalResultSection", () => { within(treegrid).getByRole("row", { name: "vdc4 Linux 1.5 GiB" }); within(treegrid).getByRole("row", { name: "vdc5 / Btrfs Partition 17.5 GiB" }); }); - - it("allows toggling the planned actions", async () => { - const { user } = plainRender(); - const button = screen.getByRole("button", { name: /planned actions/ }); - - await user.click(button); - - screen.getByRole("button", { name: "Collapse the list of planned actions" }); - }); }); diff --git a/web/src/components/storage/ProposalResultSection.tsx b/web/src/components/storage/ProposalResultSection.tsx index 4db0f566b3..0b36596891 100644 --- a/web/src/components/storage/ProposalResultSection.tsx +++ b/web/src/components/storage/ProposalResultSection.tsx @@ -20,9 +20,10 @@ * find current contact information at www.suse.com. */ -import React, { useState } from "react"; -import { Alert, ExpandableSection, Skeleton, Stack } from "@patternfly/react-core"; -import { Page } from "~/components/core"; +import React from "react"; +import { Skeleton, Stack, Tab, Tabs, TabTitleText } from "@patternfly/react-core"; +import SmallWarning from "~/components/core/SmallWarning"; +import { Page, NestedContent } from "~/components/core"; import DevicesManager from "~/components/storage/DevicesManager"; import ProposalResultTable from "~/components/storage/ProposalResultTable"; import { ProposalActionsDialog } from "~/components/storage"; @@ -30,6 +31,8 @@ import { _, n_, formatList } from "~/i18n"; import { useDevices as useSystemDevices } from "~/hooks/storage/system"; import { useDevices as useProposalDevices, useActions } from "~/hooks/storage/proposal"; import { sprintf } from "sprintf-js"; +import textStyles from "@patternfly/react-styles/css/utilities/Text/text"; +import { useStorageUiState } from "~/context/storage-ui-state"; /** * @todo Create a component for rendering a customized skeleton @@ -81,7 +84,7 @@ const DeletionsInfo = ({ manager }: { manager: DevicesManager }) => { ); } - return ; + return ; }; export type ActionsListProps = { @@ -90,22 +93,11 @@ export type ActionsListProps = { function ActionsList({ manager }: ActionsListProps) { const actions = manager.actions; - const [isExpanded, setIsExpanded] = useState(false); - const toggleText = isExpanded - ? _("Collapse the list of planned actions") - : sprintf(_("Check the %d planned actions"), actions.length); return ( - + - setIsExpanded(!isExpanded)} - toggleText={toggleText} - > - - + ); } @@ -115,10 +107,20 @@ export type ProposalResultSectionProps = { }; export default function ProposalResultSection({ isLoading = false }: ProposalResultSectionProps) { + const { uiState, setUiState } = useStorageUiState(); const system = useSystemDevices({ suspense: true }); const staging = useProposalDevices({ suspense: true }); const actions = useActions(); const devicesManager = new DevicesManager(system, staging, actions); + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: number, + ) => { + setUiState((state) => { + state.set("rt", tabIndex.toString()); + return state; + }); + }; if (isLoading) return ; @@ -126,13 +128,31 @@ export default function ProposalResultSection({ isLoading = false }: ProposalRes - - - - + + {_("Actions")}}> + + +
+ {_("The following actions will be performed in the system during installation.")} +
+ +
+
+
+ {_("Final layout")}}> + + +
+ {_("Final structure of the system after installation.")} +
+ +
+
+
+
); } diff --git a/web/src/components/storage/SearchedDeviceMenu.tsx b/web/src/components/storage/SearchedDeviceMenu.tsx index 94c5683534..70b1ba2a8e 100644 --- a/web/src/components/storage/SearchedDeviceMenu.tsx +++ b/web/src/components/storage/SearchedDeviceMenu.tsx @@ -21,7 +21,7 @@ */ import React, { useState } from "react"; -import MenuButton, { MenuButtonItem } from "~/components/core/MenuButton"; +import MenuButton, { CustomToggleProps, MenuButtonItem } from "~/components/core/MenuButton"; import NewVgMenuOption from "./NewVgMenuOption"; import { useAvailableDevices } from "~/hooks/storage/system"; import { useModel } from "~/hooks/storage/model"; @@ -35,7 +35,6 @@ import { sprintf } from "sprintf-js"; import { _, formatList } from "~/i18n"; import DeviceSelectorModal from "./DeviceSelectorModal"; import { MenuItemProps } from "@patternfly/react-core"; -import { Icon } from "../layout"; import { isDrive } from "~/helpers/storage/device"; const baseName = (device: storage.Device): string => deviceBaseName(device, true); @@ -62,18 +61,18 @@ const ChangeDeviceTitle = ({ modelDevice }) => { if (modelDevice.filesystem) { // TRANSLATORS: %s is a formatted mount point like '"/home"' - return sprintf(_("Select a disk to format as %s"), formattedPath(modelDevice.mountPath)); + return sprintf(_("Change the disk to format as %s"), formattedPath(modelDevice.mountPath)); } const mountPaths = modelDevice.getMountPaths(); const hasMountPaths = mountPaths.length > 0; if (!hasMountPaths) { - return _("Select a disk to configure"); + return _("Change the disk to configure"); } if (mountPaths.includes("/")) { - return _("Select a disk to install the system"); + return _("Change the disk to install the system"); } const newMountPaths = modelDevice.partitions @@ -83,7 +82,7 @@ const ChangeDeviceTitle = ({ modelDevice }) => { return sprintf( // TRANSLATORS: %s is a list of formatted mount points like '"/", "/var" and "swap"' (or a // single mount point in the singular case). - _("Select a disk to create %s"), + _("Change the disk to create %s"), formatList(newMountPaths), ); }; @@ -276,10 +275,10 @@ const targetDevices = ( return modelDevice.filesystem ? !device.isUsed : !device.filesystem; }); }; - export type SearchedDeviceMenuProps = { - modelDevice: model.Drive | model.MdRaid; selected: storage.Device; + modelDevice: model.Drive | model.MdRaid; + toggle?: React.ReactElement; deleteFn: (device: model.Drive | model.MdRaid) => void; }; @@ -291,6 +290,7 @@ export type SearchedDeviceMenuProps = { export default function SearchedDeviceMenu({ modelDevice, selected, + toggle, deleteFn, }: SearchedDeviceMenuProps): React.ReactNode { const [isSelectorOpen, setIsSelectorOpen] = useState(false); @@ -312,11 +312,9 @@ export default function SearchedDeviceMenu({ , , ]} - > - {_("Change")}{" "} - - + /> {isSelectorOpen && ( } diff --git a/web/src/components/storage/SpacePolicyMenu.tsx b/web/src/components/storage/SpacePolicyMenu.tsx index 0fab3103ad..f6d080c9d3 100644 --- a/web/src/components/storage/SpacePolicyMenu.tsx +++ b/web/src/components/storage/SpacePolicyMenu.tsx @@ -20,19 +20,20 @@ * find current contact information at www.suse.com. */ -import React from "react"; -import { Flex } from "@patternfly/react-core"; -import MenuButton from "~/components/core/MenuButton"; +import React, { forwardRef } from "react"; +import { Button, Flex, FlexItem } from "@patternfly/react-core"; +import MenuButton, { CustomToggleProps } from "~/components/core/MenuButton"; import Text from "~/components/core/Text"; -import { generatePath, useNavigate } from "react-router"; +import Icon from "~/components/layout/Icon"; +import { useNavigate } from "react-router"; import { useSetSpacePolicy } from "~/hooks/storage/space-policy"; import { SPACE_POLICIES } from "~/components/storage/utils"; import { apiModel, system } from "~/api/storage"; import { STORAGE as PATHS } from "~/routes/paths"; import * as driveUtils from "~/components/storage/utils/drive"; -import { isEmpty } from "radashi"; -import { _ } from "~/i18n"; +import { generateEncodedPath } from "~/utils"; import { model } from "~/types/storage"; +import { isEmpty } from "radashi"; const PolicyItem = ({ policy, modelDevice, isSelected, onClick }) => { return ( @@ -47,8 +48,30 @@ const PolicyItem = ({ policy, modelDevice, isSelected, onClick }) => { ); }; +type SpacePolicyMenuToggleProps = CustomToggleProps & { + drive: model.Drive; +}; + +const SpacePolicyMenuToggle = forwardRef(({ drive, ...props }: SpacePolicyMenuToggleProps, ref) => { + return ( + + ); +}); + type SpacePolicyMenuProps = { - modelDevice: model.Drive; + modelDevice: model.Drive | model.MdRaid; device: system.Device; }; @@ -62,7 +85,7 @@ export default function SpacePolicyMenu({ modelDevice, device }: SpacePolicyMenu const onSpacePolicyChange = (spacePolicy: apiModel.SpacePolicy) => { if (spacePolicy === "custom") { - return navigate(generatePath(PATHS.editSpacePolicy, { list, listIndex })); + return navigate(generateEncodedPath(PATHS.editSpacePolicy, { list, listIndex })); } else { setSpacePolicy(list, listIndex, { type: spacePolicy }); } @@ -71,24 +94,20 @@ export default function SpacePolicyMenu({ modelDevice, device }: SpacePolicyMenu const currentPolicy = driveUtils.spacePolicyEntry(modelDevice); return ( - - {_("Find space")} - ( - - ))} - > - {driveUtils.contentActionsSummary(modelDevice)} - - + ( + + ))} + customToggle={} + /> ); } diff --git a/web/src/components/storage/UnusedMenu.tsx b/web/src/components/storage/UnusedMenu.tsx index b3d672438f..38e51d903e 100644 --- a/web/src/components/storage/UnusedMenu.tsx +++ b/web/src/components/storage/UnusedMenu.tsx @@ -20,69 +20,70 @@ * find current contact information at www.suse.com. */ -import React, { useId } from "react"; -import { Flex } from "@patternfly/react-core"; -import { generatePath, useNavigate } from "react-router"; -import Text from "~/components/core/Text"; -import MenuButton from "~/components/core/MenuButton"; +import React, { forwardRef } from "react"; +import { Button, Flex, FlexItem } from "@patternfly/react-core"; +import Icon from "~/components/layout/Icon"; +import { useNavigate } from "react-router"; +import MenuButton, { CustomToggleProps } from "~/components/core/MenuButton"; import { STORAGE as PATHS } from "~/routes/paths"; import { model } from "~/types/storage"; -import { sprintf } from "sprintf-js"; +import { generateEncodedPath } from "~/utils"; import { _ } from "~/i18n"; type UnusedMenuProps = { deviceModel: model.Drive | model.MdRaid }; +const UnusedMenuToggle = forwardRef(({ ...props }: CustomToggleProps, ref) => { + const description = _("Not configured yet"); + + return ( + + ); +}); + export default function UnusedMenu({ deviceModel }: UnusedMenuProps): React.ReactNode { const navigate = useNavigate(); - const ariaLabelId = useId(); - const toggleTextId = useId(); const { list, listIndex } = deviceModel; - const newPartitionPath = generatePath(PATHS.addPartition, { list, listIndex }); - const formatDevicePath = generatePath(PATHS.formatDevice, { list, listIndex }); - - // TRANSLATORS: %s is the name of device, like '/dev/sda'. - const detailsAriaLabel = sprintf(_("Details for %s"), deviceModel.name); - const description = _("Not configured yet"); + const newPartitionPath = generateEncodedPath(PATHS.addPartition, { list, listIndex }); + const formatDevicePath = generateEncodedPath(PATHS.formatDevice, { list, listIndex }); const filesystemLabel = list === "drives" ? _("Use the disk without partitions") : _("Use the RAID without partitions"); return ( - - - {detailsAriaLabel} - - - {_("Details")} - - navigate(newPartitionPath)} - > - {_("Add or use partition")} - , - navigate(formatDevicePath)} - > - {filesystemLabel} - , - ]} - > - {description} - - + navigate(newPartitionPath)} + > + {_("Add or use partition")} + , + navigate(formatDevicePath)} + > + {filesystemLabel} + , + ]} + customToggle={} + /> ); } diff --git a/web/src/components/storage/VolumeGroupEditor.tsx b/web/src/components/storage/VolumeGroupEditor.tsx index 3381ba95ab..712ca6b013 100644 --- a/web/src/components/storage/VolumeGroupEditor.tsx +++ b/web/src/components/storage/VolumeGroupEditor.tsx @@ -20,25 +20,42 @@ * find current contact information at www.suse.com. */ -import React, { useId } from "react"; -import { Divider, Flex, Title } from "@patternfly/react-core"; -import { generatePath, useNavigate } from "react-router"; -import Link from "~/components/core/Link"; +import React, { forwardRef, useId, useState } from "react"; +import { + Button, + Content, + DataList, + DataListItem, + DataListItemRow, + DataListItemCells, + DataListCell, + DataListAction, + ExpandableSection, + ExpandableSectionToggle, + ExpandableSectionProps, + Flex, + FlexItem, + Title, +} from "@patternfly/react-core"; +import { useNavigate } from "react-router"; +import * as partitionUtils from "~/components/storage/utils/partition"; +import { NestedContent } from "../core"; import Text from "~/components/core/Text"; -import MenuButton from "~/components/core/MenuButton"; -import MenuHeader from "~/components/core/MenuHeader"; +import MenuButton, { CustomToggleProps } from "~/components/core/MenuButton"; import ConfigEditorItem from "~/components/storage/ConfigEditorItem"; -import MountPathMenuItem from "~/components/storage/MountPathMenuItem"; -import Icon from "~/components/layout/Icon"; +import Icon, { IconProps } from "~/components/layout/Icon"; import { STORAGE as PATHS } from "~/routes/paths"; import { model } from "~/types/storage"; import { baseName, formattedPath } from "~/components/storage/utils"; import { contentDescription } from "~/components/storage/utils/volume-group"; import { useDeleteVolumeGroup } from "~/hooks/storage/volume-group"; import { useDeleteLogicalVolume } from "~/hooks/storage/logical-volume"; +import { generateEncodedPath } from "~/utils"; import { isEmpty } from "radashi"; import { sprintf } from "sprintf-js"; import { _, n_, formatList } from "~/i18n"; +import textStyles from "@patternfly/react-styles/css/utilities/Text/text"; +import spacingStyles from "@patternfly/react-styles/css/utilities/Spacing/spacing"; const DeleteVgOption = ({ vg }: { vg: model.VolumeGroup }) => { const deleteVolumeGroup = useDeleteVolumeGroup(); @@ -92,27 +109,74 @@ const EditVgOption = ({ vg }: { vg: model.VolumeGroup }) => { itemId="edit-volume-group" description={_("Modify settings and physical volumes")} role="menuitem" - onClick={() => navigate(generatePath(PATHS.volumeGroup.edit, { id: vg.vgName }))} + onClick={() => navigate(generateEncodedPath(PATHS.volumeGroup.edit, { id: vg.vgName }))} > {_("Edit volume group")} ); }; -const VgMenu = ({ vg }: { vg: model.VolumeGroup }) => { +const LvRow = ({ lv, vg }) => { + const navigate = useNavigate(); + const editPath = generateEncodedPath(PATHS.volumeGroup.logicalVolume.edit, { + id: vg.vgName, + logicalVolumeId: lv.mountPath, + }); + const deleteLogicalVolume = useDeleteLogicalVolume(); + const description = partitionUtils.typeWithSize(lv); + return ( - , ]} - > - {_("Change")}{" "} - - + + + + {lv.mountPath} + , + + {description} + , + ]} + /> + + editPath && navigate(editPath)} + > + {_("Edit")} + , + deleteLogicalVolume(vg.vgName, lv.mountPath)} + isDanger + > + {_("Delete")} + , + ]} + > + + + + + ); }; @@ -124,25 +188,80 @@ const VgHeader = ({ vg }: { vg: model.VolumeGroup }) => { return {sprintf(title, vg.vgName)}; }; -const LogicalVolumes = ({ vg }: { vg: model.VolumeGroup }) => { +type VgMenuToggleProps = CustomToggleProps & { + vg: model.VolumeGroup; +}; + +const VgMenuToggle = forwardRef(({ vg, ...props }: VgMenuToggleProps, ref) => { + return ( + + ); +}); + +const VgMenu = ({ vg }: { vg: model.VolumeGroup }) => { + return ( + } + items={[, ]} + /> + ); +}; + +const AddLvButton = ({ vg }: { vg: model.VolumeGroup }) => { const navigate = useNavigate(); - const deleteLogicalVolume = useDeleteLogicalVolume(); - const ariaLabelId = useId(); - const toggleTextId = useId(); - const newLvPath = generatePath(PATHS.volumeGroup.logicalVolume.add, { id: vg.vgName }); + const newLvPath = generateEncodedPath(PATHS.volumeGroup.logicalVolume.add, { id: vg.vgName }); + + return ( + + ); +}; + +const LogicalVolumes = ({ vg }: { vg: model.VolumeGroup }) => { + const toggleId = useId(); + const contentId = useId(); + const [isExpanded, setIsExpanded] = useState(false); const menuAriaLabel = sprintf(_("Logical volumes for %s"), vg.vgName); + const toggle = () => setIsExpanded(!isExpanded); + const iconName: IconProps["name"] = isExpanded ? "unfold_less" : "unfold_more"; + const commonProps: Pick = { + toggleId, + contentId, + isExpanded, + }; + if (isEmpty(vg.logicalVolumes)) { - return ( - - {_("Add logical volume")} - - ); + return ; } - // FIXME: The markup is strange just for consistency with PartitionsMenu. See FIXME there. - // The markup should be fixed in both places (eg. to use MenuGroup) in a consistent way. - const description = n_( "The following logical volume will be created", "The following logical volumes will be created", @@ -150,52 +269,37 @@ const LogicalVolumes = ({ vg }: { vg: model.VolumeGroup }) => { ); return ( - - - {_("Details")} - - - {menuAriaLabel} - - , - , - ] - .concat( - vg.logicalVolumes.map((lv) => { - return ( - deleteLogicalVolume(vg.vgName, lv.mountPath)} - /> - ); - }), - ) - .concat( - navigate(newLvPath)} - > - {_("Add logical volume")} - , - )} + + - {contentDescription(vg)} - + + {contentDescription(vg)} + + + + + + + {description} + + {vg.logicalVolumes.map((lv) => { + return ; + })} + + + + + + + ); }; @@ -204,10 +308,8 @@ export type VolumeGroupEditorProps = { vg: model.VolumeGroup }; export default function VolumeGroupEditor({ vg }: VolumeGroupEditorProps) { return ( - } - content={} - actions={} - /> + }> + + ); } diff --git a/web/src/components/storage/dasd/DASDTable.tsx b/web/src/components/storage/dasd/DASDTable.tsx index 0af1423999..4a44e48c01 100644 --- a/web/src/components/storage/dasd/DASDTable.tsx +++ b/web/src/components/storage/dasd/DASDTable.tsx @@ -364,7 +364,8 @@ type DASDTableAction = | { type: "REQUEST_FORMAT"; payload: DASDTableState["devicesToFormat"] } | { type: "CANCEL_FORMAT_REQUEST" } | { type: "START_WAITING"; payload: DASDDevice["id"][] } - | { type: "UPDATE_WAITING"; payload: DASDDevice["id"] }; + | { type: "UPDATE_WAITING"; payload: DASDDevice["id"] } + | { type: "UPDATE_DEVICE"; payload: DASDDevice }; /** * Reducer function that handles all DASD table state transitions. @@ -408,6 +409,16 @@ const reducer = (state: DASDTableState, action: DASDTableAction): DASDTableState const waitingFor = prev.filter((id) => action.payload !== id); return { ...state, waitingFor }; } + + case "UPDATE_DEVICE": { + const selectedDevices = state.selectedDevices.map((dev) => + action.payload.id === dev.id ? action.payload : dev, + ); + const devicesToFormat = state.devicesToFormat.map((dev) => + action.payload.id === dev.id ? action.payload : dev, + ); + return { ...state, selectedDevices, devicesToFormat }; + } } }; @@ -486,6 +497,7 @@ export default function DASDTable() { return client.onEvent((event) => { if (event.type === "DASDDeviceChanged") { + dispatch({ type: "UPDATE_DEVICE", payload: event.device }); dispatch({ type: "UPDATE_WAITING", payload: event.device.id }); } }); diff --git a/web/src/components/users/PasswordCheck.tsx b/web/src/components/users/PasswordCheck.tsx index 466e9ed6d8..902028b321 100644 --- a/web/src/components/users/PasswordCheck.tsx +++ b/web/src/components/users/PasswordCheck.tsx @@ -20,8 +20,8 @@ * find current contact information at www.suse.com. */ -import { Alert } from "@patternfly/react-core"; import React, { useEffect, useState } from "react"; +import SmallWarning from "~/components/core/SmallWarning"; import { checkPassword } from "~/api/users"; import { _ } from "~/i18n"; @@ -48,7 +48,7 @@ const PasswordCheck = ({ password }: { password: string }) => { return (
- +
); }; diff --git a/web/src/components/users/RootUser.test.tsx b/web/src/components/users/RootUser.test.tsx index 7108765397..ef7ccde924 100644 --- a/web/src/components/users/RootUser.test.tsx +++ b/web/src/components/users/RootUser.test.tsx @@ -22,7 +22,7 @@ import React from "react"; import { screen } from "@testing-library/react"; -import { plainRender } from "~/test-utils"; +import { installerRender } from "~/test-utils"; import { RootUser } from "~/components/users"; import { USER } from "~/routes/paths"; @@ -44,7 +44,7 @@ beforeEach(() => { describe("RootUser", () => { it("renders an edit action", () => { - plainRender(); + installerRender(); const editLink = screen.getByRole("link", { name: "Edit" }); expect(editLink).toHaveAttribute("href", USER.rootUser.edit); @@ -52,7 +52,7 @@ describe("RootUser", () => { describe("if no method is defined", () => { it("renders them as 'Not defined'", () => { - plainRender(); + installerRender(); expect(screen.getAllByText("Not defined").length).toEqual(2); }); @@ -64,7 +64,7 @@ describe("RootUser", () => { }); it("renders the 'Defined (hidden)' text", async () => { - plainRender(); + installerRender(); screen.getByText("Defined (hidden)"); }); @@ -76,7 +76,7 @@ describe("RootUser", () => { }); it("renders its truncated content keeping the comment visible when possible", async () => { - plainRender(); + installerRender(); screen.getByText("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDM+"); screen.getByText("test@example"); diff --git a/web/src/context/app.tsx b/web/src/context/app.tsx index 4bf3cb2646..c4afb90bf3 100644 --- a/web/src/context/app.tsx +++ b/web/src/context/app.tsx @@ -23,6 +23,7 @@ import React from "react"; import { InstallerClientProvider } from "./installer"; import { InstallerL10nProvider } from "./installerL10n"; +import { StorageUiStateProvider } from "./storage-ui-state"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { localConnection } from "~/utils"; @@ -57,7 +58,9 @@ function AppProviders({ children }: React.PropsWithChildren) { return ( - {children} + + {children} + ); diff --git a/web/src/context/storage-ui-state.tsx b/web/src/context/storage-ui-state.tsx new file mode 100644 index 0000000000..9b2629c1d8 --- /dev/null +++ b/web/src/context/storage-ui-state.tsx @@ -0,0 +1,97 @@ +/* + * Copyright (c) [2025] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React, { useCallback, useState } from "react"; + +const StorageUiStateContext = React.createContext(null); + +/** + * Temporary context to store the state of the different elements of the storage UI (tabs, + * expandable sections, etc.) while the user navigates through the different storage routes. + * + * Initially that state information was stored in the URL (see previous commits), using + * useSearchParams to update it. But the update function provided by useSearchParams triggers a + * navigate, which resets the scroll to the top. + * + * We tried to solve the scroll problem while still using the URL to store the state, but the + * following solutions were discarded for several reasons. Some of then could be re-evaluated if the + * circumstances change. + * + * Discarded 1: Using ScrollRestoration to keep the scroll position when navigating. It does not work + * because our problem is not with the scroll of the page, but with the scroll of a given container + * within the page. We would need to patch ReactRouter to be able to use scroll restoration in an + * element of the page. Something like + * https://github.com/joshkel/react-router/commit/2bbf60ec00a3efc419e0d1f00761fecd43beeb9b + * + * Discarded 2: Preventing useSearchParams to rely on navigate. Discussed here + * https://github.com/remix-run/react-router/discussions/9851 + * There is no official way to really prevent that navigation. + * + * Discarded 3: Using nuq. It really allows to implement that behavior, but integration in our + * project is not trivial at this point in time. + * + * Discarded 4: Using Tansack Router. It allows both fine-grained control of the scroll for several + * areas and changing the query params without re-rendering. But changing the router just for this + * is too much. + * + * Discarded 5: Updating the browser history without relying on useSearchParams. Causes the router + * and the browser histories to go out of sync, which is problematic when browsing through the + * interface (eg. returning to the storage page after having visited a form). + * + * Discarded 6: Using shouldRevalidate to return false and interrupt the process (requires also + * redefining the loader). This prevents the reloading of the information, but it does not really + * prevent the re-render, so the scroll reset is still there. + * + * In the end, we implemented this context to store the state information of the UI elements. + * Hopefully it can be reverted in the future to use the URL again. + * + * This returns the functions to check and to modify the status information. + */ +function useStorageUiState() { + const context = React.useContext(StorageUiStateContext); + if (context === undefined) { + throw new Error("useStorageUiState must be used within a StorageUiStateProvider"); + } + + return context; +} + +/* + * Provider for the state of the storage UI elements. See useStorageUiState. + */ +function StorageUiStateProvider({ children }: React.PropsWithChildren) { + const [state, setState] = useState(new Map()); + const setUiState = useCallback( + (newState) => { + setState(typeof newState === "function" ? newState(new Map(state)) : newState); + }, + [state, setState], + ); + + return ( + + {children} + + ); +} + +export { StorageUiStateProvider, useStorageUiState }; diff --git a/web/src/languages.json b/web/src/languages.json index db29e01a29..689ca61bcc 100644 --- a/web/src/languages.json +++ b/web/src/languages.json @@ -1,5 +1,6 @@ { "ca-ES": "Català", + "cs-CZ": "Čeština", "de-DE": "Deutsch", "en-US": "English", "es-ES": "Español", diff --git a/web/src/po/po.ca.js b/web/src/po/po.ca.js index 5380c0fb7b..4f02d1c6a2 100644 --- a/web/src/po/po.ca.js +++ b/web/src/po/po.ca.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Selecció de la zona horària" ], + "\"%s\"": [ + "%s" + ], + "\"%s\" does not exist or is no longer available.": [ + "La xarxa %s no existeix o ja no està disponible." + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -139,9 +145,6 @@ export default { "Add another address": [ "Afegeix-hi una altra adreça" ], - "Add another partition or mount an existing one": [ - "Afegiu-hi una altra partició o munteu-ne una d'existent" - ], "Add device menu": [ "Afegeix el menú del dispositiu" ], @@ -327,9 +330,6 @@ export default { "Change Language": [ "Canvia'n la llengua" ], - "Change boot options": [ - "Canvia les opcions d'arrencada" - ], "Change device menu": [ "Canvia el menú del dispositiu" ], @@ -354,15 +354,27 @@ export default { "Change selection": [ "Canvia la selecció" ], + "Change the disk to configure": [ + "Canvieu el disc per configurar" + ], + "Change the disk to create %s": [ + "Canvieu el disc per crear-hi %s" + ], + "Change the disk to format as %s": [ + "Canvia el disc per formatar com a %s" + ], + "Change the disk to install the system": [ + "Canvieu el disc per instal·lar-hi el sistema" + ], "Change the file system or mount point": [ "Canvia'n el sistema de fitxers o el punt de muntatge" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "Els canvis en aquesta configuració actualitzaran immediatament la secció de Resultat que hi ha a continuació." + ], "Channel ID": [ "Identificador del canal" ], - "Check the %d planned actions": [ - "Comproveu les %d accions planificades" - ], "Check the authentication parameters.": [ "Comproveu els paràmetres d'autenticació." ], @@ -396,9 +408,6 @@ export default { "Close": [ "Tanca" ], - "Collapse the list of planned actions": [ - "Replega la llista d'accions previstes" - ], "Configuration out of sync": [ "Configuració no sincronitzada" ], @@ -609,9 +618,6 @@ export default { "Details": [ "Detalls" ], - "Details for %s": [ - "Detalls per a %s" - ], "Details will appear after the connection is successfully established.": [ "Els detalls apareixeran quan la connexió s'hagi establert correctament." ], @@ -666,9 +672,6 @@ export default { "Download logs": [ "Baixa els registres" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Durant la instal·lació, es fan diverses accions per configurar el disseny que es mostra a la taula següent." - ], "Edit": [ "Edita" ], @@ -732,8 +735,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Exemple: https://elmeuservidor.com" + "Example: %s": [ + "Exemple: %s" ], "Excellent signal": [ "Senyal excel·lent" @@ -791,8 +794,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Filtra per territori, codi de zona horària o desplaçament d'UTC" ], - "Find space": [ - "Aconsegueix espai" + "Final layout": [ + "Disposició final" + ], + "Final structure of the system after installation.": [ + "Estructura final del sistema després de la instal·lació:" ], "Find space in %s": [ "Cerca espai a %s" @@ -918,6 +924,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Si continueu, les particions del disc dur es modificaran segons la configuració d'instal·lació proporcionada." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "Si voleu desactivar aquesta comprovació, especifiqueu \"inst.ay_check=0\" a la línia d'ordres del nucli." + ], "In progress": [ "En curs" ], @@ -978,8 +987,8 @@ export default { "Install using several devices without modifying existing partitions.": [ "Instal·la a dispositius diversos sense modificar-ne les particions existents." ], - "Installation Devices": [ - "Dispositius d'instal·lació" + "Installation devices": [ + "Dispositius per a la instal·lació" ], "Installation will take %s.": [ "La instal·lació necessitarà %s." @@ -1158,6 +1167,9 @@ export default { "More languages might be available for the selected product at [Localization] page": [ "És possible que hi hagi més llengües disponibles per al producte seleccionat a la pàgina [Localitzation]" ], + "More storage options": [ + "Més opcions d'emmagatzematge" + ], "Moreover, the following partition will be created.": [ "A més a més, es crearà la partició següent:", "A més a més, es crearan les particions següents:" @@ -1271,6 +1283,9 @@ export default { "No logical volumes are defined yet": [ "Encara no s'ha definit cap volum lògic" ], + "No partitions will be automatically configured for booting.": [ + "No es configurarà cap partició per a l'arrencada automàticament." + ], "No partitions will be automatically configured for booting. Use with caution.": [ "No es configurarà automàticament cap partició per a l'arrencada. Useu-ho amb precaució." ], @@ -1343,24 +1358,27 @@ export default { "Only reused partitions will be used.": [ "Només s'usaran particions reutilitzades." ], + "Options for partition %s": [ + "Opcions per a la partició %s" + ], "Options toggle": [ "Canvi d'opcions" ], - "Other options": [ - "Altres opcions" - ], - "Other options toggle": [ - "Canvi d'altres opcions" - ], "Overview": [ "Resum" ], "Package installation failed": [ "Ha fallat la instal·lació del paquet." ], + "Partition %s": [ + "Partició %s" + ], "Partition Info": [ "Informació de la partició" ], + "Partitions": [ + "Particions" + ], "Partitions needed for booting will also be adapted": [ "També s'adaptaran les particions necessàries per a l'arrencada" ], @@ -1376,14 +1394,26 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Es canviarà la mida de les particions que no es reutilitzin, si cal." ], - "Partitions to boot will be allocated at the following device.": [ - "Les particions per a l'arrencada s'assignaran al dispositiu següent." + "Partitions to boot will be set up if needed at %s.": [ + "Les particions per arrencar s'establiran, si cal, a %s." + ], + "Partitions to boot will be set up if needed at the following device.": [ + "Les particions per arrencar s'establiran, si cal, al dispositiu següent:" ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Les particions per a l'arrencada s'assignaran al disc d'instal·lació %s." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Les particions per arrencar s'establiran, si cal, al disc d'instal·lació, segons la ubicació del sistema de fitxers %s." ], - "Partitions to boot will be allocated at the installation disk.": [ - "Les particions per a l'arrencada s'assignaran al disc d'instal·lació." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Les particions per arrencar s'establiran, si cal, al disc d'instal·lació, segons la ubicació del sistema de fitxers %s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Les particions per arrencar s'establiran, si cal, al disc d'instal·lació. Actualment és %1$s, segons la ubicació del sistema de fitxers %2$s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Les particions per arrencar s'establiran, si cal, al disc d'instal·lació. Actualment és %1$s, segons la ubicació del sistema de fitxers %2$s." + ], + "Partitions to host \"system\" will be created if needed.": [ + "Si cal, es crearan particions per allotjar-hi el sistema." ], "Partitions will be used and created for %s": [ "Les particions s'usaran i es crearan per a %s" @@ -1448,8 +1478,8 @@ export default { "Product is already registered": [ "El producte ja està registrat." ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Protecció de la informació emmagatzemada als sistemes de fitxers nous, incloses dades, programes i fitxers del sistema." + "Protection for the information stored at the new file systems, including data, programs, and system files.": [ + "Protecció de la informació emmagatzemada als nous sistemes de fitxers, incloses dades, programes i fitxers del sistema." ], "Provide email address": [ "Proporcioneu una adreça de correu electrònic." @@ -1538,6 +1568,9 @@ export default { "Result": [ "Resultat" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "Resultat d'aplicar la configuració descrita a la secció de Configuració anterior." + ], "Reused partitions will not be shrunk": [ "Les particions reutilitzades no s'encongiran" ], @@ -1598,21 +1631,9 @@ export default { "Select a disk": [ "Seleccioneu un disc" ], - "Select a disk to configure": [ - "Seleccioneu un disc per configurar-lo" - ], - "Select a disk to create %s": [ - "Seleccioneu un disc per crear-hi el punt de muntatge %s" - ], "Select a disk to define partitions or to mount": [ "Seleccioneu un disc per definir-ne les particions o per muntar-lo" ], - "Select a disk to format as %s": [ - "Seleccioneu un disc per formatar-lo com a %s" - ], - "Select a disk to install the system": [ - "Seleccioneu un disc per instal·lar-hi el sistema" - ], "Select a product": [ "Seleccioneu un producte" ], @@ -1640,9 +1661,6 @@ export default { "Select or enter a valid mount point": [ "Seleccioneu o introduïu un punt de muntatge vàlid" ], - "Select the disk to configure partitions for booting": [ - "Seleccioneu el disc per configurar-hi les particions per a arrencar" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Seleccioneu què fer de cada partició per trobar espai per assignar-hi el sistema nou." ], @@ -1880,6 +1898,9 @@ export default { "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ "El pas final per configurar el Mòdul de plataforma de confiança (TPM) per obrir automàticament dispositius encriptats es farà durant la primera arrencada del nou sistema. Perquè això funcioni, la màquina ha d'arrencar directament amb el carregador d'arrencada nou." ], + "The following actions will be performed in the system during installation.": [ + "Es faran les accions següents al sistema durant la instal·lació:" + ], "The following logical volume will be created": [ "Es crearà el volum lògic següent:", "Es crearan els volums lògics següents:" @@ -1947,6 +1968,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "La contrasenya no caldrà per arrencar i accedir a les dades si el TPM pot verificar la integritat del sistema. El segellat de TPM requereix que el nou sistema s'iniciï directament a la primera execució." ], + "The product will be registered with \"%s\" hostname": [ + "El producte es registrarà amb el nom d'amfitrió %s." + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "La mida de %1$s s'ajustarà dinàmicament segons la quantitat de RAM del sistema i de la presència d'un sistema de fitxers separat per a %2$s." ], @@ -2075,6 +2099,9 @@ export default { "Tmpfs": [ "Tmpfs" ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "Per assegurar que el nou sistema pugui arrencar, l'instal·lador potser haurà de crear o configurar algunes particions al disc apropiat." + ], "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ "Per garantir que el sistema nou pugui arrencar, és possible que l'instal·lador hagi de crear o configurar algunes particions al disc adequat." ], @@ -2264,6 +2291,9 @@ export default { "Using transient hostname: %s": [ "S'usa un nom d'amfitrió transitori: %s" ], + "Volume group %s": [ + "Grup de volums %s" + ], "Volume group '%s' already exists. Enter a different name.": [ "El grup de volums %s ja existeix. Introduïu un nom diferent." ], diff --git a/web/src/po/po.cs.js b/web/src/po/po.cs.js new file mode 100644 index 0000000000..b1593f6d70 --- /dev/null +++ b/web/src/po/po.cs.js @@ -0,0 +1,1924 @@ +export default { + "": { + "plural-forms": (n) => (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2, + "language": "cs" + }, + " Timezone selection": [ + " Výběr časového pásma" + ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], + "%1$s will still contain the LVM group '%2$s' and any partition needed to boot": [ + "%1$s bude nadále obsahovat LVM skupinu '%2$s’ a nějaký oddíl potřebný pro spuštění systému" + ], + "%d of %d": [ + "%d z %d" + ], + "%s - %s": [ + "%s - %s" + ], + "%s [must be registered].": [ + "%s [musí být registrován]." + ], + "%s disk": [ + "%s disk" + ], + "%s has been registered with below information.": [ + "%s byl zaregistrován společně s informacemi níže." + ], + "%s is an immutable system with atomic updates. It uses a read-only Btrfs file system updated via snapshots.": [ + "%s je neměnný systém s atomickými aktualizacemi. Používá souborový systém Btrfs pouze pro čtení aktualizovaný pomocí snímků." + ], + "%s logo": [ + "%s logo" + ], + "%s will be created as a logical volume": [ + "", + "", + "" + ], + "%s will still contain the configured LVM groups and any partition needed to boot": [ + "%s bude obsahovat nakonfigurované skupiny LVM a oddíl potřebný pro spuštění systému" + ], + "%s with %d partitions": [ + "%s s %d oddíly" + ], + "A %1$s of %2$s will be created for %3$s if possible": [ + "Pokud to je možné, bude vytvořeno %1$s o velikosti %2$s pro %3$s" + ], + "A %1$s of at least %2$s will be created for %3$s if possible": [ + "Pokud to je možné, bude vytvořeno %1$s o velikosti nejméně %2$s pro %3$s" + ], + "A %1$s with a size between %2$s and %3$s will be created for %4$s if possible": [ + "Pokud to je možné, bude vytvořeno %1$s o velikosti mezi %2$s a %3$s pro %4$s" + ], + "A generic minimum size of %1$s will be used for the new %2$s": [ + "Pro nové %2$s bude použita obecná minimální velikost %1$s" + ], + "A generic size range between %1$s and %2$s will be used for the new %3$s": [ + "Obecná velikost v rozsahu od %1$s do %2$s pro nový %3$s" + ], + "Accept": [ + "Přijmout" + ], + "Action": [ + "Akce" + ], + "Actions": [ + "Akce" + ], + "Activate": [ + "Aktivace" + ], + "Activate new disk": [ + "Aktivace nového disku" + ], + "Activate zFCP disk": [ + "Aktivovat disk zFCP" + ], + "Activated": [ + "Aktivováno" + ], + "Add": [ + "Přidat" + ], + "Add DNS": [ + "Přidat DNS" + ], + "Add an address": [ + "Přidat adresu" + ], + "Add another DNS": [ + "Přidat další DNS" + ], + "Add another address": [ + "Přidat další adresu" + ], + "Add device menu": [ + "Nabídka přidat zařízení" + ], + "Add logical volume": [ + "Přidat logický svazek" + ], + "Add or use partition": [ + "Přidat nebo použít oddíl" + ], + "Address": [ + "Adresa" + ], + "Addresses": [ + "Adresy" + ], + "Addresses data list": [ + "Seznam údajů o adresách" + ], + "Adjust the settings below to make the new system fit into the available space.": [ + "Upravte nastavení níže, aby bylo možné nový systém nasadit na dostupné volné místo." + ], + "All conflicts have been resolved, or none were detected. You can safely continue with your setup.": [ + "Nebyly zjištěny žádné konflikty nebo byly všechny vyřešeny. Nyní můžete bezpečně pokračovat s vaším nastavením." + ], + "All fields are required": [ + "Všechna pole jsou povinná" + ], + "All network connections managed through this interface are currently set to be used only during installation and will not be copied to the installed system": [ + "Všechna síťová připojení spravovaná pomocí tohoto rozhraní jsou v současnosti nastavena tak, aby se použila pouze během instalace a nebudou zkopírována do instalovaného systému" + ], + "Allow growing": [ + "Povolit růst" + ], + "Already using all available devices": [ + "Již se používají všechna dostupná zařízení" + ], + "Already using all available disks": [ + "Již se používají všechny dostupné disky" + ], + "Any partition needed to boot will be configured.": [ + "Kterýkoliv oddíl bude nakonfigurován pro potřeby spuštění systému." + ], + "Apply selected solution": [ + "Aplikovat vybrané řešení" + ], + "Applying changes": [ + "Aplikování změn" + ], + "At least one address must be provided for selected mode": [ + "Pro zvolený režim musí být uvedena alespoň jedna adresa" + ], + "At least one partition will be deleted": [ + "" + ], + "At this point you can power off the machine.": [ + "Nyní můžete počítač vypnout." + ], + "At this point you can reboot the machine to log in to the new system.": [ + "Nyní můžete počítač restartovat a přihlásit se do nového systému." + ], + "Authentication": [ + "Přihlašování" + ], + "Authentication by initiator": [ + "Ověření iniciátorem" + ], + "Authentication by target": [ + "Ověřování cílem" + ], + "Auto LUNs Scan": [ + "Automatické skenování jednotek LUN" + ], + "Automatic": [ + "Automatický" + ], + "Automatic (DHCP)": [ + "Automatická (DHCP)" + ], + "Automatic LUN scan is [disabled]. LUNs have to be manually configured after activating a controller.": [ + "Automatické skenování LUN je [zakázáno]. Po aktivaci řadiče je třeba LUNy konfigurovat ručně." + ], + "Automatic LUN scan is [enabled]. Activating a controller which is running in NPIV mode will automatically configures all its LUNs.": [ + "Automatické skenování LUN je [povoleno]. Aktivací řadiče, běžícího v režimu NPIV, se automaticky zkonfigurují všechny jeho LUN." + ], + "Available products": [ + "Dostupné produkty" + ], + "Back": [ + "Zpět" + ], + "Based on the amount of RAM in the system, a %1$s of %2$s will be planned for %3$s": [ + "Na základě množství paměti RAM v systému bude navržený %1$s o velikosti %2$s pro %3$s" + ], + "Bcachefs": [ + "Bcachefs" + ], + "Before %s": [ + "Před %s" + ], + "Before installing, you have to make some decisions. Click on each section to review the settings.": [ + "Před zahájením instalace bude nutné provést několik rozhodnutí. Pro kontrolu nastavení klikněte na každou část zvlášt." + ], + "Before starting the installation, you need to address the following problems:": [ + "Před zahájením instalace vyřešte tyto problémy:" + ], + "Below %s devices are offline and cannot be formatted.": [ + "Zařízení %s níže jsou offline a nemohou být naformátovány." + ], + "Beta": [ + "Beta" + ], + "Bind to MAC address": [ + "Svázání s MAC adresou" + ], + "Bind to device name": [ + "Navázat na název zařízení" + ], + "Binding settings for '%s'": [ + "Nastavení navázání pro ‘%s'" + ], + "BitLocker": [ + "BitLocker" + ], + "Btrfs": [ + "Btrfs" + ], + "Btrfs with snapshots": [ + "Btrfs se snímky" + ], + "Cancel": [ + "Zrušit" + ], + "Cannot be changed in remote installation": [ + "U instalace na dálku nelze změnit" + ], + "Cannot connect to Agama server": [ + "Nelze se připojit k serveru Agama" + ], + "Change": [ + "Změnit" + ], + "Change Language": [ + "Změnit jazyk" + ], + "Change device menu": [ + "Nabídka změny zařízení" + ], + "Change display language": [ + "Změnit zobrazovaný jazyk" + ], + "Change display language and keyboard layout": [ + "Změnit zobrazovaný jazyk a rozložení klávesnice" + ], + "Change filters and try again.": [ + "Upravte filtry a zkuste to znovu." + ], + "Change keyboard": [ + "Změnit klávesnici" + ], + "Change keyboard layout": [ + "Změnit rozložení kláves" + ], + "Change product": [ + "Změnit produkt" + ], + "Change selection": [ + "Změnit výběr" + ], + "Change the file system or mount point": [ + "Změnit systém souborů nebo přípojný bod" + ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], + "Channel ID": [ + "ID kanálu" + ], + "Check the authentication parameters.": [ + "Zkontrolujte přihlašovací údaje" + ], + "Check the following before continuing": [ + "Před pokračování zkontrolujte následující" + ], + "Choose a disk for placing the boot loader": [ + "Výběr disku pro umístění zavaděče" + ], + "Choose device to bind by MAC": [ + "Zvolte zařízení pro navázání podle MAC" + ], + "Choose device to bind by name": [ + "Zvolte zařízení pro navázání podle názvu" + ], + "Choose how the connection should be associated with a network device. This helps control which device the connection uses.": [ + "Zvolte způsob, jakým má být připojení přiřazeno k danému síťovému zařízení. To je nutné pro ovládání zařízení, které bude spojení používat." + ], + "Clear": [ + "Smazat" + ], + "Clear all filters": [ + "Vymazat všechny filtry" + ], + "Close": [ + "Zavřít" + ], + "Configuration out of sync": [ + "Konfigurace není synchronizována" + ], + "Configuration read from the iSCSI Boot Firmware Table (iBFT).": [ + "Konfigurace byla načtena z tabulky iSCSI Boot Firmware Table (iBFT)." + ], + "Configuration unreachable or invalid": [ + "Konfigurace není dostupná nebo je neplatná" + ], + "Configure DASD": [ + "Konfigurovat DASD" + ], + "Configure LVM Volume Group": [ + "Nastavit skupinu svazků LVM" + ], + "Configure LVM logical volume at %s volume group": [ + "Nakonfigurovat logický LVM svazek na skupině svazků %s" + ], + "Configure device %s": [ + "Konfigurovat zařízení %s" + ], + "Configured for installation only": [ + "Konfigurováno pouze pro instalaci" + ], + "Configuring the product, please wait ...": [ + "Konfigurace produktu, počkejte prosím..." + ], + "Confirm": [ + "Potvrdit" + ], + "Confirm Installation": [ + "Potvrdit instalaci" + ], + "Confirm that you really want to continue.": [ + "Prosím potvrďte, že opravdu chcete pokračovat." + ], + "Congratulations!": [ + "Blahopřejeme!" + ], + "Connect": [ + "Připojit" + ], + "Connect to %s": [ + "Připojit k %s" + ], + "Connect to iSCSI targets": [ + "Připojení k cílům iSCSI" + ], + "Connected": [ + "Připojeno" + ], + "Connected (%s)": [ + "Připojeno (%s)" + ], + "Connected device": [ + "Připojené zařízení" + ], + "Connected devices": [ + "Připojená zařízení" + ], + "Connecting to %s": [ + "Připojování k %s" + ], + "Connection details": [ + "Detaily připojení" + ], + "Connection is available to all devices.": [ + "Spojení je dostupné pro všechna zařízení." + ], + "Connection is bound to MAC address %s.": [ + "Spojení je svázáno s MAC adresou %s" + ], + "Connection is bound to device %s.": [ + "Spojení je svázáno se zařízením %s" + ], + "Connection not found or lost": [ + "Spojení nenalezeno nebo ztraceno" + ], + "Content": [ + "Obsah" + ], + "Continue": [ + "Pokračovat" + ], + "Continuing without installing the package can result in a broken system. In some cases the system might not even boot.": [ + "Pokračování bez instalace tohoto balíčku může vést k poškození systému. V některých případech systém nebude dokonce ani schopný se spustit." + ], + "Controllers": [ + "Řadiče" + ], + "Could not authenticate against the server, please check it.": [ + "Nezdařilo se ověření vůči serveru, zkontrolujte to prosím." + ], + "Could not connect to %s": [ + "Připojení k %s se nezdařilo" + ], + "Could not log in. Please, make sure that the password is correct.": [ + "Nelze se přhlásit. Zkontrolujte správnost hesla." + ], + "Create user": [ + "Vytvořit uživatele" + ], + "Current %s": [ + "Aktuálně %s" + ], + "Current content": [ + "Aktuální obsah" + ], + "Custom": [ + "Vlastní" + ], + "DASD": [ + "DASD" + ], + "DASD %s": [ + "DASD %s" + ], + "DIAG": [ + "DIAG" + ], + "DNS": [ + "DNS" + ], + "Deactivate": [ + "Deaktivace" + ], + "Deactivated": [ + "Deaktivováno" + ], + "Define a new LVM on the disk": [ + "Definovat nové LVM na disku" + ], + "Define a new LVM on top of one or several disks": [ + "Definovat nové LVM nad jedním nebo více disky" + ], + "Define a user now": [ + "Nyní definujte uživatele" + ], + "Define the first user with admin (sudo) privileges for system management.": [ + "" + ], + "Defined (hidden)": [ + "" + ], + "Delete": [ + "Smazat" + ], + "Delete current content": [ + "Odstranit aktuální obsah" + ], + "Description": [ + "Popis" + ], + "Destroy current data and format partition as": [ + "Zahodit současná data a naformátovat oddíl jako" + ], + "Details": [ + "Podrobnosti" + ], + "Details will appear after the connection is successfully established.": [ + "Podrobnosti se zobrazí poté, co bude spojení úspěšně sestaveno." + ], + "Device": [ + "Zařízení" + ], + "Device Selection": [ + "Výběr zařízení" + ], + "Device details": [ + "Podrobnosti o zařízení" + ], + "Discard": [ + "Vyřadit" + ], + "Discard the maximum size and continue with simplified configuration": [ + "Zahodit maximální velikost a pokračovat se zjednodušenou konfigurací" + ], + "Disconnected": [ + "Odpojeno" + ], + "Discover": [ + "Objevit" + ], + "Discover iSCSI Targets": [ + "Najít cílové stanice iSCSI" + ], + "Discover iSCSI targets": [ + "Objevit iSCSI cíle" + ], + "Disk": [ + "Disk" + ], + "Disks": [ + "Disky" + ], + "Do not configure": [ + "Nekonfigurujte" + ], + "Do not format %s and keep the data": [ + "NEformátovat %s a ponechat data" + ], + "Download logs": [ + "Stáhnout protokoly" + ], + "Edit": [ + "Upravit" + ], + "Edit %s": [ + "Upravit %s" + ], + "Edit connection %s": [ + "Upravit připojení %s" + ], + "Edit connection settings": [ + "Upravit nastavení připojení" + ], + "Edit user": [ + "Upravit uživatele" + ], + "Email": [ + "E-mail" + ], + "Encrypt the system": [ + "Šifrování systému" + ], + "Encrypted Device": [ + "Šifrované zařízení" + ], + "Encryption": [ + "Šifrování" + ], + "Encryption Password": [ + "Heslo pro šifrování" + ], + "Encryption is disabled": [ + "Šifrování je vypnuto" + ], + "Encryption is enabled": [ + "Šifrování je zapnuto" + ], + "Encryption is enabled using TPM unlocking": [ + "Šifrování je zapnuto s odemykáním čipem TPM" + ], + "Encryption settings": [ + "Nastavení šifrování" + ], + "Enter a name": [ + "Zadejte jméno" + ], + "ExFAT": [ + "" + ], + "Example: %s": [ + "Například: %s" + ], + "Excellent signal": [ + "Výborný signál" + ], + "Expiration date": [ + "Datum expirace" + ], + "Ext2": [ + "" + ], + "Ext3": [ + "" + ], + "Ext4": [ + "" + ], + "Extend the installation beyond the currently selected device": [ + "", + "", + "" + ], + "Extend the installation beyond the currently selected disk": [ + "", + "", + "" + ], + "Extensions": [ + "Rozšíření" + ], + "F2FS": [ + "" + ], + "FAT": [ + "" + ], + "Failed to calculate a storage layout": [ + "Nepodařilo se vypočítat návrh úložiště" + ], + "File system": [ + "Typ systému souborů" + ], + "Filesystems": [ + "Souborové systémy" + ], + "Filter by description or keymap code": [ + "Filtrování podle popisu nebo kódu mapy kláves" + ], + "Filter by language, territory or locale code": [ + "Filtrování podle jazyka, území nebo kódu lokality" + ], + "Filter by pattern title or description": [ + "Filtrování podle názvu nebo popisu vzoru" + ], + "Filter by territory, time zone code or UTC offset": [ + "Filtrování podle území, kódu časového pásma nebo posunu od UTC" + ], + "Final layout": [ + "Konečné rozvržení" + ], + "Find space in %s": [ + "Najít místo na %s" + ], + "Finish": [ + "Dokončit" + ], + "Finished": [ + "Dokončeno" + ], + "First user": [ + "První uživatel" + ], + "For more advanced needs, users can switch to this full-page, dedicated path version that provides more space for detailed views, additional columns, filters, and extended functionality.": [ + "Pro ještě pokročilejší potřeby si mohou uživatelé přepnout na tuto celou stránku, vybranou verzi cesty, která poskytuje větší prostor pro podrobnější zobrazení, dodatečné sloupce, filtry a rozšířenou funkcionalitu." + ], + "Format": [ + "Formát" + ], + "Format RAID %s": [ + "Formátovat RAID %s" + ], + "Format device as": [ + "Formátovat zařízení jako" + ], + "Format disk %s": [ + "Formátovat disk %s" + ], + "Format partition as": [ + "Formátovat oddíl jako" + ], + "Format selected devices?": [ + "Formátovat vybraná zařízení?" + ], + "Format the whole device or mount an existing file system": [ + "Naformátovat celé zařízení nebo připojit stávající systém souborů" + ], + "Formatted": [ + "Formátován" + ], + "Formatting DASD devices": [ + "Formátuji zařízení DASD" + ], + "Full Disk Encryption (FDE) allows to protect the information stored at the new file systems, including data, programs, and system files.": [ + "Šifrování celého disku (FDE) umožňuje chránit informace uložené na nových souborových systémech, včetně dat, programů a systémových souborů." + ], + "Full name": [ + "Celé jméno" + ], + "Gateway": [ + "Brána" + ], + "Gateway can be defined only in 'Manual' mode": [ + "Bránu lze definovat pouze v režimu 'Ruční'" + ], + "GiB": [ + "GiB" + ], + "Go to network page": [ + "Přejít na stránku síť" + ], + "Go to storage page": [ + "Přejít na stránku úložiště" + ], + "Good signal": [ + "Dobrý signál" + ], + "Hide": [ + "Skrýt" + ], + "Hide %d subvolume action": [ + "Skrýt %d akci podsvazku", + "Skrýt %d akce podsvazku", + "Skrýt %d akcí podsvazku" + ], + "Hide details": [ + "Skrýt podrobnosti" + ], + "Hostname could not be updated": [ + "" + ], + "Hostname successfully updated": [ + "" + ], + "I have read and accept the [license] for %s": [ + "Přečetl jsem si a přijímám [licenci] pro %s" + ], + "IP Address": [ + "IP adresa" + ], + "IP Addresses": [ + "IP adresy" + ], + "IP address": [ + "adresa IP" + ], + "IP addresses": [ + "IP adresy" + ], + "IP settings": [ + "Nastavení IP adresy" + ], + "IPv4": [ + "IPv4" + ], + "IPv6": [ + "IPv6" + ], + "If a local media was used to run this installer, remove it before the next boot.": [ + "Bylo-li ke spuštění tohoto instalačního programu použito místní médium, před dalším spuštěním ho odstraňte." + ], + "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ + "Budete-li pokračovat, oddíly na pevném disku budou upraveny podle zadaných instalačních nastavení." + ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], + "In progress": [ + "Probíhá" + ], + "Incorrect IP address": [ + "Nesprávná IP adresa" + ], + "Incorrect password": [ + "Nesprávné heslo" + ], + "Incorrect port": [ + "Nesprávný port" + ], + "Incorrect user name": [ + "Nesprávné uživatelské jméno" + ], + "Initiator": [ + "Iniciátor" + ], + "Initiator name": [ + "Název iniciátora" + ], + "Initiator name could not be updated": [ + "Název iniciátora nemohl být aktualizován" + ], + "Initiator name successfully updated": [ + "Název iniciátora byl úspěšně aktualizován" + ], + "Install": [ + "Instalovat" + ], + "Install using an advanced configuration.": [ + "Nainstalovat pomocí pokročilé konfigurace." + ], + "Install using device %s and deleting all its content.": [ + "Instalace na zařízení %s a odstranění veškerého jeho obsahu" + ], + "Install using device %s shrinking existing partitions as needed.": [ + "Instalace na zařízení %s se zmenšením stávajících oddílů podle potřeby." + ], + "Install using device %s with a custom strategy to find the needed space.": [ + "Instalace na zařízení %s s vlastní strategií pro vyhledání potřebného místa" + ], + "Install using device %s without modifying existing partitions.": [ + "Instalace na zařízení %s bez úpravy stávajících oddílů" + ], + "Install using several devices and deleting all its content.": [ + "Instalace na několik zařízení s odstraněním veškerého obsahu" + ], + "Install using several devices shrinking existing partitions as needed.": [ + "Instalace na zařízení %s se zmenšením stávajících oddílů podle potřeby" + ], + "Install using several devices with a custom strategy to find the needed space.": [ + "Instalace na několik zařízení s vlastní strategií pro vyhledání potřebného místa" + ], + "Install using several devices without modifying existing partitions.": [ + "Instalace na několik zařízení bez úpravy stávajících oddílů." + ], + "Installation will take %s.": [ + "Instalace bude trvat %s." + ], + "Installed system may not have network connections": [ + "Nainstalovaný systém nemusí mít dostupné žádné síťové připojení" + ], + "Installing a broken package affects system stability and is a big security risk!": [ + "Instalace poškozeného balíčku ovlivňuje stabilitu systému a je to velký bezpečnostní risk!" + ], + "Installing the system, please wait...": [ + "Instaluji systém, čekejte ..." + ], + "Interface": [ + "Rozhraní" + ], + "Invalid storage settings": [ + "Neplatné nastavení úložiště" + ], + "Ip prefix or netmask": [ + "Předpona IP nebo maska sítě" + ], + "Issue date": [ + "Datum vydání" + ], + "Issuer": [ + "Vydavatel" + ], + "It doesn't exist or can't be reached.": [ + "Buď neexistuje nebo není dostupný." + ], + "It is chosen for booting": [ + "Je vybrán pro spuštění systému" + ], + "It is chosen for booting and for some LVM groups": [ + "Je vybrán pro spuštění systému a pro některé skupiny LVM" + ], + "It is chosen for booting and for the LVM group '%s'": [ + "Je vybrán pro spuštění systému a pro LVM skupinu '%s'" + ], + "It is chosen for some LVM groups": [ + "Je vybráno pro některé skupiny LVM" + ], + "It is chosen for the LVM group '%s'": [ + "Je vybrán pro LVM skupinu '%s'" + ], + "It is not possible to allocate space for %s.": [ + "Není možné vyhradit místo pro %s." + ], + "It is not possible to allocate space for the boot partition and for %s.": [ + "Není možné vyhradit místo pro spuštěcí oddíl a pro %s." + ], + "It is not possible to install the system with the current configuration. Adjust the settings below.": [ + "Systém nelze v současné konfiguraci nainstalovat. Upravte nastavení níže." + ], + "It is offline and must be activated before formatting it.": [ + "Je offline a musí být před formátováním aktivován." + ], + "It may take some time.": [ + "Chvíli to potrvá." + ], + "JFS": [ + "" + ], + "Keyboard": [ + "Klávesnice" + ], + "Keyboard layout": [ + "Rozložení klávesnice" + ], + "Keyboard selection": [ + "Výběr klávesnice" + ], + "KiB": [ + "KiB" + ], + "LUN": [ + "LUN" + ], + "Label": [ + "Štítek" + ], + "Language": [ + "Jazyk" + ], + "Language and keyboard": [ + "Jazyk a klávesnice" + ], + "Let the installer propose a sensible size": [ + "Nechat instalátor navrhnout vhodnout velikost" + ], + "Loading": [ + "Načítání..." + ], + "Loading data...": [ + "Načítání dat ..." + ], + "Loading the installation repositories...": [ + "Načítají se instalační repozitáře..." + ], + "Locale selection": [ + "Výběr lokality" + ], + "Localization": [ + "Lokalizace" + ], + "Log in": [ + "Přihlásit se" + ], + "Log in as %s": [ + "Přihlásit se jako %s" + ], + "Logical volume name": [ + "Jméno logického svazku" + ], + "Login": [ + "Přihlášení" + ], + "Login %s": [ + "Přihlášení %s" + ], + "Login form": [ + "Přihlašovací formulář" + ], + "Logout": [ + "Odhlášení" + ], + "MAC": [ + "MAC" + ], + "Main navigation": [ + "Hlavní navigace" + ], + "Make sure you provide the correct values": [ + "Ujistěte se, že jste zadali správné hodnoty" + ], + "Manual": [ + "Ruční" + ], + "MiB": [ + "MiB" + ], + "Mode": [ + "Režim" + ], + "Modify settings and physical volumes": [ + "Upravit nastavení a fyzické svazky" + ], + "More actions": [ + "Další nastavení" + ], + "More devices": [ + "Další zařízení" + ], + "More keymap layout might be available for the selected product at [Localization] page": [ + "Více voleb pro rozložení klávesnice pro vybraný produkt může být dostupných na stránce [Lokalizace]" + ], + "More language and keyboard layout options for the selected product may be available in [Localization] page.": [ + "Více jazyků a voleb pro rozložení klávesnice pro vybraný produkt může být dostupných na stránce [Lokalizace]." + ], + "More languages might be available for the selected product at [Localization] page": [ + "Více jazyků pro vybraný produkt může být dostupných na stránce [Lokalizace]" + ], + "Mount Point": [ + "Přípojný bod" + ], + "Mount RAID %s": [ + "Připojit RAID %s" + ], + "Mount disk %s": [ + "Připojit disk %s" + ], + "Mount point": [ + "Přípojný bod" + ], + "Move mount points": [ + "Přesunout přípojné body" + ], + "Move the mount points currently configured at the selected disks to logical volumes of this volume group.": [ + "Přesun přípojných bodů je v současnosti nastaven na vybrané disky do logických svazků této skupiny svazků." + ], + "Multipath": [ + "Vícecestný" + ], + "Multiple conflicts found. You can address them in any order, and resolving one may resolve others.": [ + "Bylo nalezeno několik konfliktů. Můžete je vyřešit v jakémkoliv pořadí a vyřešení jednoho může vyřešit i ostatní." + ], + "NILFS2": [ + "" + ], + "NTFS": [ + "" + ], + "Name": [ + "Název" + ], + "Network": [ + "Síť" + ], + "Network details": [ + "Detaily síťě" + ], + "Network not found or lost": [ + "Síť nebyla nalezena nebo se ztratila" + ], + "New": [ + "Nový" + ], + "No": [ + "Ne" + ], + "No Wi-Fi networks were found": [ + "Nebyly nalezeny žádné sítě Wi-Fi" + ], + "No additional software was selected.": [ + "Nebyl vybrán žádný další software." + ], + "No conflicts to address": [ + "Žádné konflikty k vyřešení" + ], + "No content found": [ + "Nebyl nalezen žádný obsah" + ], + "No device is currently using this connection.": [ + "V současnosti toto připojení nepoužívá žádné zařízení." + ], + "No device selected yet": [ + "Zatím nebylo vybráno žádné zařízení" + ], + "No iSCSI Boot Firmware Table (iBFT) found. The initiator can be configured manually.": [ + "Nebyla nalezena iSCSI spouštěcí firmwarová tabulka (iBFT). Iniciátor může být nakonfigurován ručně." + ], + "No iSCSI targets found.": [ + "Nebyly nalezeny žádné cíle iSCSI." + ], + "No partitions will be automatically configured for booting. Use with caution.": [ + "Žádné oddíly nebudou automaticky konfigurovány pro zavádění systému. Používejte opatrně." + ], + "No support is planned.": [ + "Podpora není naplánována." + ], + "No user defined yet.": [ + "Zatím není definován žádný uživatel." + ], + "No wired connections were found": [ + "Nebyla nalezena žádná kabelová připojení" + ], + "No zFCP controllers found.": [ + "Nebyly nalezeny žádné řadiče zFCP." + ], + "No zFCP disks found.": [ + "Nebyly nalezeny žádné disky zFCP." + ], + "None": [ + "Žádné" + ], + "None of the keymaps match the filter.": [ + "Žádná z map kláves neodpovídá filtru." + ], + "None of the locales match the filter.": [ + "Žádné umístění neodpovídá filtru." + ], + "None of the patterns match the filter.": [ + "Žádný ze vzorů neodpovídá filtru." + ], + "None of the time zones match the filter.": [ + "Žádné z časových pásem neodpovídá filtru." + ], + "None set": [ + "Nenastaveno" + ], + "Not available": [ + "Není dostupné" + ], + "Not implemented yet (%s)": [ + "Dosud nepodporováno (%s)" + ], + "Not possible with the current setup. Click to know more.": [ + "Není možné pokračovat se současným nastavením. Klikněte sem pro více informací." + ], + "Not protected network": [ + "Nezabezpečená síť" + ], + "Not selected yet": [ + "Dosud nevybráno" + ], + "Not supported (%s)": [ + "Není podporováno (%s)" + ], + "On boot": [ + "Při spuštění systému" + ], + "Only available if authentication by target is provided": [ + "K dispozici, jen když je zadáno ověřování cílem" + ], + "Options toggle": [ + "Přepínač možností" + ], + "Overview": [ + "Přehled" + ], + "Package installation failed": [ + "Instalace balíčku selhala" + ], + "Partition Info": [ + "Údaje o oddílech" + ], + "Partitions needed for booting will also be adapted": [ + "Oddíly potřebné pro spuštění systému se také přizpůsobí" + ], + "Partitions needed for booting will remain at %s": [ + "Oddíly potřebné pro spuštění systému zůstanou na %s" + ], + "Partitions that are not reused would be resized if needed.": [ + "" + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" + ], + "Partitions will be used and created for %s": [ + "" + ], + "Password": [ + "Heslo" + ], + "Password Required": [ + "Vyžadováno heslo" + ], + "Password confirmation": [ + "Potvrzení hesla" + ], + "Password input": [ + "Zadejte heslo" + ], + "Password is empty.": [ + "Heslo je prázdné." + ], + "Password visibility button": [ + "Tlačítko viditelnosti hesla" + ], + "Passwords do not match": [ + "Hesla se neshodují" + ], + "Pending": [ + "Čeká se na" + ], + "PiB": [ + "PiB" + ], + "Please, cancel and check the settings if you are unsure.": [ + "Nejste-li si jisti, zrušte akci a zkontrolujte nastavení." + ], + "Please, check whether it is running.": [ + "Zkontrolujte, zda je spuštěn." + ], + "Please, perform an iSCSI discovery in order to find available iSCSI targets.": [ + "Spusťte vyhledávání iSCSI a tím najděte dostupné cíle iSCSI." + ], + "Please, provide its password to log in to the system.": [ + "Zadejte heslo pro přihlášení do systému." + ], + "Please, try to activate a zFCP controller.": [ + "Zkuste aktivovat řadič zFCP." + ], + "Please, try to activate a zFCP disk.": [ + "Zkuste aktivovat disk zFCP." + ], + "Port": [ + "Port" + ], + "Portal": [ + "Portál" + ], + "Pre-installation checks": [ + "Kontrola před instalací" + ], + "Prefix length or netmask": [ + "Délka předpony nebo maska sítě" + ], + "Product is already registered": [ + "" + ], + "Provide email address": [ + "Zadejte emailovou adresu" + ], + "Provide registration code": [ + "Zadejte registrační kód" + ], + "Public SSH Key is empty.": [ + "" + ], + "Public network": [ + "Veřejná síť" + ], + "Question": [ + "Dotaz" + ], + "Read zFCP devices": [ + "Načtení zařízení zFCP" + ], + "Reboot": [ + "Restartovat systém" + ], + "Recommended": [ + "Doporučeno" + ], + "Register": [ + "Registrovat" + ], + "Register using SUSE server": [ + "Zaregistrovat pomocí serveru SUSE" + ], + "Register using a custom registration server": [ + "Zaregistrovat pomocí vlastního registračního serveru" + ], + "Registration": [ + "Registrace" + ], + "Registration certificate": [ + "Registrační certifikát" + ], + "Registration code": [ + "Registrační kód" + ], + "Registration server": [ + "Registrační server" + ], + "ReiserFS": [ + "" + ], + "Reload": [ + "Znovu načíst" + ], + "Reload now": [ + "Teď znovu načíst" + ], + "Reloading is required to get the latest data and avoid issues or data loss.": [ + "Je vyžadováno nové načtení pro získání nejnovějších dat a předejití chybám nebo ztrátě dat." + ], + "Remove": [ + "Odstranit" + ], + "Repository load failed": [ + "Selhalo načítání repozitáře" + ], + "Reset to defaults": [ + "Obnovit výchozí nastavení" + ], + "Resource not found or lost": [ + "Zdroj nenalezen nebo byl ztracen" + ], + "Result": [ + "Výsledek" + ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], + "Review and fix": [ + "Zkontrolovat a opravit" + ], + "Routes": [ + "Trasy" + ], + "Row actions": [ + "Akce pro řádek" + ], + "Row expansion": [ + "Rozšíření řádku" + ], + "Row selection": [ + "Výběr řádku" + ], + "SD Card": [ + "Karta SD" + ], + "SHA1 fingerprint": [ + "Otisk SHA1" + ], + "SHA256 fingerprint": [ + "Otisk SHA256" + ], + "SSID": [ + "SSID" + ], + "SUSE Customer Center (SCC)": [ + "Zákaznické centrum SUSE (SCC)" + ], + "Search": [ + "Hledat" + ], + "Secured network": [ + "Zabezpečená síť" + ], + "Security": [ + "Zabezpečení" + ], + "See more details": [ + "Zobrazit podrobnosti" + ], + "Select": [ + "Zvolit" + ], + "Select a device to define partitions or to mount": [ + "Vyberte zařízení pro definování oddílů nebo pro připojení" + ], + "Select a disk": [ + "Výběr disku" + ], + "Select a disk to define partitions or to mount": [ + "Vyberte disk pro definování oddílů nebo pro připojení" + ], + "Select a product": [ + "Vyberte produkt" + ], + "Select a solution to continue": [ + "Pro pokračování vyberte řešení" + ], + "Select another device to define partitions or to mount": [ + "Vyberte další zařízení pro definování oddílů nebo pro připojení" + ], + "Select another disk to define partitions or to mount": [ + "Vyberte další disk pro definování oddílů nebo pro připojení" + ], + "Select at least one disk.": [ + "Vyberte alespoň jeden disk." + ], + "Select or enter a mount point": [ + "Vyberte nebo zadejte přípojný bod" + ], + "Select or enter a mount point that is not already assigned to another device": [ + "Vyber nebo zadej bod připojení, který ještě není přiřazen jinému zařízení" + ], + "Select or enter a valid mount point": [ + "Vyber nebo zadej platný bod připojení" + ], + "Select what to do with each partition in order to find space for allocating the new system.": [ + "Vybrat pro každý oddíl co dělat, aby se podařilo najít místo pro vyhrazení novému systému." + ], + "Select what to do with each partition.": [ + "Vyberte, co se má s jednotlivými oddíly dělat." + ], + "Selected patterns": [ + "Vybrané vzory" + ], + "Server IP": [ + "IP adresa serveru" + ], + "Server URL": [ + "URL serveru" + ], + "Server options": [ + "Nastavení serveru" + ], + "Set a permanent hostname that won’t change with network updates.": [ + "" + ], + "Setting up connection": [ + "Nastavuji připojení" + ], + "Settings": [ + "Nastavení" + ], + "Show": [ + "Zobrazit" + ], + "Show %d subvolume action": [ + "Zobrazit %d akci podsvazku", + "Zobrazit %d akce podsvazku", + "Zobrazit %d akcí podsvazku" + ], + "Show information about %s": [ + "Zobrazit informace o %s" + ], + "Show less actions": [ + "Zobrazit méně akcí" + ], + "Show more actions": [ + "Zobrazit více akcí" + ], + "Shrink existing partitions": [ + "Zmenšit stávající oddíly" + ], + "Signal strength": [ + "Síla signálu" + ], + "Size": [ + "Velikost" + ], + "Size limits must be numbers followed by a unit like GiB or GB": [ + "Velikosti limitů musí být nějaká čísla následovaná jednotkou jako GiB nebo GB" + ], + "Size limits must be numbers optionally followed by a unit like GiB or GB": [ + "Limity velikosti musí být nějaká čísla, která mohou být následována jednotkou jako GiB nebo GB" + ], + "Skip to content": [ + "Přeskočit na obsah" + ], + "Skip to next": [ + "Přeskočit na další" + ], + "Skip to previous": [ + "Přeskočit na předchozí" + ], + "Software": [ + "Software" + ], + "Software %s": [ + "Software %s" + ], + "Software conflicts resolution": [ + "Řešení softwarových konfliktů" + ], + "Software selection": [ + "Výběr softwaru" + ], + "Some installation repositories could not be loaded. The system cannot be installed without them.": [ + "Některé instalační repozitáře nemohly být načteny. Systém bez nich nemůže být nainstalován." + ], + "Some of the elements in your AutoYaST profile are not supported.": [ + "Některé prvky ve vašem AutoYaST profilu nejsou podporovány." + ], + "Something went wrong": [ + "Něco se nezdařilo" + ], + "Start from scratch with the default configuration": [ + "Začít znovu s výchozí konfigurací" + ], + "Startup": [ + "Typ startu iSCSI" + ], + "Static hostname": [ + "" + ], + "Status": [ + "Stav" + ], + "Storage": [ + "Úložiště" + ], + "Suggested mount points": [ + "Navrhované přípojné body" + ], + "Swap": [ + "" + ], + "TPM sealing requires the new system to be booted directly.": [ + "Zapečetění čipem TPM vyžaduje přímé spuštění nového systému." + ], + "Target Password": [ + "Cílové heslo" + ], + "Targets": [ + "Cíle" + ], + "The LVM group '%1$s' will remain at %2$s": [ + "LVM skupina '%1$s' zůstane na %2$s" + ], + "The configuration has been updated externally.": [ + "Konfigurace byla externě aktualizována." + ], + "The configuration must be adapted to address the following issue:": [ + "Před zahájením instalace vyřešte tento problém:", + "Před zahájením instalace vyřešte tyto problémy:", + "Před zahájením instalace vyřešte tyto problémy:" + ], + "The configured LVM groups will remain at %s": [ + "Nakonfigurované LVM skupiny na %s zůstanou" + ], + "The connection can be used by any available device.": [ + "Připojení může být použito kterýmkoliv dostupným zařízením." + ], + "The connection will be used only during installation and not available in the installed system.": [ + "Připojení bude použito pouze během instalace a nebude dostupné v nainstalovaném systému." + ], + "The content may be deleted": [ + "Obsah může být smazán" + ], + "The current configuration will result in an attempt to create a %1$s of %2$s.": [ + "Současná konfigurace povede k pokusu vytvořit %1$s o velikosti %2$s." + ], + "The current configuration will result in an attempt to create a %1$s of at least %2$s.": [ + "Současná konfigurace povede k pokusu vytvořit %1$s o velikosti alespoň %2$s." + ], + "The current configuration will result in an attempt to create a %1$s with a size between %2$s and %3$s.": [ + "Současná konfigurace povede k pokusu vytvořit %1$s o velikosti mezi %2$s a %3$s." + ], + "The current file system will be mounted at %s": [ + "Aktuální souborový systém bude připojen na %s" + ], + "The current storage configuration has the following issue:": [ + "", + "", + "" + ], + "The data is kept, but the current partitions will be resized as needed.": [ + "Data zůstanou zachována, ale velikost aktuálních oddílů se podle potřeby změní." + ], + "The data is kept. Only the space not assigned to any partition will be used.": [ + "Data jsou uchována. Využije se pouze prostor, který není přiřazen žádnému oddílu." + ], + "The device cannot be shrunk:": [ + "Zařízení nelze zmenšit:" + ], + "The device will be formatted": [ + "Zařízení bude formátováno" + ], + "The device will be formatted as %1$s and mounted at %2$s": [ + "Zařízení bude formátováno jako %1$s a připojeno na %2$s" + ], + "The device will be mounted": [ + "Zařízení bude připojeno" + ], + "The disk is used for LVM": [ + "Tento disk se používá pro LVM" + ], + "The disk is used for LVM and boot": [ + "Tento disk se používá pro LVM a spuštění systému" + ], + "The disk is used for booting": [ + "Tento disk se používá pro spuštění systému" + ], + "The encryption password did not work": [ + "Zadané šifrovací heslo nefungovalo" + ], + "The extension has been registered with key %s.": [ + "Rozšíření bylo zaregistrováno pomocí klíče %s." + ], + "The extension was registered without any registration code.": [ + "Rozšíření bylo zaregistrováno bez jakéhokoliv registračního kódu." + ], + "The final size can be bigger in order to fill the extra free space.": [ + "Konečná velikost může být větší, aby se zaplnilo zbývající volné místo." + ], + "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ + "Poslední krok konfigurace modulu TPM (Trusted Platform Module) pro automatické otevírání šifrovaných zařízení se provede při prvním spuštění nového systému. Aby to fungovalo, musí se počítač spustit přímo novým zavaděčem." + ], + "The following partitions will be created or mounted": [ + "Následující oddíly budou vytvořeny nebo připojeny" + ], + "The following software patterns are selected for installation:": [ + "Pro instalaci jsou vybrány tyto softwarové vzory:" + ], + "The installation on your machine is complete.": [ + "Instalace na váš počítač je dokončena." + ], + "The installation will take": [ + "Instalace zabere" + ], + "The installation will take %s including:": [ + "Instalace bude trvat %s včetně:" + ], + "The installer interface is no longer available, so you can safely close this window.": [ + "Instalátor už není dostupný, můžete bezpečně zavřít toto okno." + ], + "The installer requires [root] user privileges.": [ + "Instalátor vyžaduje oprávnění uživatele [root]." + ], + "The maximum must be a number followed by a unit like GiB or GB": [ + "Maximum musí být nějaké číslo následované jednotkou jako GiB nebo GB" + ], + "The maximum must be a number optionally followed by a unit like GiB or GB": [ + "Maximum musí být nějaké číslo, které může následovat jednotka jako GiB nebo GB" + ], + "The minimum cannot be greater than the maximum": [ + "Minimum nemůže být větší než maximum" + ], + "The minimum must be a number followed by a unit like GiB or GB": [ + "Minimum musí být nějaké číslo následované jednotkou jako GiB nebo GB" + ], + "The minimum must be a number optionally followed by a unit like GiB or GB": [ + "Minimum musí být nějaké číslo, které může následovat jednotka jako GiB nebo GB" + ], + "The modal selector offers a simplified interface designed for quick and straightforward use, without overwhelming the user.": [ + "Modální výběr nabízí zjednodušené rozhraní navržené pro rychlé a přímočaré použití, aniž by byl uživatel zahlcen." + ], + "The needed LVM physical volumes will be added as partitions on the chosen disks, based on the sizes of the logical volumes. If you select more than one disk, the physical volumes may be distributed along several disks.": [ + "Požadované fyzické LVM svazky budou přidány jako oddíly vybraných disku, na základě velikosti logických svazků. Pokud vyberete více než jeden disk, fyzické svazky mohou být rozloženy mezi několik disků." + ], + "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ + "Dokáže-li čip TPM ověřit integritu systému, nebude heslo pro spuštění systému a přístup k datům potřebné. Zapečetění TPM vyžaduje, aby byl nový systém spuštěn hned při prvním použití." + ], + "The product will be registered with \"%s\" hostname": [ + "" + ], + "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ + "Velikost %1$s bude dynamicky upravena na základě množství paměti RAM v systému a přítomnosti zvláštního souborového systému pro %2$s." + ], + "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of separate file systems for %2$s.": [ + "Velikost %1$s bude dynamicky upravena na základě množství paměti RAM v systému a přítomnosti zvláštních souborových systémů pro %2$s." + ], + "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system, the usage of Btrfs snapshots and the presence of a separate file system for %2$s.": [ + "Velikost %1$s bude dynamicky upravena na základě množství paměti RAM v systému, použití snímků Btrfs a přítomnosti zvláštního souborového systému pro %2$s." + ], + "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system, the usage of Btrfs snapshots and the presence of separate file systems for %2$s.": [ + "Velikost %1$s bude dynamicky upravena na základě množství paměti RAM v systému, použití snímků Btrfs a přítomnosti zvláštních souborových systémů pro %2$s." + ], + "The size for %1$s will be dynamically adjusted based on the presence of a separate file system for %2$s.": [ + "Velikost %1$s bude dynamicky upravena na základě přítomnosti zvláštního souborového systému pro %2$s." + ], + "The size for %1$s will be dynamically adjusted based on the presence of separate file systems for %2$s.": [ + "Velikost %1$s bude dynamicky upravena na základě přítomnosti zvláštních souborových systémů pro %2$s." + ], + "The size for %1$s will be dynamically adjusted based on the usage of Btrfs snapshots and the presence of a separate file system for %2$s.": [ + "Velikost %1$s bude dynamicky upravena na základě použití snímků Btrfs a přítomnosti zvláštního souborového systému pro %2$s." + ], + "The size for %1$s will be dynamically adjusted based on the usage of Btrfs snapshots and the presence of separate file systems for %2$s.": [ + "Velikost %1$s bude dynamicky upravena na základě použití snímků Btrfs a přítomnosti zvláštních souborových systémů pro %2$s." + ], + "The size for %s will be dynamically adjusted based on the amount of RAM in the system and the usage of Btrfs snapshots.": [ + "Velikost %s bude dynamicky upravena na základě množství paměti RAM v systému a použití snímků Btrfs." + ], + "The size for %s will be dynamically adjusted based on the usage of Btrfs snapshots.": [ + "Velikost %s bude dynamicky upravena na základě použití snímků Btrfs." + ], + "The size is configured as a range between %s and %s, but this interface cannot handle ranges with a given max size.": [ + "Velikost je nakonfigurovaná jako rozsah mezi %s a %s, ale toto rozhraní nemůže zpracovat rozsah s danou maximální velikostí." + ], + "The size must be a number followed by a unit of the form GiB (power of 2) or GB (power of 10).": [ + "Velikost musí být číslo následované jednotkou ve formátu GiB (mocnina 2) nebo GB (mocnina 10)." + ], + "The storage configuration is valid (see result below) but uses elements not supported by this interface.": [ + "Konfigurace úložiště je platná (viz výsledek níže), ale používá prvky, které nejsou tímto rozhraním podporovány." + ], + "The storage configuration uses elements not supported by this interface.": [ + "Konfigurace úložiště používá prvky, které nejsou tímto rozhraním podporovány." + ], + "The system does not support Wi-Fi connections, probably because of missing or disabled hardware.": [ + "Systém nepodporuje připojení Wi-Fi, pravděpodobně chybí hardware nebo je zakázán." + ], + "The system will use %s as its default language.": [ + "Systém použije jako výchozí jazyk %s." + ], + "The zFCP disk was not activated.": [ + "Disk zFCP nebyl aktivován." + ], + "There are no disks available for the installation.": [ + "Pro instalaci nejsou k dispozici žádné disky." + ], + "There are not disks available for the installation. You may need to configure some device.": [ + "Pro instalaci nesou dostupné žádné disky. Možná bude potřeba nakonfigurovat nějaká zařízení." + ], + "There is %d destructive action planned affecting %s": [ + "", + "", + "" + ], + "These are the most relevant installation settings. Feel free to browse the sections in the menu for further details.": [ + "Toto je nejdůležitější nastavení instalace. Další podrobnosti najdete v sekcích v nabídce." + ], + "These are the settings for the product to install. The installer language and keyboard layout can be adjusted via the [settings panel] accessible from the top bar.": [ + "Toto jsou nastavení pro instalaci produktu. Jazyk instalátoru a rozložení klávesnice můžete upravit v [panelu nastavení] dostupném v horní liště." + ], + "These are the settings for the product to install. The installer language can be adjusted via the [settings panel] accessible from the top bar.": [ + "Toto jsou nastavení pro instalaci produktu. Jazyk instalátoru můžete upravit v [panelu nastavení] dostupném v horní liště." + ], + "This extension is not available on the server. Ask the server administrator to mirror the extension.": [ + "Toto rozšíření není na tomto serveru dostupné. Požádejte správce serveru, aby provedl zrcadlení tohoto rozšíření." + ], + "This hostname is dynamic and may change after a reboot or network update, as configured by the local network administrator.": [ + "" + ], + "This license is not available in %s.": [ + "V %s není tato licence dostupná." + ], + "This may take a moment while updates complete.": [ + "Než budou aktualizace dokončeny, může to chvilku zabrat." + ], + "This message will close automatically when everything is done.": [ + "Tato zpráva bude automaticky uzavřena jakmile bude vše hotovo." + ], + "This pattern strikes a balance between clarity and efficiency: the modal keeps things lightweight for simple selections, while the full view supports deeper exploration and more complex actions, specially for users with tons of devices.": [ + "Tento vzor balancuje mezi jasností a efektivitou: modál ponechává věci odlehčené pro jednoduché volby, zatímco plné zobrazení umožňuje hlubší průzkum a mnohem komplexnější akce. To zvláště ocení uživatelé s velkým množstvím zařízení." + ], + "This product does not allow to select software patterns during installation. However, you can add additional software once the installation is finished.": [ + "Tento produkt neumožňuje výběr softwarových vzorů během instalace. Po dokončení instalace však můžete přidat další software." + ], + "This space includes the base system and the selected software patterns, if any.": [ + "Tento prostor zahrnuje základní systém a vybrané softwarové vzory, pokud existují." + ], + "This will affect only the installer interface, not the product to be installed. You can adjust the product’s localization later in the Localization settings page.": [ + "Toto ovlivní pouze rozhraní instalátoru, nikoliv produkt, který bude nainstalován. Lokalizaci produktu můžete upravit později na stránce nastavení lokalizace." + ], + "TiB": [ + "TiB" + ], + "Time zone": [ + "Časové pásmo" + ], + "Tmpfs": [ + "" + ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "Aby bylo možné nový systém spustit, může být nutné, aby instalační program vytvořil nebo nakonfiguroval některé oddíly na příslušném disku." + ], + "Transactional root file system": [ + "Transakční kořenový souborový systém" + ], + "Try again": [ + "Zkusit znovu" + ], + "Type": [ + "Typ" + ], + "URL": [ + "Adresa URL" + ], + "Unable to modify the settings": [ + "Není možné upravit nastavení" + ], + "Unbound": [ + "Nenavázané" + ], + "Unselect": [ + "Zrušit výběr" + ], + "Unselect or activate them and try it again.": [ + "Zrušte jejich označení nebo je aktivujte a zkuste to znovu." + ], + "Unsupported AutoYaST elements": [ + "Nepodporované prvky AutoYaSTu" + ], + "Unused space": [ + "Nevyužitý prostor" + ], + "Up to %s can be recovered by shrinking the device.": [ + "Zmenšením zařízení lze obnovit až %s." + ], + "Update available disks and activate crypt devices": [ + "Aktualizovat dostupné disky a aktivovat šifrovaná zařízení" + ], + "Updating the hostname now or later will not change the currently registered hostname.": [ + "" + ], + "Upload": [ + "Nahrát" + ], + "Upload, paste, or drop an SSH public key": [ + "Nahrání, vložení nebo přetažení veřejného klíče SSH" + ], + "Use RAID %s": [ + "Použít RAID %s" + ], + "Use RAID %s to host LVM": [ + "Použít RAID %s pro zavedení LVM" + ], + "Use RAID %s to host LVM and boot": [ + "Použít RAID %s pro zavedení LVM a spuštění" + ], + "Use RAID %s to install": [ + "Použít RAID %s pro instalaci" + ], + "Use RAID %s to install and boot": [ + "Použít RAID %s k instalaci a spuštění systému" + ], + "Use RAID %s to install and host LVM": [ + "Použít RAID %s pro instalaci a zavedení LVM" + ], + "Use RAID %s to install, host LVM and boot": [ + "Použít RAID %s pro instalaci, zavedení LVM a spuštění" + ], + "Use actions below to set up your devices or click %s to start from scratch with the default configuration.": [ + "Použijte akce níže pro nastavení vašich zařízení nebo klikněte na %s pro vytvoření od znova s výchozí konfigurací." + ], + "Use available space": [ + "Využít dostupný prostor" + ], + "Use disk %s": [ + "Použít disk %s" + ], + "Use disk %s to host LVM": [ + "Použij disk %s pro zavedení LVM" + ], + "Use disk %s to host LVM and boot": [ + "Použij disk %s pro zavedení LVM a spuštění" + ], + "Use disk %s to install": [ + "Použij disk %s k instalaci" + ], + "Use disk %s to install, host LVM and boot": [ + "Použij disk %s pro instalaci, zavedení LVM a spuštění" + ], + "Use for installation only": [ + "Použít pouze během instalace" + ], + "Use for the selected product too": [ + "Použít také pro vybraný produkt" + ], + "Use static hostname": [ + "" + ], + "Use suggested username": [ + "Použijte navrhované uživatelské jméno" + ], + "Use the Trusted Platform Module (TPM) to decrypt automatically on each boot": [ + "Použití modulu TPM (Trusted Platform Module) k automatickému dešifrování při každém spuštění systému" + ], + "Use these same settings for the selected product": [ + "Použít stejné nastavení pro vybraný produkt" + ], + "Used space": [ + "Využitý prostor" + ], + "User name": [ + "Uživatelské jméno" + ], + "Username": [ + "Uživatelské jméno" + ], + "Username suggestion dropdown": [ + "Rozbalovací nabídka uživatelských jmen" + ], + "Using [%s] keyboard": [ + "Používá se klávesnice [%s]" + ], + "Using a hashed password.": [ + "" + ], + "Volume group '%s' already exists. Enter a different name.": [ + "Skupina svazků ‘%s’ již existuje. Zadejte jiný název." + ], + "WPA & WPA2 Personal": [ + "WPA & WPA2 Osobní" + ], + "WPA Password": [ + "Heslo WPA" + ], + "WWPN": [ + "WWPN" + ], + "Waiting for a mount point": [ + "Čekám na přípojný bod" + ], + "Waiting for information about storage configuration": [ + "Čekání na informace o konfiguraci úložiště" + ], + "Weak signal": [ + "Slabý signál" + ], + "Wi-Fi connection form": [ + "Formulář pro připojení WiFi" + ], + "Wi-Fi networks": [ + "Wi-Fi sítě" + ], + "Wi-Fi not supported": [ + "Wi-Fi není podporováno" + ], + "Will be supported in a future version.": [ + "Bude podporováno v budoucí verzi." + ], + "Wired connections": [ + "Drátová připojení" + ], + "XFS": [ + "" + ], + "Yes": [ + "Ano" + ], + "You can proceed to install with the current settings or you may want to discard the configuration and start from scratch with a simple one.": [ + "Můžete pokračovat s instalací za použití současného nastavení nebo můžete konfiguraci skartovat a začít od začátku s jednodušším návrhem." + ], + "You cannot change it later. Go to the %s section if you want to modify it before proceeding with registration.": [ + "Toto není možné později změnit. Pokud chcete ještě něco upravit, přejděte před pokračováním v registraci do oddílu %s." + ], + "You may want to discard the current settings and start from scratch with a simple configuration.": [ + "Možná budete chtít zahodit toto nastavení a začít od znova s jednoduchou konfigurací." + ], + "You may want to discard those settings and start from scratch with a simple configuration.": [ + "Možná budete chtít zahodit toto nastavení a začít od znova s jednoduchou konfigurací." + ], + "You will connect to a public network without encryption. Your data may not be secure.": [ + "Připojíte se do veřejné nešifrované sítě. Vaše data nemusí být v bezpečí." + ], + "Your system is rebooting": [ + "Váš systém se nyní restartuje" + ], + "ZFCP": [ + "ZFCP" + ], + "[CAPS LOCK] is on": [ + "[CAPS LOCK] je zapnutý" + ], + "[FIXME]": [ + "[OPRAV MĚ]" + ], + "approx. %s": [ + "zhruba %s" + ], + "at least %s": [ + "alespoň %s" + ], + "auto selected": [ + "automaticky vybráno" + ], + "hostname": [ + "jméno počítače" + ], + "iBFT": [ + "iBFT" + ], + "iSCSI": [ + "iSCSI" + ], + "logical volume": [ + "logický svazek" + ], + "no": [ + "ne" + ], + "offline": [ + "offline" + ], + "partition": [ + "oddíl" + ], + "read_only": [ + "pouze_čtení" + ], + "reset to defaults": [ + "Obnovit výchozí nastavení" + ], + "zFCP": [ + "zFCP" + ], + "zFCP Disk Activation": [ + "Aktivace disku zFCP" + ], + "zFCP Disk activation form": [ + "Aktivační formulář zFCP disku" + ] +}; diff --git a/web/src/po/po.de.js b/web/src/po/po.de.js index 2560154bfe..2f13cff86e 100644 --- a/web/src/po/po.de.js +++ b/web/src/po/po.de.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Zeitzonenauswahl" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -139,9 +145,6 @@ export default { "Add another address": [ "Weitere Adresse hinzufügen" ], - "Add another partition or mount an existing one": [ - "Eine weitere Partition hinzufügen oder eine vorhandene Partition einhängen" - ], "Add device menu": [ "Gerätemenü hinzufügen" ], @@ -327,9 +330,6 @@ export default { "Change Language": [ "Sprache ändern" ], - "Change boot options": [ - "Boot-Optionen ändern" - ], "Change device menu": [ "Gerätemenü ändern" ], @@ -357,12 +357,12 @@ export default { "Change the file system or mount point": [ "Dateisystem oder Einhängepunkt ändern" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "Kanalkennung" ], - "Check the %d planned actions": [ - "%d geplante Aktionen prüfen" - ], "Check the authentication parameters.": [ "Überprüfen Sie die Authentifizierungsparameter." ], @@ -396,9 +396,6 @@ export default { "Close": [ "Schließen" ], - "Collapse the list of planned actions": [ - "Liste der geplanten Aktionen einklappen" - ], "Configuration out of sync": [ "Konfiguration nicht synchronisiert" ], @@ -609,9 +606,6 @@ export default { "Details": [ "Details" ], - "Details for %s": [ - "Details für %s" - ], "Details will appear after the connection is successfully established.": [ "Nachdem die Verbindung erfolgreich hergestellt wurde, werden Details angezeigt." ], @@ -666,9 +660,6 @@ export default { "Download logs": [ "Protokolle herunterladen" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Während der Installation werden mehrere Aktionen durchgeführt, um die in der Tabelle unten dargestellte Anordnung einzurichten." - ], "Edit": [ "Bearbeiten" ], @@ -732,8 +723,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Beispiel: https://myserver.com" + "Example: %s": [ + "Beispiel: %s" ], "Excellent signal": [ "Ausgezeichnetes Signal" @@ -791,8 +782,8 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Nach Gebiet, Zeitzonencode oder UTC-Abweichung filtern" ], - "Find space": [ - "Speicherplatz ausfindig machen" + "Final layout": [ + "Endgültige Anordnung" ], "Find space in %s": [ "Speicherplatz in %s finden" @@ -918,6 +909,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Wenn Sie fortfahren, werden die Partitionen auf Ihrer Festplatte entsprechend den vorgegebenen Installationseinstellungen geändert." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "In Bearbeitung" ], @@ -978,9 +972,6 @@ export default { "Install using several devices without modifying existing partitions.": [ "Installieren unter Verwendung mehrerer Geräte ohne Änderung der vorhandenen Partitionen." ], - "Installation Devices": [ - "Installationsgeräte" - ], "Installation will take %s.": [ "Installation wird %s in Anspruch nehmen." ], @@ -1346,12 +1337,6 @@ export default { "Options toggle": [ "Optionen umschalten" ], - "Other options": [ - "Andere Optionen" - ], - "Other options toggle": [ - "Umschalter für andere Optionen" - ], "Overview": [ "Übersicht" ], @@ -1361,6 +1346,9 @@ export default { "Partition Info": [ "Partitionierungsinformationen" ], + "Partitions": [ + "Partitionen" + ], "Partitions needed for booting will also be adapted": [ "Zum Booten benötigte Partitionen werden ebenfalls angepasst" ], @@ -1376,14 +1364,11 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Die Größe von Partitionen, die nicht wiederverwendet werden, wird bei Bedarf angepasst." ], - "Partitions to boot will be allocated at the following device.": [ - "Die zu bootenden Partitionen werden auf dem folgenden Gerät zugewiesen." - ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Die zu bootenden Partitionen werden auf der Installationsfestplatte %s zugewiesen." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], - "Partitions to boot will be allocated at the installation disk.": [ - "Die zu bootenden Partitionen werden auf der Installationsfestplatte zugewiesen." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], "Partitions will be used and created for %s": [ "Partitionen werden für %s verwendet und erstellt" @@ -1448,9 +1433,6 @@ export default { "Product is already registered": [ "Produkt ist bereits registriert" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Schutz für die in den neuen Dateisystemen gespeicherten Informationen, einschließlich Daten, Programme und Systemdateien." - ], "Provide email address": [ "E-Mail-Adresse angeben" ], @@ -1538,6 +1520,9 @@ export default { "Result": [ "Ergebnis" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "Wiederverwendete Partitionen werden nicht verkleinert" ], @@ -1598,21 +1583,9 @@ export default { "Select a disk": [ "Festplatte auswählen" ], - "Select a disk to configure": [ - "Festplatte zum Konfigurieren auswählen" - ], - "Select a disk to create %s": [ - "Festplatte zum Erstellen von %s auswählen" - ], "Select a disk to define partitions or to mount": [ "Wählen Sie eine Festplatte aus, um Partitionen zu definieren oder einzuhängen" ], - "Select a disk to format as %s": [ - "Festplatte zum Formatieren als %s auswählen" - ], - "Select a disk to install the system": [ - "Festplatte für die Installation des Systems auswählen" - ], "Select a product": [ "Wählen Sie ein Produkt aus" ], @@ -1640,9 +1613,6 @@ export default { "Select or enter a valid mount point": [ "Gültigen Einhängepunkt auswählen oder eingeben" ], - "Select the disk to configure partitions for booting": [ - "Festplatte zum Konfigurieren von Partitionen für das Booten auswählen" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Wählen Sie aus, was mit jeder Partition geschehen soll, um Platz für das neue System zu finden." ], @@ -1947,6 +1917,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "Das Passwort wird nicht benötigt, um zu booten und auf die Daten zuzugreifen, wenn das TPM die Integrität des Systems verifizieren kann. Die TPM-Versiegelung erfordert, dass das neue System bei seinem ersten Start direkt gebootet wird." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "Die Größe für %1$s wird dynamisch angepasst, basierend auf der Menge an RAM im System und dem Vorhandensein eines separaten Dateisystems für %2$s." ], diff --git a/web/src/po/po.es.js b/web/src/po/po.es.js index c4aa870be0..d87c489d40 100644 --- a/web/src/po/po.es.js +++ b/web/src/po/po.es.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " · Selección de zona horaria" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -139,9 +145,6 @@ export default { "Add another address": [ "Añadir otras direcciones" ], - "Add another partition or mount an existing one": [ - "Añada otra partición o monte una existente" - ], "Add device menu": [ "Añadir menú de dispositivo" ], @@ -327,9 +330,6 @@ export default { "Change Language": [ "Cambiar idioma" ], - "Change boot options": [ - "Cambiar opciones de arranque" - ], "Change device menu": [ "Cambiar el menú del dispositivos" ], @@ -357,12 +357,12 @@ export default { "Change the file system or mount point": [ "Cambiar el sistema de archivos o el punto de montaje" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "ID de canal" ], - "Check the %d planned actions": [ - "Revise las %d acciones planificadas" - ], "Check the authentication parameters.": [ "Verifique los parámetros de autenticación." ], @@ -396,9 +396,6 @@ export default { "Close": [ "Cerrar" ], - "Collapse the list of planned actions": [ - "Contraer la lista de acciones planificadas" - ], "Configuration out of sync": [ "Configuración desincronizada" ], @@ -609,9 +606,6 @@ export default { "Details": [ "Detalles" ], - "Details for %s": [ - "Detalles de %s" - ], "Details will appear after the connection is successfully established.": [ "Los detalles aparecerán después de que la conexión se haya establecido con éxito." ], @@ -666,9 +660,6 @@ export default { "Download logs": [ "Descargar registros" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Durante la instalación, se realizarán varias acciones para establecer la estructura de particiones que se muestra en la siguiente tabla." - ], "Edit": [ "Editar" ], @@ -732,8 +723,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Ejemplo: https://miservidor.com" + "Example: %s": [ + "Ejemplo: %s" ], "Excellent signal": [ "Señal excelente" @@ -791,8 +782,8 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Filtrar por territorio, código de zona horaria o compensación UTC" ], - "Find space": [ - "Buscar espacio" + "Final layout": [ + "Diseño final" ], "Find space in %s": [ "Encontrar espacio en %s" @@ -918,6 +909,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Si continúa, las particiones del disco duro se modificarán de acuerdo con la configuración de instalación proporcionada." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "En curso" ], @@ -978,9 +972,6 @@ export default { "Install using several devices without modifying existing partitions.": [ "Instalar utilizando varios dispositivos sin modificar las particiones existentes." ], - "Installation Devices": [ - "Dispositivos de instalación" - ], "Installation will take %s.": [ "La instalación utilizará %s." ], @@ -1346,12 +1337,6 @@ export default { "Options toggle": [ "Conmutador de opciones" ], - "Other options": [ - "Otras opciones" - ], - "Other options toggle": [ - "Mostrar/ocultar otras opciones" - ], "Overview": [ "Vista general" ], @@ -1361,6 +1346,9 @@ export default { "Partition Info": [ "Información de la partición" ], + "Partitions": [ + "Particiones" + ], "Partitions needed for booting will also be adapted": [ "Las particiones necesarias para el arranque también se adaptarán" ], @@ -1376,14 +1364,11 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Las particiones que no se reutilizan se redimensionarían si fuese necesario." ], - "Partitions to boot will be allocated at the following device.": [ - "Las particiones de arranque se asignarán en el siguiente dispositivo." - ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Las particiones de arranque se asignarán en el disco de instalación %s." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], - "Partitions to boot will be allocated at the installation disk.": [ - "Las particiones para arrancar se asignarán en el disco de instalación." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], "Partitions will be used and created for %s": [ "Las particiones se utilizarán y crearán para %s" @@ -1448,9 +1433,6 @@ export default { "Product is already registered": [ "El producto ya está registrado" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Protección de la información almacenada en los nuevos sistemas de archivo, incluyendo datos, programas y archivos del sistema." - ], "Provide email address": [ "Proporcione una dirección de correo electrónico" ], @@ -1538,6 +1520,9 @@ export default { "Result": [ "Resultado" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "Las particiones reutilizadas no se reducirán" ], @@ -1598,21 +1583,9 @@ export default { "Select a disk": [ "Seleccione un disco" ], - "Select a disk to configure": [ - "Seleccione un disco para configurarlo" - ], - "Select a disk to create %s": [ - "Seleccione un disco para crear %s" - ], "Select a disk to define partitions or to mount": [ "Seleccione un disco para definir particiones o para montarlo" ], - "Select a disk to format as %s": [ - "Seleccione un disco para formatear como %s" - ], - "Select a disk to install the system": [ - "Seleccione un disco para instalar el sistema" - ], "Select a product": [ "Seleccione un producto" ], @@ -1640,9 +1613,6 @@ export default { "Select or enter a valid mount point": [ "Seleccione o introduzca un punto de montaje válido" ], - "Select the disk to configure partitions for booting": [ - "Seleccione el disco para configurar particiones de arranque" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Selecciona lo que quiere hacer con cada partición con el fin de encontrar espacio para asignar el sistema nuevo." ], @@ -1947,6 +1917,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "La contraseña no será necesaria para arrancar y acceder a los datos si TPM puede verificar la integridad del sistema. El sellado TPM requiere que el nuevo sistema se arranque directamente en su primera ejecución." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "El tamaño para %1$s se ajustará dinámicamente según el total de RAM del sistema y la presencia de un sistema de archivos independiente para %2$s." ], diff --git a/web/src/po/po.fi.js b/web/src/po/po.fi.js index be7c496910..03b999626e 100644 --- a/web/src/po/po.fi.js +++ b/web/src/po/po.fi.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Aikavyöhykkeen valinta" ], + "\"%s\"": [ + "\"%s\"" + ], + "\"%s\" does not exist or is no longer available.": [ + "”%s” ei ole enää olemassa tai saatavilla." + ], "%1$s (%2$s)": [ "%1$s (koko %2$s)" ], @@ -139,9 +145,6 @@ export default { "Add another address": [ "Lisää toinen osoite" ], - "Add another partition or mount an existing one": [ - "Lisää ylimääräinen osio tai liitä olemassa oleva" - ], "Add device menu": [ "Lisää laitevalikko" ], @@ -229,13 +232,13 @@ export default { "Tunnistautuminen" ], "Authentication by initiator": [ - "" + "Alullepanijan mukaan tunnistautuminen" ], "Authentication by target": [ - "" + "Kohteen mukaan tunnistautuminen" ], "Auto LUNs Scan": [ - "" + "Automaattinen LUN-skannaus" ], "Automatic": [ "Automaattinen" @@ -244,10 +247,10 @@ export default { "Automaattinen (DHCP)" ], "Automatic LUN scan is [disabled]. LUNs have to be manually configured after activating a controller.": [ - "" + "Automaattinen LUN-skannaus on [pois käytöstä]. LUNien asetukset tulee määrittää käsin ohjaimen aktivoinnin jälkeen." ], "Automatic LUN scan is [enabled]. Activating a controller which is running in NPIV mode will automatically configures all its LUNs.": [ - "" + "Automaattinen LUN-skannaus on [käytössä]. NPIV-tilassa toimivan ohjaimen aktivoiminen määrittää automaattisesti kaikkien LUNien asetukset." ], "Available products": [ "Saatavilla olevat tuotteet" @@ -327,9 +330,6 @@ export default { "Change Language": [ "Vaihda kieltä" ], - "Change boot options": [ - "Muuta käynnistysvalintoja" - ], "Change device menu": [ "Laitteen valintavalikko" ], @@ -354,15 +354,27 @@ export default { "Change selection": [ "Muuta valintoja" ], + "Change the disk to configure": [ + "Valitse levy jolle tehdään asetukset" + ], + "Change the disk to create %s": [ + "Valitse levy jolle luodaan \"%s\"" + ], + "Change the disk to format as %s": [ + "Valitse levy joka alustetaan liitoskohtaan ”%s”" + ], + "Change the disk to install the system": [ + "Valitse levy jolle järjestelmän asennus tehdään" + ], "Change the file system or mount point": [ "Vaihda tiedostojärjestelmää tai liitoskohtaa" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "Kanavatunniste" ], - "Check the %d planned actions": [ - "Tarkista %d suunniteltua toimintoa" - ], "Check the authentication parameters.": [ "Tarkista tunnistautumisasetukset." ], @@ -396,14 +408,11 @@ export default { "Close": [ "Sulje" ], - "Collapse the list of planned actions": [ - "Supista suunniteltujen toimintojen luettelo" - ], "Configuration out of sync": [ "Asetukset eivät ajan tasalla" ], "Configuration read from the iSCSI Boot Firmware Table (iBFT).": [ - "" + "Asetukset luettu kohteesta iSCSI Boot Firmware Table (iBFT)." ], "Configuration unreachable or invalid": [ "Asetuksia ei voida ladata tai ne eivät ole kelvollisia" @@ -502,7 +511,7 @@ export default { "Jatkaminen asentamatta pakettia voi johtaa rikkinäiseen järjestelmään. Joissain tapauksissa järjestelmä ei välttämättä edes käynnisty." ], "Controllers": [ - "" + "Ohjaimet" ], "Could not authenticate against the server, please check it.": [ "Palvelimelle ei voitu tunnistautua, ole hyvä ja tarkista." @@ -609,9 +618,6 @@ export default { "Details": [ "Tiedot" ], - "Details for %s": [ - "Tiedot kohteelle %s" - ], "Details will appear after the connection is successfully established.": [ "Kun yhteys on muodostettu, näet lisätietoja." ], @@ -637,13 +643,13 @@ export default { "Yhteys katkaistu" ], "Discover": [ - "" + "Havaitse" ], "Discover and connect to iSCSI targets": [ "Löydä ja yhdistä iSCSI-kohteita" ], "Discover iSCSI Targets": [ - "" + "Havaitse iSCSI-kohteita" ], "Discover iSCSI targets": [ "Havaitaan iSCSI-kohteita" @@ -666,9 +672,6 @@ export default { "Download logs": [ "Lataa lokit" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Useita toimintoja tullaan suorittamaan asennuksen aikana alla olevan taulukon mukaisesti." - ], "Edit": [ "Muokkaa" ], @@ -732,8 +735,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Esimerkki: https://minunpalvelin.fi" + "Example: %s": [ + "Esimerkki: %s" ], "Excellent signal": [ "Erinomainen signaali" @@ -791,8 +794,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Suodata alueen, aikavyöhykoodin tai UTC-aikaeron mukaan" ], - "Find space": [ - "Vapauta tilaa" + "Final layout": [ + "Lopullinen asettelu" + ], + "Final structure of the system after installation.": [ + "Järjestelmän lopullinen rakenne asennuksen jälkeen." ], "Find space in %s": [ "Vapauta tilaa kohteessa %s" @@ -858,7 +864,7 @@ export default { "Yhdyskäytävän voi määrittää vain tilassa ”Manuaalinen”" ], "GiB": [ - "" + "GiB" ], "Go to network page": [ "Mene verkko-sivulle" @@ -918,6 +924,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Jos jatkat, kiintolevyn osioita muokataan asennusasetusten mukaisesti." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "Jos haluat poistaa tämän tarkistuksen, määritä \"inst.ay_check=0\" Linux-ytimen komentoriville" + ], "In progress": [ "Käynnissä" ], @@ -934,19 +943,19 @@ export default { "Virheellinen käyttäjänimi" ], "Initiator": [ - "" + "Alullepanija (initiator)" ], "Initiator details": [ - "" + "Alullepanijan tiedot" ], "Initiator name": [ - "" + "Alullepanijan nimi" ], "Initiator name could not be updated": [ - "" + "Alullepanijan nimeä ei voi päivittää" ], "Initiator name successfully updated": [ - "" + "Alullepanijan nimi päivitettty" ], "Install": [ "Asenna" @@ -978,7 +987,7 @@ export default { "Install using several devices without modifying existing partitions.": [ "Asenna käyttäen useita laitteita, muuttamatta olevia osioita." ], - "Installation Devices": [ + "Installation devices": [ "Asennuslaitteet" ], "Installation will take %s.": [ @@ -1120,7 +1129,7 @@ export default { "Päänavigointi" ], "Make sure you provide the correct values": [ - "" + "Varmista että tarjoat oikeita arvoja" ], "Manage DASD devices": [ "Hallitse DASD-laitteita" @@ -1158,6 +1167,9 @@ export default { "More languages might be available for the selected product at [Localization] page": [ "Lisää kieliä valitulle tuotteelle saattaa olla tarjolla [Kotoistaminen]-sivulla" ], + "More storage options": [ + "Lisää tallenustilavalintoja" + ], "Moreover, the following partition will be created.": [ "Lisäksi seuraava osio luodaan.", "Lisäksi seuraavat osiot luodaan." @@ -1263,14 +1275,17 @@ export default { "Laitteita ei löydy" ], "No iSCSI Boot Firmware Table (iBFT) found. The initiator can be configured manually.": [ - "" + "iSCSI Boot Firmware Table (iBFT):tä ei löydy. Alullepanija (initiator) voidaan määrittää käsin." ], "No iSCSI targets found.": [ - "" + "iSCSI-kohteita ei löydy." ], "No logical volumes are defined yet": [ "Loogisia taltioita ei ole vielä määritetty" ], + "No partitions will be automatically configured for booting.": [ + "Käynnistämiseen käytettäviä osioita ei ole automaattisesti otettu käyttöön." + ], "No partitions will be automatically configured for booting. Use with caution.": [ "Käynnistämiseen käytettäviä osioita ei ole automaattisesti otettu käyttöön. Käytä tällaisia asetuksia varoen." ], @@ -1284,10 +1299,10 @@ export default { "Kiinteitä yhteyksiä ei löydy" ], "No zFCP controllers found.": [ - "" + "zFCP-ohjaimia ei löydy." ], "No zFCP disks found.": [ - "" + "zFCP-levyjä ei löydy." ], "None": [ "Ei mitään" @@ -1335,7 +1350,7 @@ export default { "Käynnistyksessä" ], "Only available if authentication by target is provided": [ - "" + "Käytettävissä vain kohteen mukaan tunnistautumisen kanssa" ], "Only reused partitions and space not assigned to any partition will be used.": [ "Vain uudelleenkäytettyjä osioita sekä varaamatonta tilaa tullaan käyttämään." @@ -1343,24 +1358,27 @@ export default { "Only reused partitions will be used.": [ "Vain uudelleenkäytettyjä osioita tullaan käyttämään." ], + "Options for partition %s": [ + "Osion %s valinnat" + ], "Options toggle": [ "Valinnat-tila" ], - "Other options": [ - "Muut valinnat" - ], - "Other options toggle": [ - "Muiden valintojen tila" - ], "Overview": [ "Yleiskuva" ], "Package installation failed": [ "Paketin asennus epäonnistui" ], + "Partition %s": [ + "Osio %s" + ], "Partition Info": [ "Osion tiedot" ], + "Partitions": [ + "Osiot" + ], "Partitions needed for booting will also be adapted": [ "Myös käynnistämiseen tarvittavia osioita mukautetaan" ], @@ -1376,14 +1394,23 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Osioiden, joita ei uudelleenkäytetä, kokoja muutetaan tarpeen mukaan." ], - "Partitions to boot will be allocated at the following device.": [ - "Käynnistämiseen tarvittavat osiot otetaan käyttöön seuraavalta laitteelta." + "Partitions to boot will be set up if needed at %s.": [ + "Käynnistämiseen tarvittavat osiot otetaan käyttöön tarvittaessa kohteessa %s." ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Käynnistämiseen tarvittavat osiot otetaan käyttöön asennuslevyltä %s." + "Partitions to boot will be set up if needed at the following device.": [ + "Käynnistämiseen tarvittavat osiot otetaan tarvittaessa käyttöön seuraavalta laitteelta." ], - "Partitions to boot will be allocated at the installation disk.": [ - "Käynnistämiseen tarvittavat osiot otetaan käyttöön asennuslevyltä." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Käynnistämiseen tarvittavat osiot otetaan käyttöön tarvittaessa asennuslevyltä, perustuen %s-tiedostojärjestelmän sijaintiin." + ], + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Käynnistämiseen tarvittavat osiot otetaan tarvittaessa käyttöön asennuslevyltä, perustuen %s-tiedostojärjestelmän sijaintiin." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Käynnistämiseen tarvittavat osiot otetaan tarvittaessa käyttöön asennuslevyltä. Tällä hetkellä kyseessä on %1$s, perustuen%2$s-tiedostojärjestelmän sijaintiin." ], "Partitions will be used and created for %s": [ "Osioita tullaan luomaan ja käyttämään liitoskohdalle %s" @@ -1422,22 +1449,22 @@ export default { "Tarkista onko se käynnissä." ], "Please, perform an iSCSI discovery in order to find available iSCSI targets.": [ - "" + "Käytä iSCSI-havaitsemistoimintoa saatavilla olevien iSCSI-kohteiden löytämiseksi." ], "Please, provide its password to log in to the system.": [ "Kirjoita salasana jota käytetään järjestelmään kirjautumiseen." ], "Please, try to activate a zFCP controller.": [ - "" + "Yritä aktivoida zFCP-ohjain." ], "Please, try to activate a zFCP disk.": [ - "" + "Yritä aktivoida zFCP-levy." ], "Port": [ "Portti" ], "Portal": [ - "" + "Portaali" ], "Pre-installation checks": [ "Ennen asennusta tehtävät tarkistukset" @@ -1448,9 +1475,6 @@ export default { "Product is already registered": [ "Tuote on jo rekisteröity" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Uusien tiedostojärjestelmien tietojen turvaaminen, mukaanlukien data, ohjelmistot ja järjestelmätiedostot." - ], "Provide email address": [ "Kirjoita sähköpostiosoite" ], @@ -1470,7 +1494,7 @@ export default { "Kysmys" ], "Read zFCP devices": [ - "" + "Lue zFCP-laitteita" ], "Reboot": [ "Käynnistä uudelleen" @@ -1538,6 +1562,9 @@ export default { "Result": [ "Tulos" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "Uudelleenkäytettyjä osioita ei tulla pienentämään" ], @@ -1598,21 +1625,9 @@ export default { "Select a disk": [ "Valitse levy" ], - "Select a disk to configure": [ - "Valitse levy jonka asetukset tehdään" - ], - "Select a disk to create %s": [ - "Valitse levy jolle luodaan liitoskohta %s" - ], "Select a disk to define partitions or to mount": [ "Valitse levy osioiden määrittämiseen tai liittämiseen" ], - "Select a disk to format as %s": [ - "Valitse levy joka alustetaan liitoskohtaan %s" - ], - "Select a disk to install the system": [ - "Valitse levy jolle järjestelmä asennetaan" - ], "Select a product": [ "Valitse tuote" ], @@ -1640,9 +1655,6 @@ export default { "Select or enter a valid mount point": [ "Valitse tai syötä kelvollinen liitoskohtaa" ], - "Select the disk to configure partitions for booting": [ - "Valitse levy käynnistysosioiden määrittämiseksi" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Valitse mitä jokaiselle osiolle tehdään, jotta uuden järjestelmän käyttöön vapautuisi tilaa." ], @@ -1671,7 +1683,7 @@ export default { "Aseta DIAG päälle" ], "Set a permanent hostname that won’t change with network updates.": [ - "" + "Aseta pysyvä isäntänimi joka ei muuta verkkopäivityksissä." ], "Setting up connection": [ "Muodostetaan yhteyttä" @@ -1789,10 +1801,10 @@ export default { "TPM-sinetöinti vaatii uuden järjestelmän suoran käynnistämisen." ], "Target Password": [ - "" + "Kohteen salasana" ], "Targets": [ - "" + "Kohteet" ], "The LVM group '%1$s' will remain at %2$s": [ "LVM-ryhmä ”%1$s” säilyy levyllä %2$s" @@ -1880,6 +1892,9 @@ export default { "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ "Viimeinen kohta on tehdä Trusted Platform Module (TPM) -asetukset, jotta salattujen laitteiden aukaisu automaattisesti tapahtuu uuteen järjestelmään ensimmäistä kertaa käytettäessä. Jotta tämä toimisi, laite tulee käynnistää suoraan uudeen käynnistyslataimeen." ], + "The following actions will be performed in the system during installation.": [ + "Seuraavat toiminnot tehdään järjestelmään asennuksen aikana." + ], "The following logical volume will be created": [ "Seuraava looginen taltio luodaan", "Seuraavat loogiset taltiot luodaan" @@ -1899,7 +1914,7 @@ export default { "Seuraavat ohjelmistoryhmät on valittu asennukseen:" ], "The initiator name cannot be blank": [ - "" + "Alullepanijan nimi ei voi olla tyhjä" ], "The installation on your machine is complete.": [ "Asennus laitteelle on valmis." @@ -1947,6 +1962,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "Salasanaa ei tarvita käynnistämiseen ja tietoihin pääsyyn, jos TPM onnistuu varmistamaan järjestelmän eheyden. TPM-sinetöinti vaatii, että uuteen järjestelmään käynnistetään suoraan ensimmäisellä kerralla." ], + "The product will be registered with \"%s\" hostname": [ + "Tuote rekisteröidään isäntänimellä ”%s”" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "Kohteen %1$s koko määritellään dynaamisesti järjestelmä RAM-muistin ja kohteen %2$s erillisen tiedostojärjestelmän olemassa olon perusteella." ], @@ -1999,7 +2017,7 @@ export default { "Koko laitetta tullaan käyttämään kohteelle %s" ], "The zFCP disk was not activated.": [ - "" + "zFCP-levyä ei aktivoitu." ], "There are no disks available for the installation.": [ "Asennusta varten ei ole saatavilla levyjä." @@ -2028,16 +2046,16 @@ export default { "Nämä ovat asennettavan tuotteen asetukset. Asennusohjelman kieltä voi muuttaa yläpalkin [asetuspaneelista]." ], "This action could destroy any data stored on the device.": [ - "" + "Tämä toiminto voi tuhota kaikki laitteelle tallennetut tiedot." ], "This action could destroy any data stored on the devices listed below.": [ - "" + "Tämä toiminto voi tuhota kaikki alla luetelluille laitteille tallennetut tiedot." ], "This extension is not available on the server. Ask the server administrator to mirror the extension.": [ "Tämä laajennus ei ole saatavilla palvelimella. Pyydä palvelimen ylläpitoa peilaamaan laajennus." ], "This hostname is dynamic and may change after a reboot or network update, as configured by the local network administrator.": [ - "" + "Isäntänimi on dynaaminen ja voi muuttua uudelleenkäynnistyksen tai verkkopäivityksen myötä, siten kuten paikallinen verkkoylläpitäjä on määritellyt." ], "This license is not available in %s.": [ "Lisenssiä ei ole saatavilla tuotteelle %s." @@ -2075,6 +2093,9 @@ export default { "Tmpfs": [ "Tmpfs" ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "Jotta järjestelmä käynnistyisi, asennusohjelman saattaa täytyä luoda tai tehdä osioiden asetusmuutoksia soveltuvalla levyllä." + ], "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ "Jotta järjestelmä käynnistyisi, asennusohjelman saattaa täytyä luoda tai tehdä osioiden asetusmuutoksia soveltuvalla levyllä." ], @@ -2115,10 +2136,10 @@ export default { "Päivitä saatavilla olevia laitteita ja aktivoi salatut laitteet" ], "Updating the hostname now or later will not change the currently registered hostname.": [ - "" + "Isäntänimen päivittäminen nyt tai myöhemmin ei muuta tällä hetkellä rekisteröityä isäntänimeä." ], "Updating the initiator name": [ - "" + "Päivitetään alullepanijan nimeä" ], "Upload": [ "Lataa" @@ -2253,7 +2274,7 @@ export default { "Käytetään [%s]-näppämistöä" ], "Using a hashed password.": [ - "" + "Käytetään tiivisteellistä salasanaa." ], "Using an existing partition": [ "Käytä olemassa olevaa osioita" @@ -2264,6 +2285,9 @@ export default { "Using transient hostname: %s": [ "Käytetään tilapäistä verkkonimeä: %s" ], + "Volume group %s": [ + "Taltioryhmä %s" + ], "Volume group '%s' already exists. Enter a different name.": [ "Taltioryhmä ”%s” on jo olemassa, syötä toinen nimi." ], @@ -2382,9 +2406,9 @@ export default { "zFCP" ], "zFCP Disk Activation": [ - "" + "zFCP-levyaktivointi" ], "zFCP Disk activation form": [ - "" + "zFCP-levyaktivoinnin lomake" ] }; diff --git a/web/src/po/po.fr.js b/web/src/po/po.fr.js index f8730c0a37..3bff9bcc2a 100644 --- a/web/src/po/po.fr.js +++ b/web/src/po/po.fr.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Sélection du fuseau horaire" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -139,9 +145,6 @@ export default { "Add another address": [ "Ajouter une autre adresse" ], - "Add another partition or mount an existing one": [ - "Ajouter une autre partition ou en monter une existante" - ], "Add device menu": [ "Ajouter le menu du périphérique" ], @@ -327,9 +330,6 @@ export default { "Change Language": [ "Modifier la langue" ], - "Change boot options": [ - "Modifier les options d'amorçage" - ], "Change device menu": [ "Modifier le menu du périphérique" ], @@ -357,12 +357,12 @@ export default { "Change the file system or mount point": [ "Modifier le système de fichiers ou le point de montage" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "ID du canal" ], - "Check the %d planned actions": [ - "Vérifier les %d actions planifiées" - ], "Check the authentication parameters.": [ "Vérifiez les paramètres d'authentification." ], @@ -396,9 +396,6 @@ export default { "Close": [ "Fermer" ], - "Collapse the list of planned actions": [ - "Réduire la liste des actions planifiées" - ], "Configuration out of sync": [ "Configuration désynchronisée" ], @@ -609,9 +606,6 @@ export default { "Details": [ "Détails" ], - "Details for %s": [ - "Détails pour %s" - ], "Details will appear after the connection is successfully established.": [ "Les détails s'afficheront une fois la connexion établie avec succès." ], @@ -666,9 +660,6 @@ export default { "Download logs": [ "Télécharger les journaux" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Au cours de l'installation, plusieurs actions seront effectuées pour configurer la disposition indiquée dans le tableau ci-dessous." - ], "Edit": [ "Modifier" ], @@ -732,8 +723,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Exemple : https://monserveur.com" + "Example: %s": [ + "Exemple : %s" ], "Excellent signal": [ "Signal excellent" @@ -791,8 +782,8 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Filtrer par territoire, code de fuseau horaire ou décalage UTC" ], - "Find space": [ - "Trouver de l'espace" + "Final layout": [ + "" ], "Find space in %s": [ "Trouver de l'espace dans %s" @@ -918,6 +909,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Si vous continuez, les partitions de votre disque dur seront modifiées selon les paramètres d'installation fournis." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "En cours" ], @@ -978,9 +972,6 @@ export default { "Install using several devices without modifying existing partitions.": [ "Effectuez l'installation à l'aide de plusieurs périphériques sans modifier les partitions existantes." ], - "Installation Devices": [ - "Périphériques d'installation" - ], "Installation will take %s.": [ "L'installation utilisera %s." ], @@ -1346,12 +1337,6 @@ export default { "Options toggle": [ "Bouton de bascule des options" ], - "Other options": [ - "Autres options" - ], - "Other options toggle": [ - "Bouton de bascule Autres options" - ], "Overview": [ "Aperçu" ], @@ -1361,6 +1346,9 @@ export default { "Partition Info": [ "Informations sur la partition" ], + "Partitions": [ + "Partitions" + ], "Partitions needed for booting will also be adapted": [ "Les partitions nécessaires au démarrage seront également adaptées" ], @@ -1376,14 +1364,11 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Les partitions qui ne sont pas réutilisées seraient redimensionnées si nécessaire." ], - "Partitions to boot will be allocated at the following device.": [ - "Les partitions à amorcer seront attribuées au périphérique suivant." - ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Les partitions de démarrage seront allouées sur le disque d'installation %s." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], - "Partitions to boot will be allocated at the installation disk.": [ - "Les partitions pour le démarrage seront allouées sur le disque d'installation." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], "Partitions will be used and created for %s": [ "Des partitions seront créées et utilisées pour %s" @@ -1448,9 +1433,6 @@ export default { "Product is already registered": [ "Le produit est déjà enregistré" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Protection des informations stockées dans les nouveaux systèmes de fichiers, y compris les données, les programmes et les fichiers système." - ], "Provide email address": [ "Fournir une adresse électronique" ], @@ -1538,6 +1520,9 @@ export default { "Result": [ "Résultat" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "Les partitions réutilisées ne seront pas réduites" ], @@ -1598,21 +1583,9 @@ export default { "Select a disk": [ "Sélectionner un disque" ], - "Select a disk to configure": [ - "Sélectionner un disque à configurer" - ], - "Select a disk to create %s": [ - "Sélectionner un disque pour créer %s" - ], "Select a disk to define partitions or to mount": [ "Sélectionner un disque pour définir des partitions ou effectuer le montage" ], - "Select a disk to format as %s": [ - "Sélectionner un disque pour à formater en tant que %s" - ], - "Select a disk to install the system": [ - "Sélectionner un disque pour installer le système" - ], "Select a product": [ "Sélectionner un produit" ], @@ -1640,9 +1613,6 @@ export default { "Select or enter a valid mount point": [ "Sélectionner ou entrer un point de montage valide" ], - "Select the disk to configure partitions for booting": [ - "Sélectionnez le disque afin de configurer les partitions pour le démarrage" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Sélectionnez ce qu'il faut faire avec chaque partition afin de trouver de l'espace pour allouer le nouveau système." ], @@ -1947,6 +1917,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "Le mot de passe ne sera pas nécessaire pour démarrer et accéder aux données si le TPM peut vérifier l'intégrité du système. Le verrouillage du TPM requiert que le nouveau système soit démarré directement lors de sa première exécution." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "La taille de %1$s sera ajustée dynamiquement en fonction de la quantité de mémoire vive du système et de la présence d'un système de fichiers distinct pour %2$s." ], diff --git a/web/src/po/po.id.js b/web/src/po/po.id.js index abc5e05896..25371912a1 100644 --- a/web/src/po/po.id.js +++ b/web/src/po/po.id.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Pemilihan zona waktu" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -135,9 +141,6 @@ export default { "Add another address": [ "Tambahkan alamat lain" ], - "Add another partition or mount an existing one": [ - "Tambahkan partisi lain atau pasang partisi yang sudah ada" - ], "Add device menu": [ "Tambahkan menu perangkat" ], @@ -321,9 +324,6 @@ export default { "Change Language": [ "Ubah Bahasa" ], - "Change boot options": [ - "Mengubah opsi boot" - ], "Change device menu": [ "Ubah menu perangkat" ], @@ -348,15 +348,27 @@ export default { "Change selection": [ "Mengubah pilihan" ], + "Change the disk to configure": [ + "Ganti disk untuk konfigurasi" + ], + "Change the disk to create %s": [ + "Ganti disk untuk membuat %s" + ], + "Change the disk to format as %s": [ + "Ganti disk untuk diformat sebagai %s" + ], + "Change the disk to install the system": [ + "Ganti disk untuk menginstal sistem" + ], "Change the file system or mount point": [ "Ubah sistem berkas atau titik mount" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "Perubahan pada pengaturan ini akan segera memperbarui bagian 'Hasil' di bawah ini." + ], "Channel ID": [ "ID saluran" ], - "Check the %d planned actions": [ - "Periksa %d tindakan yang direncanakan" - ], "Check the authentication parameters.": [ "Periksa parameter otentikasi." ], @@ -390,9 +402,6 @@ export default { "Close": [ "Tutup" ], - "Collapse the list of planned actions": [ - "Lipat daftar tindakan yang direncanakan" - ], "Configuration out of sync": [ "Konfigurasi tidak sinkron" ], @@ -603,9 +612,6 @@ export default { "Details": [ "Detail" ], - "Details for %s": [ - "Rincian untuk %s" - ], "Details will appear after the connection is successfully established.": [ "Rincian akan ditampilkan setelah koneksi berhasil terhubung." ], @@ -660,9 +666,6 @@ export default { "Download logs": [ "Unduh log" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Selama pemasangan, beberapa tindakan akan dilakukan untuk mengatur tata letak yang ditunjukkan pada tabel di bawah ini." - ], "Edit": [ "Edit" ], @@ -726,8 +729,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Contoh: https://myserver.com" + "Example: %s": [ + "Contoh: %s" ], "Excellent signal": [ "Sinyal sangat baik" @@ -748,7 +751,7 @@ export default { "Perluas instalasi melampaui perangkat %d yang saat ini dipilih" ], "Extend the installation beyond the currently selected disk": [ - "Perluas instalasi melampaui disk %d yang saat ini dipilih." + "Perluas instalasi melampaui disk %d yang saat ini dipilih" ], "Extensions": [ "Ekstensi" @@ -783,8 +786,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Memfilter berdasarkan wilayah, kode zona waktu, atau offset UTC" ], - "Find space": [ - "Temukan ruang" + "Final layout": [ + "Tata letak akhir" + ], + "Final structure of the system after installation.": [ + "Struktur akhir sistem setelah pemasangan." ], "Find space in %s": [ "Temukan ruang di %s" @@ -909,6 +915,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Jika Anda melanjutkan, partisi pada hard disk Anda akan dimodifikasi sesuai dengan pengaturan instalasi yang disediakan." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "Dalam proses" ], @@ -969,8 +978,8 @@ export default { "Install using several devices without modifying existing partitions.": [ "Pasang menggunakan beberapa perangkat tanpa mengubah partisi yang ada." ], - "Installation Devices": [ - "Perangkat Pemasangan" + "Installation devices": [ + "Perangkat pemasangan" ], "Installation will take %s.": [ "Penginstalan akan memakan waktu %s." @@ -1149,6 +1158,9 @@ export default { "More languages might be available for the selected product at [Localization] page": [ "Bahasa lain mungkin tersedia untuk produk yang dipilih di halaman [Localization]" ], + "More storage options": [ + "Lebih banyak opsi penyimpanan" + ], "Moreover, the following partition will be created.": [ "Selain itu, partisi berikut akan dibuat." ], @@ -1260,6 +1272,9 @@ export default { "No logical volumes are defined yet": [ "Belum ada volume logis yang didefinisikan" ], + "No partitions will be automatically configured for booting.": [ + "Partisi tidak akan dikonfigurasi secara otomatis untuk booting." + ], "No partitions will be automatically configured for booting. Use with caution.": [ "Tidak ada partisi yang akan dikonfigurasi secara otomatis untuk booting. Gunakan dengan hati-hati." ], @@ -1332,24 +1347,27 @@ export default { "Only reused partitions will be used.": [ "Hanya partisi yang telah digunakan kembali yang akan digunakan." ], + "Options for partition %s": [ + "Opsi untuk partisi %s" + ], "Options toggle": [ "Sakelar opsi" ], - "Other options": [ - "Opsi lain" - ], - "Other options toggle": [ - "Tombol opsi lain" - ], "Overview": [ "Ikhtisar" ], "Package installation failed": [ "Pemasangan paket gagal" ], + "Partition %s": [ + "Partisi %s" + ], "Partition Info": [ "Info Partisi" ], + "Partitions": [ + "Partisi" + ], "Partitions needed for booting will also be adapted": [ "Partisi yang diperlukan untuk booting juga akan disesuaikan" ], @@ -1365,14 +1383,23 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Partisi yang tidak digunakan ulang akan diubah ukurannya jika diperlukan." ], - "Partitions to boot will be allocated at the following device.": [ - "Partisi untuk boot akan dialokasikan pada perangkat berikut." + "Partitions to boot will be set up if needed at %s.": [ + "Partisi untuk booting akan disiapkan jika diperlukan di %s." + ], + "Partitions to boot will be set up if needed at the following device.": [ + "Partisi untuk booting akan disiapkan jika diperlukan pada perangkat berikut." ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Partisi untuk boot akan dialokasikan pada disk instalasi %s." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Partisi untuk booting akan dibuat jika diperlukan pada disk instalasi, berdasarkan lokasi sistem berkas %s." ], - "Partitions to boot will be allocated at the installation disk.": [ - "Partisi untuk boot akan dialokasikan pada disk instalasi." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Partisi untuk booting akan dibuat jika diperlukan pada disk instalasi, berdasarkan lokasi sistem berkas %s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Partisi untuk booting akan dibuat jika diperlukan pada disk instalasi. Saat ini %1$s, berdasarkan lokasi sistem berkas %2$s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Partisi untuk booting akan dibuat jika diperlukan pada disk instalasi. Saat ini %1$s, berdasarkan lokasi sistem berkas %2$s." ], "Partitions will be used and created for %s": [ "Partisi akan digunakan dan dibuat untuk %s" @@ -1437,8 +1464,8 @@ export default { "Product is already registered": [ "Produk sudah terdaftar" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Perlindungan untuk informasi yang disimpan di sistem berkas baru, termasuk data, program, dan berkas sistem." + "Protection for the information stored at the new file systems, including data, programs, and system files.": [ + "Pemeliharaan keamanan informasi yang disimpan pada sistem berkas baru, termasuk data, program, dan berkas sistem." ], "Provide email address": [ "Berikan alamat email" @@ -1527,6 +1554,9 @@ export default { "Result": [ "Hasil" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "Hasil penerapan konfigurasi yang dijelaskan pada bagian 'Pengaturan' di atas." + ], "Reused partitions will not be shrunk": [ "Partisi yang digunakan kembali tidak akan diperkecil" ], @@ -1587,21 +1617,9 @@ export default { "Select a disk": [ "Pilih disk" ], - "Select a disk to configure": [ - "Pilih disk yang akan dikonfigurasi" - ], - "Select a disk to create %s": [ - "Pilih disk untuk membuat %s" - ], "Select a disk to define partitions or to mount": [ "Pilih perangkat lain untuk mendefinisikan partisi atau untuk mount" ], - "Select a disk to format as %s": [ - "Pilih disk yang akan diformat sebagai %s" - ], - "Select a disk to install the system": [ - "Pilih disk untuk memasang sistem" - ], "Select a product": [ "Pilih produk" ], @@ -1629,9 +1647,6 @@ export default { "Select or enter a valid mount point": [ "Pilih atau masukkan titik mount yang valid" ], - "Select the disk to configure partitions for booting": [ - "Pilih disk yang akan dikonfigurasi partisi untuk booting" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Pilih tindakan yang akan dilakukan pada setiap partisi untuk menemukan ruang yang cukup untuk mengalokasikan sistem baru." ], @@ -1866,6 +1881,9 @@ export default { "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ "Langkah terakhir untuk mengonfigurasi Trusted Platform Module (TPM) agar dapat membuka perangkat yang dienkripsi secara otomatis selama booting pertama dari sistem yang baru. Agar dapat berfungsi, mesin harus melakukan booting secara langsung ke boot loader yang baru." ], + "The following actions will be performed in the system during installation.": [ + "Tindakan berikut akan dilakukan dalam sistem selama proses instalasi." + ], "The following logical volume will be created": [ "Volume logis berikut akan dibuat" ], @@ -1929,6 +1947,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "Kata sandi tidak akan diperlukan untuk mem-boot dan mengakses data jika TPM dapat memverifikasi integritas sistem. Penyegelan TPM mengharuskan sistem baru untuk di-boot secara langsung saat pertama kali dijalankan." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "Ukuran untuk %1$s akan disesuaikan secara dinamis berdasarkan jumlah RAM dalam sistem dan keberadaan sistem berkas yang terpisah untuk %2$s." ], @@ -2055,6 +2076,9 @@ export default { "Tmpfs": [ "Tmpfs" ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "Untuk memastikan sistem baru dapat booting, penginstal mungkin perlu membuat atau mengonfigurasi beberapa partisi di disk yang sesuai." + ], "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ "Untuk memastikan sistem baru dapat melakukan booting, penginstal mungkin perlu membuat atau mengonfigurasi beberapa partisi di disk yang sesuai." ], @@ -2244,6 +2268,9 @@ export default { "Using transient hostname: %s": [ "Menggunakan nama host sementara: %s" ], + "Volume group %s": [ + "Grup volume %s" + ], "Volume group '%s' already exists. Enter a different name.": [ "Grup volume ‘%s’ sudah ada. Masukkan nama yang berbeda." ], diff --git a/web/src/po/po.it.js b/web/src/po/po.it.js index 3e53c26772..2c39f04ff8 100644 --- a/web/src/po/po.it.js +++ b/web/src/po/po.it.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Selezione fuso orario" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -139,9 +145,6 @@ export default { "Add another address": [ "Aggiungi un altro indirizzo" ], - "Add another partition or mount an existing one": [ - "Aggiungi un'altra partizione o montane una esistente" - ], "Add device menu": [ "Aggiungi menu del dispositivo" ], @@ -327,9 +330,6 @@ export default { "Change Language": [ "Cambia lingua" ], - "Change boot options": [ - "Cambia le opzioni di boot" - ], "Change device menu": [ "Cambia menu del dispositivo" ], @@ -357,12 +357,12 @@ export default { "Change the file system or mount point": [ "Modifica il file system o il punto di montaggio" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "ID canale" ], - "Check the %d planned actions": [ - "Verifica le azioni pianificate %d" - ], "Check the authentication parameters.": [ "Verificare i parametri di autenticazione." ], @@ -396,9 +396,6 @@ export default { "Close": [ "Esci" ], - "Collapse the list of planned actions": [ - "Riduci l'elenco delle azioni pianificate" - ], "Configuration out of sync": [ "Configurazione fuori sincronizzazione" ], @@ -609,9 +606,6 @@ export default { "Details": [ "Dettagli" ], - "Details for %s": [ - "Dettagli di %s" - ], "Details will appear after the connection is successfully established.": [ "I dettagli saranno visualizzati una volta stabilita la connessione." ], @@ -666,9 +660,6 @@ export default { "Download logs": [ "Scarica i logs" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Durante l'installazione verranno eseguite diverse azioni per configurare il layout mostrato nella tabella seguente." - ], "Edit": [ "Modifica" ], @@ -732,8 +723,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Esempio: https://mioserver.com" + "Example: %s": [ + "Esempio: %s" ], "Excellent signal": [ "Segnale eccellente" @@ -791,8 +782,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Filtra per territorio, codice di fuso orario o differenza da UTC" ], - "Find space": [ - "Trova spazio" + "Final layout": [ + "" + ], + "Final structure of the system after installation.": [ + "" ], "Find space in %s": [ "Trova spazio in %s" @@ -918,6 +912,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Se continui, le partizioni del disco rigido saranno modificate in base alle impostazioni di installazione fornite." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "In corso" ], @@ -978,9 +975,6 @@ export default { "Install using several devices without modifying existing partitions.": [ "Installa utilizzando il dispositivo %s senza modificare le partizioni esistenti." ], - "Installation Devices": [ - "Dispositivi di installazione" - ], "Installation will take %s.": [ "L'installazione richiederà %s." ], @@ -1346,12 +1340,6 @@ export default { "Options toggle": [ "Abilita opzioni" ], - "Other options": [ - "Altre opzioni" - ], - "Other options toggle": [ - "Commutazione di altre opzioni" - ], "Overview": [ "Panoramica" ], @@ -1361,6 +1349,9 @@ export default { "Partition Info": [ "Informazioni sulla partizione" ], + "Partitions": [ + "Partizioni" + ], "Partitions needed for booting will also be adapted": [ "Le partizioni necessarie per l'avvio saranno anche adattate" ], @@ -1376,14 +1367,11 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Le partizioni che non vengono riutilizzate verranno ridimensionate se necessario." ], - "Partitions to boot will be allocated at the following device.": [ - "Le partizioni per l'avvio saranno allocate sul seguente dispositivo." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Le partizioni di avvio verranno allocate nel disco di installazione %s." - ], - "Partitions to boot will be allocated at the installation disk.": [ - "Le partizioni di avvio verranno allocate sul disco di installazione." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], "Partitions will be used and created for %s": [ "Le partizioni verranno utilizze e create per %s" @@ -1448,9 +1436,6 @@ export default { "Product is already registered": [ "Il prodotto è già registrato" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Protezione per le informazoini memorizzate nei nuovi file system, tra cui dati, programmi e file di sistema." - ], "Provide email address": [ "Fornire un indirizzo e-mail" ], @@ -1538,6 +1523,9 @@ export default { "Result": [ "Risultato" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "Le partizioni riutilizzate non verranno ridotte" ], @@ -1598,21 +1586,9 @@ export default { "Select a disk": [ "Seleziona un disco" ], - "Select a disk to configure": [ - "Seleziona un disco da configurare" - ], - "Select a disk to create %s": [ - "Seleziona un disco per creare %s" - ], "Select a disk to define partitions or to mount": [ "Seleziona un disco per definire le partizioni o montare" ], - "Select a disk to format as %s": [ - "Seleziona un disco da formattare come %s" - ], - "Select a disk to install the system": [ - "Seleziona un disco su cui installare il sistema" - ], "Select a product": [ "Seleziona un prodotto" ], @@ -1640,9 +1616,6 @@ export default { "Select or enter a valid mount point": [ "Seleziona o immetti un punto di montaggio valido" ], - "Select the disk to configure partitions for booting": [ - "L'installazione non provvederà a configurare le partizioni per l'avvio" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Selezionare le azioni da eseguire con ogni partizione per trovare lo spazio per allocare il nuovo sistema." ], @@ -1947,6 +1920,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "Non sarà necessaria la password per avviare e accedere ai dati se TPM è in grado di verificare l'integrità del sistema. La sigillatura del TPM richiede che il nuovo sistema venga avviato direttamente alla sua prima esecuzione." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "La dimensione di %1$s verrà regolata dinamicamente in base alla quantità di RAM nel sistema e alla presenza di un file system separato per %2$s." ], diff --git a/web/src/po/po.ja.js b/web/src/po/po.ja.js index 311433f5e3..ca8772e3d3 100644 --- a/web/src/po/po.ja.js +++ b/web/src/po/po.ja.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " タイムゾーンの選択" ], + "\"%s\"": [ + "\"%s\"" + ], + "\"%s\" does not exist or is no longer available.": [ + "\"%s\" は存在していないか、利用できなくなっています。" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -61,7 +67,7 @@ export default { "可能であれば、 %2$s から %3$s までの範囲で %1$s を %4$s 向けに作成します" ], "A file system will be used for the whole device": [ - "ファイルシステムはデバイス全体を使用します" + "ファイルシステムはデバイス全体を使用する" ], "A generic minimum size of %1$s will be used for the new %2$s": [ "新しい %2$s に対しては少なくとも %1$s を使用します" @@ -73,7 +79,7 @@ export default { "新しい %3$s に対しては一般的なサイズ %1$s から %2$s の範囲を使用します" ], "A new partition will be created for %s": [ - "%s に対しては新しいパーティションを作成します" + "%s に対して新しいパーティションを作成する" ], "A new volume will be created for %s": [ "%s に対しては新しいボリュームを作成します" @@ -85,7 +91,7 @@ export default { "パーティションを縮小するかもしれません" ], "A partition will be deleted": [ - "パーティションを削除します" + "パーティションを削除する" ], "Accept": [ "受け入れる" @@ -135,9 +141,6 @@ export default { "Add another address": [ "その他のアドレスの追加" ], - "Add another partition or mount an existing one": [ - "他のパーティションの追加または既存のパーティションのマウント" - ], "Add device menu": [ "デバイスメニューの追加" ], @@ -163,7 +166,7 @@ export default { "すべての競合が解決されたか、競合が検出されませんでした。セットアップを安全に続行できます。" ], "All content not configured to be mounted will be deleted": [ - "マウントするように設定していない全ての内容を削除します" + "マウントするように設定していない全ての内容を削除する" ], "All content will be deleted": [ "全ての内容を削除する" @@ -187,7 +190,7 @@ export default { "既に利用可能な全てのディスクを使用しています" ], "An existing partition will be used for %s": [ - "%s に対しては既存のパーティションを使用します" + "%s に対して既存のパーティションを使用する" ], "Any existing partition will be removed and all data in the disk will be lost.": [ "全てのパーティションを削除し、ディスク内に存在するデータを全て消去します。" @@ -211,7 +214,7 @@ export default { "選択しているモードの場合、 1 つ以上のアドレスを設定しなければなりません" ], "At least one partition will be deleted": [ - "少なくとも 1 つのパーティションを削除します" + "少なくとも 1 つのパーティションを削除する" ], "At this point you can power off the machine.": [ "マシンの電源を切って問題ありません。" @@ -321,9 +324,6 @@ export default { "Change Language": [ "言語の変更" ], - "Change boot options": [ - "起動オプションの変更" - ], "Change device menu": [ "デバイスメニューの変更" ], @@ -348,15 +348,27 @@ export default { "Change selection": [ "選択の変更" ], + "Change the disk to configure": [ + "設定したいディスクの変更" + ], + "Change the disk to create %s": [ + "%s を作成するディスクの変更" + ], + "Change the disk to format as %s": [ + "%s としてフォーマットするディスクの変更" + ], + "Change the disk to install the system": [ + "システムのインストール先となるディスクの変更" + ], "Change the file system or mount point": [ "ファイルシステムまたはマウントポイントの変更" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "これらの設定を変更すると、下記の '結果' セクションに即時に反映されます。" + ], "Channel ID": [ "チャネル ID" ], - "Check the %d planned actions": [ - "%d 個の処理計画を確認する" - ], "Check the authentication parameters.": [ "認証パラメータをご確認ください。" ], @@ -390,9 +402,6 @@ export default { "Close": [ "閉じる" ], - "Collapse the list of planned actions": [ - "処理計画の一覧を巻き取る" - ], "Configuration out of sync": [ "設定が同期できていません" ], @@ -529,7 +538,7 @@ export default { "現在の内容" ], "Current partitions will be kept": [ - "現在のパーティションを維持します" + "現在のパーティションを維持する" ], "Custom": [ "独自設定" @@ -603,9 +612,6 @@ export default { "Details": [ "詳細" ], - "Details for %s": [ - "%s の詳細" - ], "Details will appear after the connection is successfully established.": [ "詳細は接続成功後に表示されます。" ], @@ -660,9 +666,6 @@ export default { "Download logs": [ "ログのダウンロード" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "インストールの際、下記の表に示した配置を設定するためにいくつかの処理が行われます。" - ], "Edit": [ "編集" ], @@ -726,8 +729,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "例: https://myserver.com" + "Example: %s": [ + "例: %s" ], "Excellent signal": [ "優良な信号強度" @@ -783,8 +786,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "地域/タイムゾーンコード/UTC オフセット値でフィルタ" ], - "Find space": [ - "領域の検出" + "Final layout": [ + "最終形態" + ], + "Final structure of the system after installation.": [ + "インストール後のシステムの最終形です。" ], "Find space in %s": [ "%s 内での領域検出" @@ -909,6 +915,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "続行すると、お使いのコンピュータのハードディスクにあるパーティションは、ここまでのダイアログで設定したとおりに変更されます。" ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "このチェックを無効化したい場合は、カーネルのコマンドラインに \"inst.ay_check=0\" を指定してください" + ], "In progress": [ "処理中" ], @@ -969,7 +978,7 @@ export default { "Install using several devices without modifying existing partitions.": [ "複数のデバイスの既存パーティションを変更せずにインストールします。" ], - "Installation Devices": [ + "Installation devices": [ "インストール先のデバイス" ], "Installation will take %s.": [ @@ -1149,6 +1158,9 @@ export default { "More languages might be available for the selected product at [Localization] page": [ "選択した製品に対する言語の詳細な設定は、 [ローカライゼーション] のページにあります" ], + "More storage options": [ + "さらなるストレージオプション" + ], "Moreover, the following partition will be created.": [ "このほか、下記のパーティションを作成します。" ], @@ -1225,7 +1237,7 @@ export default { "検出された Wi-Fi ネットワークはありません" ], "No additional partitions will be created": [ - "追加パーティションは作成しません" + "追加パーティションは作成しない" ], "No additional software was selected.": [ "追加のソフトウエアは何も選択していません。" @@ -1260,6 +1272,9 @@ export default { "No logical volumes are defined yet": [ "何も論理ボリュームを設定していません" ], + "No partitions will be automatically configured for booting.": [ + "起動用のパーティションを自動設定しません。" + ], "No partitions will be automatically configured for booting. Use with caution.": [ "起動用のパーティションを自動設定しません。注意してお使いください。" ], @@ -1332,24 +1347,27 @@ export default { "Only reused partitions will be used.": [ "再利用するよう設定したパーティションのみを使用します。" ], + "Options for partition %s": [ + "パーティション %s のオプション" + ], "Options toggle": [ "オプションの切り替え" ], - "Other options": [ - "その他のオプション" - ], - "Other options toggle": [ - "その他のオプションの切り替え" - ], "Overview": [ "概要" ], "Package installation failed": [ "インストールのインストール失敗" ], + "Partition %s": [ + "パーティション %s" + ], "Partition Info": [ "パーティション情報" ], + "Partitions": [ + "パーティション" + ], "Partitions needed for booting will also be adapted": [ "起動に必要なパーティションについても調整を行います" ], @@ -1365,17 +1383,29 @@ export default { "Partitions that are not reused would be resized if needed.": [ "再利用するように設定していないパーティションは、必要に応じてサイズ変更されます。" ], - "Partitions to boot will be allocated at the following device.": [ - "下記のデバイス内に起動用パーティションを割り当てます。" + "Partitions to boot will be set up if needed at %s.": [ + "%s 内に起動用のパーティションを設定します。" + ], + "Partitions to boot will be set up if needed at the following device.": [ + "下記のデバイス内に必要に応じて起動用のパーティションを割り当てます。" ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "インストール先のディスク %s 内で起動用のパーティションを割り当てます。" + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "ファイルシステム %s の配置場所に応じて 、 必要であればインストール先のディスク内に起動用のパーティションを割り当てます。" ], - "Partitions to boot will be allocated at the installation disk.": [ - "インストール先のディスク内に起動用のパーティションを割り当てます。" + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "ファイルシステム %s の配置場所に応じて、 必要であればインストール先のディスク内に起動用のパーティションを割り当てます。" + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "ファイルシステム %2$s の配置場所に応じて (現時点では %1$s) 、 必要であればインストール先のディスク内に起動用のパーティションを割り当てます。" + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "ファイルシステム %2$s の配置場所に応じて (現時点では %1$s) 、 必要であればインストール先のディスク内に起動用のパーティションを割り当てます。" + ], + "Partitions to host \"system\" will be created if needed.": [ + "必要に応じて、 \"システム\" を保持するためのパーティションを作成します。" ], "Partitions will be used and created for %s": [ - "パーティションを使用し、 %s 向けに作成します" + "%s 向けにパーティションを使用して作成する" ], "Password": [ "パスワード" @@ -1437,8 +1467,8 @@ export default { "Product is already registered": [ "製品は既に登録済みです" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "データやプログラム、システムファイルなど、新しく作成するファイルシステム内に配置される情報への保護を行います。" + "Protection for the information stored at the new file systems, including data, programs, and system files.": [ + "データやプログラム、システムファイルなど、 新しく作成するファイルシステム内に配置される情報への保護を行います。" ], "Provide email address": [ "電子メールアドレスを入力する" @@ -1527,8 +1557,11 @@ export default { "Result": [ "結果" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "上記の '設定' セクションに示された設定を適用した結果です。" + ], "Reused partitions will not be shrunk": [ - "再利用したパーティションは縮小しません" + "再利用したパーティションは縮小しない" ], "Review and fix": [ "確認と修正" @@ -1587,21 +1620,9 @@ export default { "Select a disk": [ "ディスクの選択" ], - "Select a disk to configure": [ - "設定したいディスクの選択" - ], - "Select a disk to create %s": [ - "%s を作成するディスクの選択" - ], "Select a disk to define partitions or to mount": [ "パーティションの設定またはマウントを行うディスクを選択してください" ], - "Select a disk to format as %s": [ - "%s としてフォーマットするディスクの選択" - ], - "Select a disk to install the system": [ - "システムのインストール先となるディスクの選択" - ], "Select a product": [ "製品の選択" ], @@ -1629,9 +1650,6 @@ export default { "Select or enter a valid mount point": [ "正しいマウントポイントを選択または入力してください" ], - "Select the disk to configure partitions for booting": [ - "起動用のパーティションを設定するディスクの選択" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "新しいシステムのインストール先となる領域を確保するため、各パーティションに対してすべきことを選択します。" ], @@ -1669,7 +1687,7 @@ export default { "設定" ], "Several partitions will be deleted": [ - "いくつかのパーティションを削除します" + "いくつかのパーティションを削除する" ], "Show": [ "表示" @@ -1798,7 +1816,7 @@ export default { "接続時に利用可能な任意のデバイスを使用するようにします。" ], "The connection will be used only during installation and not available in the installed system.": [ - "接続はインストール時にのみ使用され、インストールされたシステムでは利用できません。" + "接続をインストール時にのみ使用するものとし、インストール後は削除します。" ], "The content may be deleted": [ "内容が削除されるかもしれません" @@ -1866,6 +1884,9 @@ export default { "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ "Trusted Platform Module (TPM) の設定の最後では、新しいシステムの初回起動時に暗号化されたデバイスを自動で解除するよう設定します。これを動作させるためには、マシンが新しいブートローダを直接起動するように設定しておく必要があります。" ], + "The following actions will be performed in the system during installation.": [ + "インストールの際に、システムに対して下記の処理が実施されます。" + ], "The following logical volume will be created": [ "下記の論理ボリュームを作成します" ], @@ -1929,6 +1950,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "TPM 側でシステムの一貫性検証が成功すると、起動とデータへのアクセス処理に際してパスワードが不要になります。 TPM シーリングを使用するには、新しいシステムの初回起動時に直接起動を行う必要があります。" ], + "The product will be registered with \"%s\" hostname": [ + "製品をホスト名 \"%s\" で登録します" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "システムのメモリサイズと %2$s 向けの個別ファイルシステムの存在に応じて、 %1$s 向けのサイズを動的に調整します。" ], @@ -1978,7 +2002,7 @@ export default { "システムは %s を既定の言語として使用します。" ], "The whole device will be used for %s": [ - "デバイス全体を %s 向けに使用します" + "デバイス全体を %s 向けに使用する" ], "The zFCP disk was not activated.": [ "zFCP ディスクは有効化されませんでした。" @@ -2055,6 +2079,9 @@ export default { "Tmpfs": [ "tmpfs" ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "システムを起動できるようにするため、インストーラは適切なディスク内にいくつかの追加パーティションを作成もしくは設定する必要があるかもしれません。" + ], "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ "システムを起動できるようにするため、インストーラはディスク内にいくつかの追加パーティションを作成もしくは設定する必要があるかもしれません。" ], @@ -2244,6 +2271,9 @@ export default { "Using transient hostname: %s": [ "暫定的なホスト名を使用しています: %s" ], + "Volume group %s": [ + "ボリュームグループ %s" + ], "Volume group '%s' already exists. Enter a different name.": [ "ボリュームグループ '%s' は既に存在しています。別の名前を入力してください。" ], diff --git a/web/src/po/po.ka.js b/web/src/po/po.ka.js index b0e4e9847e..095b79a9e3 100644 --- a/web/src/po/po.ka.js +++ b/web/src/po/po.ka.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " დროის სარტყლის არჩევანი" ], + "\"%s\"": [ + "\"%s\"" + ], + "\"%s\" does not exist or is no longer available.": [ + "\"%s\" არ არსებობს, ან ხელმისაწვდომი აღარაა." + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -44,8 +50,8 @@ export default { "%s-ის ლოგო" ], "%s will be created as a logical volume": [ - "", - "" + "%s შეიქმნება ლოგიკური ტომის სახით", + "%s შეიქმნება ლოგიკური ტომების სახით" ], "%s will still contain the configured LVM groups and any partition needed to boot": [ "" @@ -139,9 +145,6 @@ export default { "Add another address": [ "სხვა მისამართის დამატება" ], - "Add another partition or mount an existing one": [ - "დაამატეთ კიდევ ერთი დანაყოფი ან მიამაგრეთ არსებული" - ], "Add device menu": [ "მოწყობილობის მენიუს დამატება" ], @@ -327,9 +330,6 @@ export default { "Change Language": [ "ენის შეცვლა" ], - "Change boot options": [ - "ჩატვირთვის პარამეტრების შეცვლა" - ], "Change device menu": [ "მოწყობილობის მენიუს შეცვლა" ], @@ -354,15 +354,27 @@ export default { "Change selection": [ "მონიშნულის შეცვლა" ], + "Change the disk to configure": [ + "შეცვალეთ დისკი მოსარგებად" + ], + "Change the disk to create %s": [ + "შეცვალეთ დისკი %s-ის შესაქმნელად" + ], + "Change the disk to format as %s": [ + "დისკის შეცვლა, რომ დაფორმატდეს, როგორც %s" + ], + "Change the disk to install the system": [ + "შეცვალეთ დისკი სისტემის დასაყენებლად" + ], "Change the file system or mount point": [ "ფილური სისტემის ან მიმაგრების წერტილის შეცვლა" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "ამ პარამეტრის შეცვლა დაუყოვნებლივ განაახლებს ქვემორე სექციას 'შედეგი'." + ], "Channel ID": [ "არხის ID" ], - "Check the %d planned actions": [ - "%d დაგეგმილი ქმედების შემოწმება" - ], "Check the authentication parameters.": [ "შეამოწმეთ ავთენტიკაციის პარამეტრები." ], @@ -396,9 +408,6 @@ export default { "Close": [ "დახურვა" ], - "Collapse the list of planned actions": [ - "დაგეგმილი ქმედებების ჩამოშლა" - ], "Configuration out of sync": [ "კონფიგურაციის სინქრონიზაცია დარღვეულია" ], @@ -609,9 +618,6 @@ export default { "Details": [ "დეტალები" ], - "Details for %s": [ - "%s-ის დეტალები" - ], "Details will appear after the connection is successfully established.": [ "დეტალები გამოჩნდება კავშირის წარმატებულად დამყარების შემდეგ." ], @@ -666,9 +672,6 @@ export default { "Download logs": [ "ჟურნალის გადმოწერა" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "" - ], "Edit": [ "ჩასწორება" ], @@ -732,8 +735,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "მაგ: https://ჩემისერვერი.ცომ" + "Example: %s": [ + "მაგ: %s" ], "Excellent signal": [ "ძალიან კარგი სიგნალი" @@ -751,12 +754,12 @@ export default { "Ext4" ], "Extend the installation beyond the currently selected device": [ - "", - "" + "დაყენების გაფართოება ამჟამად არჩეული მოწყობილობის მიღმა", + "დაყენების გაფართოება ამჟამად არჩეული %d მოწყობილობის მიღმა" ], "Extend the installation beyond the currently selected disk": [ - "", - "" + "დაყენების გაფართოება ამჟამად არჩეული დისკის მიღმა", + "დაყენების გაფართოება ამჟამად არჩეული %d დისკის მიღმა" ], "Extensions": [ "გაფართოებები" @@ -791,8 +794,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "გაფილტვრა ტერიტორიით, დროის სარტყლით, ან UTC წანაცვლებით" ], - "Find space": [ - "ადგილის პოვნა" + "Final layout": [ + "საბოლოო განლაგება" + ], + "Final structure of the system after installation.": [ + "სისტემის საბოლოო სტრუქტურა დაყენების შემდეგ." ], "Find space in %s": [ "ადგილის პოვნა %s-ში" @@ -918,6 +924,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "" ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "მიმდინარეობს" ], @@ -978,7 +987,7 @@ export default { "Install using several devices without modifying existing partitions.": [ "დაყენება რამდენიმე მოწყობილობის გამოყენებით არსებული დანაყოფების შეცვლის გარეშე." ], - "Installation Devices": [ + "Installation devices": [ "დაყენების მოწყობილობები" ], "Installation will take %s.": [ @@ -1158,6 +1167,9 @@ export default { "More languages might be available for the selected product at [Localization] page": [ "მეტი ენა, შეიძლება, [Localization]-ის გვერდზე იყოს ხელმისაწვდომი" ], + "More storage options": [ + "საცავის მეტი პარამეტრი" + ], "Moreover, the following partition will be created.": [ "კიდევ შეიქმნება შემდეგი დანაყოფი.", "კიდევ შეიქმნება შემდეგი დანაყოფები." @@ -1271,6 +1283,9 @@ export default { "No logical volumes are defined yet": [ "ლოგიკური ტომები ჯერ აღწერილი არაა" ], + "No partitions will be automatically configured for booting.": [ + "ჩასატვირთად დანაყოფების ავტომატური მორგება არ მოხდება." + ], "No partitions will be automatically configured for booting. Use with caution.": [ "ჩასატვირთად დანაყოფების ავტომატური მორგება არ მოხდება. ფრთხილად გამოიყენეთ." ], @@ -1343,24 +1358,27 @@ export default { "Only reused partitions will be used.": [ "გამოყენებული იქნება, მხოლოდ, თავიდან გამოყენებული დანაყოფები." ], + "Options for partition %s": [ + "პარამეტრები დანაყოფისთვის %s" + ], "Options toggle": [ "პარამეტრის გადართვა" ], - "Other options": [ - "სხვა პარამეტრები" - ], - "Other options toggle": [ - "სხვა პარამეტრის გადართვა" - ], "Overview": [ "გადახედვა" ], "Package installation failed": [ "პაკეტის დაყენება ჩავარდა" ], + "Partition %s": [ + "დანაყოფი %s" + ], "Partition Info": [ "დანაყოფის ინფორმაცია" ], + "Partitions": [ + "დანაყოფები" + ], "Partitions needed for booting will also be adapted": [ "ასევე მოხდება ჩასატვირთად საჭირო დანაყოფების მორგება" ], @@ -1376,14 +1394,26 @@ export default { "Partitions that are not reused would be resized if needed.": [ "დანაყოფები, რომლებიც თავიდან არ გამოიყენება, შეიძლება, ზომა საჭიროებისამებრ შეეცვალოს." ], - "Partitions to boot will be allocated at the following device.": [ - "ჩატვირთვადი დანაყოფები გამოიყოფა შემდეგი მოწყობილობიდან." + "Partitions to boot will be set up if needed at %s.": [ + "ჩატვირთვადი დანაყოფები დაყენების დისკზე(%s )გამოიყოფა." + ], + "Partitions to boot will be set up if needed at the following device.": [ + "ჩატვირთვადი დანაყოფები გამოიყოფა საჭიროებისამებრ შემდეგი მოწყობილობიდან." ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "ჩატვირთვადი დანაყოფები გამოიყოფა დაყენების დისკზე %s." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "ჩატვირთვადი დანაყოფები გამოიყოფა დაყენების დისკზე იმაზე დამოკიდებულებით, თუ სად იქნება მოთავსებული ფაილური სისტემა %s." ], - "Partitions to boot will be allocated at the installation disk.": [ - "ჩატვირთვადი დანაყოფები დაყენების დისკზე გამოიყოფა." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "ჩატვირთვადი დანაყოფები მორგებული იქნება საჭიროებისამებრ დაყენების დისკზე იმაზე დამოკიდებულებით, თუ სად იქნება ფაილური სისტემა %s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" + ], + "Partitions to host \"system\" will be created if needed.": [ + "დანაყოფები \"სისტემისთვის\" საჭიროებისამებრ შეიქმნება." ], "Partitions will be used and created for %s": [ "დანაყოფები, რომლებიც გამოყენებული და შექმნილი იქნება '%s'-სთვის" @@ -1448,7 +1478,7 @@ export default { "Product is already registered": [ "პროდუქტი უკვე რეგისტრირებულია" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ + "Protection for the information stored at the new file systems, including data, programs, and system files.": [ "" ], "Provide email address": [ @@ -1538,6 +1568,9 @@ export default { "Result": [ "შედეგი" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "შედეგი იმ პარამეტრების გადატარებისა, რომლებიც აღწერილია ზემორე სექციაში 'მორგება'." + ], "Reused partitions will not be shrunk": [ "თავიდან გამოყენებული დანაყოფების დაპატარავება შეუძლებელია" ], @@ -1598,21 +1631,9 @@ export default { "Select a disk": [ "აირჩიეთ დისკი" ], - "Select a disk to configure": [ - "აირჩიეთ დისკი მოსარგებად" - ], - "Select a disk to create %s": [ - "აირჩიეთ დისკი %s-ის შესაქმნელად" - ], "Select a disk to define partitions or to mount": [ "აირჩიეთ დისკი დანაყოფების აღწერისთვის, ან მიმაგრებისთვის" ], - "Select a disk to format as %s": [ - "აირჩიეთ დისკი, რომელიც დაფორმატდება, როგორც %s" - ], - "Select a disk to install the system": [ - "აირჩიეთ დისკი სისტემის დასაყენებლად" - ], "Select a product": [ "აირჩიეთ პროდუქტი" ], @@ -1640,9 +1661,6 @@ export default { "Select or enter a valid mount point": [ "აირჩიეთ, ან შეიყვანეთ სწორი მიმაგრების წერტილი" ], - "Select the disk to configure partitions for booting": [ - "აირჩიეთ დისკი ჩატვირთვადი დანაყოფების მოსარგებად" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "" ], @@ -1880,6 +1898,9 @@ export default { "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ "" ], + "The following actions will be performed in the system during installation.": [ + "დაყენებისას სისტემაში მოხდება შემდეგი ცვლილებები." + ], "The following logical volume will be created": [ "შეიქმნება შემდეგი ლოგიკური ტომი", "შეიქმნება შემდეგი ლოგიკური ტომები" @@ -1947,6 +1968,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "" ], + "The product will be registered with \"%s\" hostname": [ + "პროდუქტი დარეგისტრირდება ჰოსტის სახელით \"%s\"" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "" ], @@ -2015,8 +2039,8 @@ export default { "დაგეგმილია %d გამანადგურებელი ქმედება" ], "There is %d destructive action planned affecting %s": [ - "", - "" + "დაგეგმილია %d დამანგრეველი ქმედება, რომელიც ეხება %s-ს", + "დაგეგმილია %d დამანგრეველი ქმედება რომელიც ეხება %s-ს" ], "These are the most relevant installation settings. Feel free to browse the sections in the menu for further details.": [ "ეს ყველაზე ხშირად არჩეული დაყენების პარამეტრებია. ნუ შეშინდებით, დაათვალიეროთ მენიუს სექციები დამატებითი დეტალებისთვის." @@ -2075,6 +2099,9 @@ export default { "Tmpfs": [ "Tmpfs" ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "" + ], "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ "" ], @@ -2264,6 +2291,9 @@ export default { "Using transient hostname: %s": [ "გამოიყენება გარდამავლი ჰოსტის სახელი: %s" ], + "Volume group %s": [ + "ტომების ჯგუფი %s" + ], "Volume group '%s' already exists. Enter a different name.": [ "ტომების ჯგუფი '%s' უკვე არსებობს. შეიყვანეთ განსხვავებული სახელი." ], diff --git a/web/src/po/po.pt-BR.js b/web/src/po/po.pt-BR.js index 2b46d3041f..efeb354bf5 100644 --- a/web/src/po/po.pt-BR.js +++ b/web/src/po/po.pt-BR.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Seleção de fuso horário" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -139,9 +145,6 @@ export default { "Add another address": [ "Adicionar outro endereço" ], - "Add another partition or mount an existing one": [ - "Adicionar outra partição ou montar uma nova" - ], "Add device menu": [ "Adicionar menu do dispositivo" ], @@ -327,9 +330,6 @@ export default { "Change Language": [ "Alterar idioma" ], - "Change boot options": [ - "Alterar opções de inicialização" - ], "Change device menu": [ "Alterar menu do dispositivo" ], @@ -357,12 +357,12 @@ export default { "Change the file system or mount point": [ "Alterar o sistema de arquivos ou ponto de montagem" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "ID do canal" ], - "Check the %d planned actions": [ - "Verificar as %d ações planejadas" - ], "Check the authentication parameters.": [ "Verifique os parâmetros de autenticação." ], @@ -396,9 +396,6 @@ export default { "Close": [ "Fechar" ], - "Collapse the list of planned actions": [ - "Recolher a lista de ações planejadas" - ], "Configuration out of sync": [ "Configuração fora de sincronia" ], @@ -609,9 +606,6 @@ export default { "Details": [ "Detalhes" ], - "Details for %s": [ - "Detalhes de %s" - ], "Details will appear after the connection is successfully established.": [ "Os detalhes aparecerão depois que conexão for estabelecida com êxito." ], @@ -666,9 +660,6 @@ export default { "Download logs": [ "Baixar logs" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Durante a instalação, várias ações serão executadas para configurar o layout mostrado na tabela abaixo." - ], "Edit": [ "Editar" ], @@ -732,8 +723,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Exemplo: https://meuservidor.com" + "Example: %s": [ + "Exemplo: %s" ], "Excellent signal": [ "Sinal excelente" @@ -791,8 +782,8 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Filtrar por território, código de fuso horário ou deslocamento UTC" ], - "Find space": [ - "Encontrar espaço" + "Final layout": [ + "Layout final" ], "Find space in %s": [ "Encontrar espaço em %s" @@ -918,6 +909,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Se você continuar, as partições do seu disco rígido serão modificadas de acordo com as configurações de instalação fornecidas." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "Em progresso" ], @@ -978,9 +972,6 @@ export default { "Install using several devices without modifying existing partitions.": [ "Instale usando vários dispositivos sem modificar as partições existentes." ], - "Installation Devices": [ - "Dispositivo de instalação" - ], "Installation will take %s.": [ "A instalação levará %s." ], @@ -1346,12 +1337,6 @@ export default { "Options toggle": [ "Alternar opções" ], - "Other options": [ - "Outras opções" - ], - "Other options toggle": [ - "Alternância para outras opções" - ], "Overview": [ "Visão geral" ], @@ -1361,6 +1346,9 @@ export default { "Partition Info": [ "Informação da partição" ], + "Partitions": [ + "Partições" + ], "Partitions needed for booting will also be adapted": [ "As partições necessárias para inicialização também serão adaptadas" ], @@ -1376,14 +1364,11 @@ export default { "Partitions that are not reused would be resized if needed.": [ "As partições não reutilizadas serão redimensionadas se necessário." ], - "Partitions to boot will be allocated at the following device.": [ - "As partições para inicialização serão alocadas no seguinte dispositivo." - ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "As partições para inicialização serão alocadas no disco de instalação %s." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], - "Partitions to boot will be allocated at the installation disk.": [ - "As partições para inicialização serão alocadas no disco de instalação." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], "Partitions will be used and created for %s": [ "Partições serão usadas e criadas para %s" @@ -1448,9 +1433,6 @@ export default { "Product is already registered": [ "Produto já registrado" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Proteção para as informações armazenadas nos novos sistemas de arquivos, incluindo dados, programas e arquivos de sistema." - ], "Provide email address": [ "Inserir endereço de e-mail" ], @@ -1538,6 +1520,9 @@ export default { "Result": [ "Resultado" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "As partições reutilizadas serão reduzidas" ], @@ -1598,21 +1583,9 @@ export default { "Select a disk": [ "Selecionar um disco" ], - "Select a disk to configure": [ - "Selecionar um disco para configurar" - ], - "Select a disk to create %s": [ - "Selecionar um disco para criar %s" - ], "Select a disk to define partitions or to mount": [ "Selecionar um disco para definir as partições ou para montar" ], - "Select a disk to format as %s": [ - "Selecionar um disco para formatar como %s" - ], - "Select a disk to install the system": [ - "Selecionar um disco para instalar o sistema" - ], "Select a product": [ "Selecione um produto" ], @@ -1640,9 +1613,6 @@ export default { "Select or enter a valid mount point": [ "Selecionar ou inserir um ponto de montagem válido" ], - "Select the disk to configure partitions for booting": [ - "Selecionar o disco para configurar partições para inicialização" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Selecione o que fazer com cada partição para encontrar espaço para alocar o novo sistema." ], @@ -1947,6 +1917,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "A senha não será necessária para inicializar e acessar os dados se o TPM puder verificar a integridade do sistema. A vedação do TPM exige que o novo sistema seja inicializado diretamente em sua primeira execução." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "O tamanho para %1$s será ajustado dinamicamente com base na quantidade de RAM no sistema e na presença de um sistema de arquivos separado para %2$s." ], diff --git a/web/src/po/po.ru.js b/web/src/po/po.ru.js index b68e34546a..d2e416129d 100644 --- a/web/src/po/po.ru.js +++ b/web/src/po/po.ru.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Выбор часового пояса" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -143,9 +149,6 @@ export default { "Add another address": [ "Добавить другой адрес" ], - "Add another partition or mount an existing one": [ - "Добавьте еще один раздел или смонтируйте существующий" - ], "Add device menu": [ "Меню добавления устройств" ], @@ -333,9 +336,6 @@ export default { "Change Language": [ "Изменить язык" ], - "Change boot options": [ - "Изменение параметров загрузки" - ], "Change device menu": [ "Меню изменения устройства" ], @@ -360,15 +360,27 @@ export default { "Change selection": [ "Изменить выбор" ], + "Change the disk to configure": [ + "Измените диск для настройки" + ], + "Change the disk to create %s": [ + "Измените диск для создания %s" + ], + "Change the disk to format as %s": [ + "Измените диск для форматирования как %s" + ], + "Change the disk to install the system": [ + "Измените диск для установки системы" + ], "Change the file system or mount point": [ "Изменить файловую систему или точку монтирования" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "Изменения этих настроек немедленно обновят секцию «Результат» ниже." + ], "Channel ID": [ "Идентификатор канала" ], - "Check the %d planned actions": [ - "Показать запланированные действия: %d" - ], "Check the authentication parameters.": [ "Проверьте параметры аутентификации." ], @@ -402,9 +414,6 @@ export default { "Close": [ "Закрыть" ], - "Collapse the list of planned actions": [ - "Свернуть список запланированных действий" - ], "Configuration out of sync": [ "Конфигурация рассинхронизирована" ], @@ -613,10 +622,7 @@ export default { "Уничтожить текущие данные и отформатировать раздел как" ], "Details": [ - "Подробности" - ], - "Details for %s": [ - "Сведения для %s" + "Сведения" ], "Details will appear after the connection is successfully established.": [ "После успешной установки подключения появится подробная информация." @@ -672,9 +678,6 @@ export default { "Download logs": [ "Скачать журналы" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "В процессе установки будут произведены действия для создания структуры разделов, указанной в таблице ниже." - ], "Edit": [ "Изменить" ], @@ -738,8 +741,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Пример: https://myserver.com" + "Example: %s": [ + "Пример: %s" ], "Excellent signal": [ "Отличный сигнал" @@ -799,8 +802,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Фильтр по территории, коду часового пояса или смещению UTC" ], - "Find space": [ - "Найти пространство" + "Final layout": [ + "Окончательный вариант" + ], + "Final structure of the system after installation.": [ + "Окончательная структура системы после установки." ], "Find space in %s": [ "Найти пространство в %s" @@ -886,7 +892,7 @@ export default { "Скрыть %d действий подтома" ], "Hide details": [ - "Скрыть подробности" + "Скрыть сведения" ], "Hostname": [ "Имя узла" @@ -927,6 +933,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Если продолжите, разделы на жестком диске будут изменены в соответствии с заданными настройками установки." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "В процессе" ], @@ -987,7 +996,7 @@ export default { "Install using several devices without modifying existing partitions.": [ "Установка с использованием нескольких устройств без изменения существующих разделов." ], - "Installation Devices": [ + "Installation devices": [ "Устройства для установки" ], "Installation will take %s.": [ @@ -1167,6 +1176,9 @@ export default { "More languages might be available for the selected product at [Localization] page": [ "Для выбранного продукта могут быть доступны другие языки в разделе [Локализации]" ], + "More storage options": [ + "Дополнительные параметры хранилища" + ], "Moreover, the following partition will be created.": [ "Кроме того, будет создан следующий раздел.", "Кроме того, будут созданы следующие разделы.", @@ -1282,6 +1294,9 @@ export default { "No logical volumes are defined yet": [ "Логические тома еще не определены" ], + "No partitions will be automatically configured for booting.": [ + "Ни один раздел не будет автоматически настроен для загрузки." + ], "No partitions will be automatically configured for booting. Use with caution.": [ "Ни один раздел не будет автоматически настроен для загрузки. Используйте с осторожностью." ], @@ -1354,24 +1369,27 @@ export default { "Only reused partitions will be used.": [ "Будут использоваться только повторно используемые разделы." ], + "Options for partition %s": [ + "Параметры для раздела %s" + ], "Options toggle": [ "Показ настроек" ], - "Other options": [ - "Другие опции" - ], - "Other options toggle": [ - "Показ других опций" - ], "Overview": [ "Обзор" ], "Package installation failed": [ "Не удалось установить пакет" ], + "Partition %s": [ + "Раздел %s" + ], "Partition Info": [ "Информация о разделе" ], + "Partitions": [ + "Разделы" + ], "Partitions needed for booting will also be adapted": [ "Разделы, необходимые для загрузки, также будут адаптированы" ], @@ -1387,14 +1405,23 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Разделы, которые не используются повторно, при необходимости будут изменены в размерах." ], - "Partitions to boot will be allocated at the following device.": [ - "Загрузочные разделы будут выделены на следующем устройстве." + "Partitions to boot will be set up if needed at %s.": [ + "Разделы для загрузки будут настроены при необходимости на %s." + ], + "Partitions to boot will be set up if needed at the following device.": [ + "При необходимости разделы для загрузки будут созданы на следующем устройстве." ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Загрузочные разделы будут выделены на установочном диске %s." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "При необходимости на установочном диске будут созданы разделы для загрузки в зависимости от расположения файловой системы %s." ], - "Partitions to boot will be allocated at the installation disk.": [ - "Загрузочные разделы будут выделены на установочном диске." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Разделы для загрузки будут настроены при необходимости на установочном диске, исходя из расположения файловой системы %s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "При необходимости на установочном диске будут созданы загрузочные разделы. В настоящее время это %1$s, в зависимости от расположения файловой системы %2$s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Разделы для загрузки будут настроены при необходимости на установочном диске. В настоящее время %1$s, исходя из расположения файловой системы %2$s." ], "Partitions will be used and created for %s": [ "Разделы будут использоваться и создаваться для %s" @@ -1459,7 +1486,7 @@ export default { "Product is already registered": [ "Продукт уже зарегистрирован" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ + "Protection for the information stored at the new file systems, including data, programs, and system files.": [ "Защита информации, хранящейся в новых файловых системах, включая данные, программы и системные файлы." ], "Provide email address": [ @@ -1549,6 +1576,9 @@ export default { "Result": [ "Результат" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "Результат применения конфигурации, описанной в секции «Настройки» выше." + ], "Reused partitions will not be shrunk": [ "Повторно используемые разделы не будут уменьшены" ], @@ -1609,21 +1639,9 @@ export default { "Select a disk": [ "Выберите диск" ], - "Select a disk to configure": [ - "Выберите диск для настройки" - ], - "Select a disk to create %s": [ - "Выберите диск для создания %s" - ], "Select a disk to define partitions or to mount": [ "Выберите диск для определения разделов или монтирования" ], - "Select a disk to format as %s": [ - "Выберите диск для форматирования как %s" - ], - "Select a disk to install the system": [ - "Выберите диск для установки системы" - ], "Select a product": [ "Выберите продукт" ], @@ -1651,9 +1669,6 @@ export default { "Select or enter a valid mount point": [ "Выберите или введите правильную точку монтирования" ], - "Select the disk to configure partitions for booting": [ - "Выберите диск для настройки разделов для загрузки" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Выберите, что нужно сделать с каждым разделом, чтобы найти место для размещения новой системы." ], @@ -1894,6 +1909,9 @@ export default { "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ "Последний шаг по настройке Доверенного платформенного модуля (TPM) на автоматическое открытие зашифрованных устройств будет выполнен во время первой загрузки новой системы. Чтобы это сработало, машина должна загрузиться непосредственно в новый загрузчик." ], + "The following actions will be performed in the system during installation.": [ + "В процессе установки в системе будут выполнены следующие действия." + ], "The following logical volume will be created": [ "Будет создан следующий логический том", "Будут созданы следующие логические тома", @@ -1965,6 +1983,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "Пароль не понадобится для загрузки и доступа к данным, если TPM может проверить целостность системы. Запечатывание TPM требует непосредственной загрузки новой системы при первом запуске." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "Размер для %1$s будет динамически корректироваться в зависимости от объема оперативной памяти в системе и наличия отдельной файловой системы для %2$s." ], @@ -2095,6 +2116,9 @@ export default { "Tmpfs": [ "Tmpfs" ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "Чтобы обеспечить загрузку новой системы, программе установки может потребоваться создать или настроить некоторые разделы на соответствующем диске." + ], "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ "Чтобы обеспечить загрузку новой системы, программе установки может потребоваться создать или настроить некоторые разделы на соответствующем диске." ], @@ -2284,6 +2308,9 @@ export default { "Using transient hostname: %s": [ "Использование переходного имени узла: %s" ], + "Volume group %s": [ + "Группа томов %s" + ], "Volume group '%s' already exists. Enter a different name.": [ "Группа томов „%s“ уже существует. Введите другое имя." ], diff --git a/web/src/po/po.sv.js b/web/src/po/po.sv.js index 2ac3787ccb..330bf6b843 100644 --- a/web/src/po/po.sv.js +++ b/web/src/po/po.sv.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Tidszon val" ], + "\"%s\"": [ + "\"%s\"" + ], + "\"%s\" does not exist or is no longer available.": [ + "\"%s\" existrerar inte eller är inte längre tillgänglig." + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -139,9 +145,6 @@ export default { "Add another address": [ "Lägg till en annan adress" ], - "Add another partition or mount an existing one": [ - "Lägg till ytterligare en partition eller montera en befintlig" - ], "Add device menu": [ "Lägg till enhetsmeny" ], @@ -327,9 +330,6 @@ export default { "Change Language": [ "Ändra språk" ], - "Change boot options": [ - "Ändra uppstartsalternativ" - ], "Change device menu": [ "Ändra enhetsmeny" ], @@ -354,15 +354,27 @@ export default { "Change selection": [ "Ändra val" ], + "Change the disk to configure": [ + "Ändra disken som ska konfigureras" + ], + "Change the disk to create %s": [ + "Ändra disk för att skapa %s" + ], + "Change the disk to format as %s": [ + "Ändra disken till att formateras som %s" + ], + "Change the disk to install the system": [ + "Ändra disk för att installera systemet" + ], "Change the file system or mount point": [ "Ändra filsystemet eller monteringspunkten" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "Ändringar i dessa inställningar kommer omedelbart att uppdatera avsnittet \"Resultat\" nedan." + ], "Channel ID": [ "Kanal-ID" ], - "Check the %d planned actions": [ - "Kontrollera det %d planerade åtgärderna" - ], "Check the authentication parameters.": [ "Kontrollera autentiseringsparametrarna." ], @@ -396,9 +408,6 @@ export default { "Close": [ "Stäng" ], - "Collapse the list of planned actions": [ - "Dölj listan över planerade åtgärder" - ], "Configuration out of sync": [ "Konfigurationen är inte synkroniserad" ], @@ -609,9 +618,6 @@ export default { "Details": [ "Detaljer" ], - "Details for %s": [ - "Detaljer för %s" - ], "Details will appear after the connection is successfully established.": [ "Detaljer kommer att visas efter att anslutningen har upprättats." ], @@ -666,9 +672,6 @@ export default { "Download logs": [ "Ladda ner loggar" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Under installationen kommer flera åtgärder att utföras för att ställa in layouten som visas i tabellen nedan." - ], "Edit": [ "Redigera" ], @@ -732,8 +735,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Exempel: https://minserver.com" + "Example: %s": [ + "Exempel: %s" ], "Excellent signal": [ "Utmärkt signal" @@ -791,8 +794,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Filtrera efter område, tidszonskod eller UTC-förskjutning" ], - "Find space": [ - "Hitta utrymme" + "Final layout": [ + "Slutgiltig layout" + ], + "Final structure of the system after installation.": [ + "Systemets slutgiltiga struktur efter installation." ], "Find space in %s": [ "Hitta utrymme på %s" @@ -918,6 +924,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Om du fortsätter kommer partitionerna på din hårddisk att modifieras enligt de medföljande installationsinställningarna." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "Om du vill inaktivera den här kontrollen, ange \"inst.ay_check=0\" för kärnans kommandorad" + ], "In progress": [ "Pågår" ], @@ -978,8 +987,8 @@ export default { "Install using several devices without modifying existing partitions.": [ "Installera med flera enheter utan att ändra befintliga partitioner." ], - "Installation Devices": [ - "Installationsenheter" + "Installation devices": [ + "Installations enheter" ], "Installation will take %s.": [ "Installationen kommer att ta %s." @@ -1158,6 +1167,9 @@ export default { "More languages might be available for the selected product at [Localization] page": [ "Fler språk kan vara tillgängliga för den valda produkten på [Lokalisering] sidan" ], + "More storage options": [ + "Mer lagringsalternativ" + ], "Moreover, the following partition will be created.": [ "Dessutom kommer följande partition att skapas.", "Dessutom kommer följande partitioner att skapas." @@ -1271,6 +1283,9 @@ export default { "No logical volumes are defined yet": [ "Inga logiska volymer är definierade ännu" ], + "No partitions will be automatically configured for booting.": [ + "Inga partitioner kommer att konfigureras automatiskt för uppstart." + ], "No partitions will be automatically configured for booting. Use with caution.": [ "Inga partitioner kommer att konfigureras automatiskt för uppstart. Använd med försiktighet." ], @@ -1343,24 +1358,27 @@ export default { "Only reused partitions will be used.": [ "Endast återanvända partitioner kommer att användas." ], + "Options for partition %s": [ + "Alternativ för partition %s" + ], "Options toggle": [ "Växla mellan alternativ" ], - "Other options": [ - "Andra alternativ" - ], - "Other options toggle": [ - "Andra alternativ växel" - ], "Overview": [ "Översikt" ], "Package installation failed": [ "Paket installation misslyckades" ], + "Partition %s": [ + "Partition %s" + ], "Partition Info": [ "Partitionsinformation" ], + "Partitions": [ + "Partitioner" + ], "Partitions needed for booting will also be adapted": [ "Partitioner som behövs för uppstart kommer också att anpassas" ], @@ -1376,14 +1394,26 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Partitioner som inte återanvänds kan ändras i storlek vid behov." ], - "Partitions to boot will be allocated at the following device.": [ - "Partitioner för att uppstart kommer att tilldelas på följande enhet." + "Partitions to boot will be set up if needed at %s.": [ + "Partitioner att starta kommer att konfigureras vid behov på %s." + ], + "Partitions to boot will be set up if needed at the following device.": [ + "Partitioner att starta från kommer att konfigureras om det behövs på följande enhet." ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Partitioner att starta kommer att allokeras på installationsdisken %s." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Partitioner att starta från kommer att konfigureras vid behov på installationsdisken, baserat på platsen för filsystemet %s." ], - "Partitions to boot will be allocated at the installation disk.": [ - "Partitioner som ska startas upp kommer att tilldelas på installationsdisken." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Partitioner att starta från kommer att konfigureras vid behov på installationsdisken, baserat på platsen för filsystemet %s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Partitioner att starta från kommer att konfigureras vid behov på installationsdisken. För närvarande %1$s, baserat på platsen för filsystemet %2$s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Partitioner att starta från kommer att konfigureras vid behov på installationsdisken. För närvarande %1$s, baserat på platsen för filsystemet %2$s." + ], + "Partitions to host \"system\" will be created if needed.": [ + "Partitioner för att vara värd för \"systemet\" kommer att skapas vid behov." ], "Partitions will be used and created for %s": [ "Partitioner kommer att användas och skapas för %s" @@ -1448,7 +1478,7 @@ export default { "Product is already registered": [ "Produkten är redan registrerad" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ + "Protection for the information stored at the new file systems, including data, programs, and system files.": [ "Skydd för informationen som lagras i de nya filsystemen, inklusive data, program och systemfiler." ], "Provide email address": [ @@ -1538,6 +1568,9 @@ export default { "Result": [ "Resultat" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "Resultat av att tillämpa konfigurationen som beskrivs i avsnittet \"Inställningar\" ovan." + ], "Reused partitions will not be shrunk": [ "Återanvända partitioner kommer inte att krympas" ], @@ -1598,21 +1631,9 @@ export default { "Select a disk": [ "Välj en disk" ], - "Select a disk to configure": [ - "Välj en disk att konfigurera" - ], - "Select a disk to create %s": [ - "Välj en disk för att skapa %s" - ], "Select a disk to define partitions or to mount": [ "Välj en disk för att definiera partitioner eller för att montera" ], - "Select a disk to format as %s": [ - "Välj en disk att formatera som %s" - ], - "Select a disk to install the system": [ - "Välj en disk för att installera systemet" - ], "Select a product": [ "Välj en produkt" ], @@ -1640,9 +1661,6 @@ export default { "Select or enter a valid mount point": [ "Välj eller ange en giltig monteringspunkt" ], - "Select the disk to configure partitions for booting": [ - "Välj disk för att konfigurera partitionerna för uppstart" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Välj vad som ska göras med varje partition för att hitta utrymme för att allokera det nya systemet." ], @@ -1880,6 +1898,9 @@ export default { "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ "Det sista steget för att konfigurera Trusted Platform Module (TPM) för att automatiskt öppna krypterade enheter kommer att ske under den första uppstarten av det nya systemet. För att det ska fungera måste maskinen startas direkt till den nya uppstartshanteraren." ], + "The following actions will be performed in the system during installation.": [ + "Följande åtgärder kommer att utföras i systemet under installationen." + ], "The following logical volume will be created": [ "Följande logiska volym kommer att skapas", "Följande logiska volymer kommer också att skapas" @@ -1947,6 +1968,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "Lösenordet kommer inte att behövas för att starta och komma åt data om TPM kan verifiera systemets integritet. TPM-försegling kräver att det nya systemet startas upp direkt vid första körningen." ], + "The product will be registered with \"%s\" hostname": [ + "Produkten kommer att registreras med \"%s\" värdnamn" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "Storleken för %1$s kommer att justeras dynamiskt baserat på mängden RAM i systemet och förekomsten av ett separat filsystem för %2$s." ], @@ -2075,6 +2099,9 @@ export default { "Tmpfs": [ "Tmpfs" ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "För att säkerställa att det nya systemet kan starta kan installationsprogrammet behöva skapa eller konfigurera några partitioner på lämplig disk." + ], "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ "För att säkerställa att det nya systemet kan starta kan installationsprogrammet behöva skapa eller konfigurera vissa partitioner på lämplig disk." ], @@ -2264,6 +2291,9 @@ export default { "Using transient hostname: %s": [ "Använder transient värdnamn: %s" ], + "Volume group %s": [ + "Volymgrupp %s" + ], "Volume group '%s' already exists. Enter a different name.": [ "Volymgrupp '%s' existerar redan. Ange ett annat namn." ], diff --git a/web/src/po/po.tr.js b/web/src/po/po.tr.js index f210961a9f..298aef090e 100644 --- a/web/src/po/po.tr.js +++ b/web/src/po/po.tr.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Zaman dilimi seçimi" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -15,6 +21,10 @@ export default { "%1$s at %2$s": [ "%1$s %2$s'de" ], + "%1$s will be created as a partition at %2$s": [ + "%1$s bölümü (%2$s) olarak oluşturulacak", + "%1$s bölümleri (%2$s) olarak oluşturulacak" + ], "%1$s will still contain the LVM group '%2$s' and any partition needed to boot": [ "%1$s hala '%2$s' LVM grubunu ve önyükleme için gereken herhangi bir bölümü içerecektir" ], @@ -40,8 +50,8 @@ export default { "%s logosu" ], "%s will be created as a logical volume": [ - "", - "" + "%s mantıksal bir birim olarak oluşturulacak", + "%s mantıksal bir birimler olarak oluşturulacak" ], "%s will still contain the configured LVM groups and any partition needed to boot": [ "%s hala yapılandırılmış LVM gruplarını ve önyükleme için gereken tüm bölümleri içerecektir" @@ -70,6 +80,14 @@ export default { "A generic size range between %1$s and %2$s will be used for the new %3$s": [ "Yeni %3$s için %1$s ile %2$s arasında genel bir boyut aralığı kullanılacak" ], + "A new partition will be created for %s": [ + "Yeni bölüm %s için oluşturulacak", + "Yeni bölümler %s için oluşturulacak" + ], + "A new volume will be created for %s": [ + "Yeni bir birim %s için oluşturulacak", + "Yeni birimler %s için oluşturulacak" + ], "A partition may be deleted": [ "Bir bölüm silinebilir" ], @@ -92,7 +110,7 @@ export default { "Etkinleştir" ], "Activate and format DASD devices": [ - "DASD cihazlarını etkinleştirin ve biçimlendirin" + "DASD aygıtlarını etkinleştir ve biçimlendir" ], "Activate new disk": [ "Yeni diski etkinleştir" @@ -127,9 +145,6 @@ export default { "Add another address": [ "Başka Bir Adres Ekle" ], - "Add another partition or mount an existing one": [ - "Başka bir bölüm ekleyin veya mevcut bir bölümü bağlayın" - ], "Add device menu": [ "Cihaz menüsü ekle" ], @@ -173,11 +188,15 @@ export default { "İlk kullanıcıyı tanımlamanın yanı sıra, root kullanıcı için kimlik doğrulama yöntemleri de yapılandırılabilir." ], "Already using all available devices": [ - "Zaten mevcut tüm cihazları kullanılıyor" + "Zaten uygun tüm aygıtlar kullanılıyor" ], "Already using all available disks": [ "Zaten tüm kullanılabilir diskler kullanılıyor" ], + "An existing partition will be used for %s": [ + "Mevcut bölüm %s için kullanılacak", + "Mevcut bölümler %s için kullanılacak" + ], "Any existing partition will be removed and all data in the disk will be lost.": [ "Mevcut herhangi bir bölüm kaldırılacak ve diskteki tüm veriler kaybolacaktır." ], @@ -187,6 +206,10 @@ export default { "Apply selected solution": [ "Seçilen çözümü uygula" ], + "Apply to the selected device": [ + "Seçili cihaz biçimlendirilsin mi?", + "Seçili %s aygıt biçimlendirilsin mi?" + ], "Applying changes": [ "Değişiklikleri uygula" ], @@ -215,13 +238,13 @@ export default { "Hedefe göre kimlik doğrulama" ], "Auto LUNs Scan": [ - "Otomatik LUN Taraması" + "Kendiliğinden LUN Taraması" ], "Automatic": [ - "Otomatik" + "Kendiliğinden" ], "Automatic (DHCP)": [ - "Otomatik (DHCP)" + "Kendiliğinden (DHCP)" ], "Automatic LUN scan is [disabled]. LUNs have to be manually configured after activating a controller.": [ "Otomatik LUN taraması [devre dışı]. LUN'ların manuel olarak taranması gerekir Bir kontrol cihazı etkinleştirildikten sonra yapılandırılır." @@ -307,9 +330,6 @@ export default { "Change Language": [ "Dili değiştir" ], - "Change boot options": [ - "Önyükleme seçeneklerini değiştir" - ], "Change device menu": [ "Cihaz menüsünü değiştir" ], @@ -337,12 +357,12 @@ export default { "Change the file system or mount point": [ "Dosya sistemini veya bağlama noktasını değiştirin" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "Kanal Kimliği" ], - "Check the %d planned actions": [ - "%d planlanan eylemi kontrol edin" - ], "Check the authentication parameters.": [ "Kimlik doğrulama parametrelerini kontrol edin." ], @@ -350,7 +370,7 @@ export default { "Devam etmeden önce aşağıdakileri kontrol edin" ], "Choose a disk for placing the boot loader": [ - "Önyükleme yükleyicisini yerleştirmek için bir disk seçin" + "Önyükleyiciyi yerleştirmek için disk seç" ], "Choose device to bind by MAC": [ "Bağlanacak cihazı MAC ile seçin" @@ -376,15 +396,15 @@ export default { "Close": [ "Kapat" ], - "Collapse the list of planned actions": [ - "Planlanan eylemlerin listesini daraltın" - ], "Configuration out of sync": [ "Yapılandırma senkronize değil" ], "Configuration read from the iSCSI Boot Firmware Table (iBFT).": [ "Yapılandırma iSCSI Önyükleme Ürün Yazılımı Tablosu'ndan (iBFT) okundu." ], + "Configuration unreachable or invalid": [ + "Konfigürasyon ulaşılamaz veya geçersiz" + ], "Configure DASD": [ "DASD'yi yapılandırın" ], @@ -455,7 +475,7 @@ export default { "%s'ye bağlanılıyor" ], "Connection details": [ - "Bağlantı detayları" + "Bağlantı ayrıntıları" ], "Connection is available to all devices.": [ "Tüm cihazlara bağlantı mevcuttur." @@ -536,16 +556,16 @@ export default { "Devre dışı bırakıldı" ], "Default file system for %s": [ - "%s için varsayılan dosya sistemi" + "%s için öntanımlı dosya sistemi" ], "Default file system for generic logical volumes": [ - "Genel mantıksal birimler için varsayılan dosya sistemi" + "Genel mantıksal birimler için öntanımlı dosya sistemi" ], "Default file system for generic mount paths": [ - "Genel bağlama yolları için varsayılan dosya sistemi" + "Genel bağlama yolları için öntanımlı dosya sistemi" ], "Default file system for generic partitions": [ - "Genel bölümler için varsayılan dosya sistemi" + "Genel bölümler için öntanımlı dosya sistemi" ], "Define a custom size": [ "Özel bir boyut tanımlayın" @@ -584,13 +604,10 @@ export default { "Mevcut verileri yok edin ve bölümü şu şekilde biçimlendirin" ], "Details": [ - "Detaylar" - ], - "Details for %s": [ - "%s için ayrıntılar" + "Ayrıntılar" ], "Details will appear after the connection is successfully established.": [ - "Bağlantı başarıyla kurulduktan sonra detaylar görünecektir." + "Bağlantı başarıyla kurulduktan sonra ayrıntılar görünecektir." ], "Device": [ "Cihaz" @@ -602,7 +619,7 @@ export default { "Cihaz Seçimi" ], "Device details": [ - "Cihaz detayları" + "Aygıt ayrıntıları" ], "Discard": [ "At" @@ -643,9 +660,6 @@ export default { "Download logs": [ "Günlükleri indir" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Kurulum sırasında aşağıdaki tabloda gösterilen düzeni oluşturmak için çeşitli işlemler gerçekleştirilecektir." - ], "Edit": [ "Düzenle" ], @@ -709,8 +723,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Örnek: https://sunucum.com" + "Example: %s": [ + "Örnek: %s" ], "Excellent signal": [ "Mükemmel sinyal" @@ -728,12 +742,12 @@ export default { "Ext4" ], "Extend the installation beyond the currently selected device": [ - "", - "" + "Kurulumu şu anda seçili olan cihazın ötesine genişletin", + "Kurulumu şu anda seçili olan %d aygıtın ötesine genişlet" ], "Extend the installation beyond the currently selected disk": [ - "", - "" + "Kurulumu şu anda seçili olan diskin ötesine geçirin", + "Kurulumu şu anda seçili olan %d disklerin ötesine geçirin" ], "Extensions": [ "Uzantılar" @@ -768,8 +782,8 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Bölgeye, saat dilimi koduna veya UTC farkına göre filtreleyin" ], - "Find space": [ - "Boşluk bul" + "Final layout": [ + "Son düzen" ], "Find space in %s": [ "%s'de boşluk bul" @@ -823,7 +837,7 @@ export default { "DASD aygıtlarının biçimlendirilmesi" ], "Full Disk Encryption (FDE) allows to protect the information stored at the new file systems, including data, programs, and system files.": [ - "Tam Disk Şifrelemesi (FDE), veriler, programlar ve sistem dosyaları da dahil olmak üzere yeni dosya sistemlerinde depolanan bilgilerin korunmasına olanak tanır." + "Tam Disk Şifrelemesi (FDE) yeni dosya sistemlerinde depolanan veri, program ve sistem dosyaları gibi bilgilerin korunmasını sağlar." ], "Full name": [ "Tam isim" @@ -854,7 +868,7 @@ export default { "%d alt birim eylemlerini gizle" ], "Hide details": [ - "Detayları gizle" + "Ayrıntıları gizle" ], "Hostname": [ "Ana bilgisayar adı" @@ -895,6 +909,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Devam ederseniz sabit diskinizdeki bölümler, sağlanan kurulum ayarlarına göre değiştirilecektir." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "Devam ediyor" ], @@ -914,7 +931,7 @@ export default { "Başlatıcı" ], "Initiator details": [ - "Başlatıcı detayları" + "Başlatıcı ayrıntıları" ], "Initiator name": [ "Başlatıcı adı" @@ -955,9 +972,6 @@ export default { "Install using several devices without modifying existing partitions.": [ "Mevcut bölümleri değiştirmeden %s aygıtını kullanarak yükleyin." ], - "Installation Devices": [ - "Kurulum Cihazları" - ], "Installation will take %s.": [ "Kurulum %s kadar olacak." ], @@ -1004,13 +1018,13 @@ export default { "LVM grubu '%s' için seçildi" ], "It is not possible to allocate space for %s.": [ - "%s için alan ayırmak mümkün değil." + "%s için alan ayırmak olanaksız." ], "It is not possible to allocate space for the boot partition and for %s.": [ - "Önyükleme bölümü ve %s için alan ayırmak mümkün değil." + "Önyükleme bölümü ve %s için alan ayırmak olanaksız." ], "It is not possible to install the system with the current configuration. Adjust the settings below.": [ - "Mevcut yapılandırma ile sistemi kurmak mümkün değildir. Aşağıdaki ayarları düzenleyin." + "Şu anki yapılandırma ile sistemi kurmak olanaksızdır. Aşağıdaki ayarları düzenleyin." ], "It is offline and must be activated before formatting it.": [ "Çevrimdışıdır ve biçimlendirmeden önce etkinleştirilmesi gerekir." @@ -1100,7 +1114,7 @@ export default { "Doğru değerleri sağladığınızdan emin olun" ], "Manage DASD devices": [ - "DASD cihazlarını yönetin" + "DASD aygıtlarını yönet" ], "Manual": [ "Manuel" @@ -1121,19 +1135,27 @@ export default { "Ayarları ve fiziksel birimleri değiştirin" ], "More actions": [ - "Daha fazla eylem" + "Daha çok eylem" ], "More devices": [ - "Daha fazla cihaz" + "Daha çok aygıt" ], "More keymap layout might be available for the selected product at [Localization] page": [ - "Seçili ürün için daha fazla tuş haritası düzeni [Yerelleştirme] sayfasında mevcut olabilir" + "Seçili ürün için daha çok klavye düzeni [Yerelleştirme] sayfasında bulunabilir" ], "More language and keyboard layout options for the selected product may be available in [Localization] page.": [ - "Seçili ürün için daha fazla dil ve klavye düzeni seçeneği [Yerelleştirme] sayfasında bulunabilir." + "Seçili ürün için daha çok dil ve klavye düzeni seçeneği [Yerelleştirme] sayfasında bulunabilir." ], "More languages might be available for the selected product at [Localization] page": [ - "Seçili ürün için [Yerelleştirme] sayfasında daha fazla dil mevcut olabilir" + "Seçili ürün için [Yerelleştirme] sayfasında daha çok dil bulunabilir" + ], + "Moreover, the following partition will be created.": [ + "Ayrıca, aşağıdaki bölüm oluşturulacak veya bağlanacaktır.", + "Ayrıca, aşağıdaki bölümler oluşturulacak veya bağlanacaktır." + ], + "Moreover, the following partition will be mounted.": [ + "Ayrıca, aşağıdaki bölüm oluşturulacak veya bağlanacaktır.", + "Ayrıca, aşağıdaki bölümler oluşturulacak veya bağlanacaktır." ], "Moreover, the following partitions will be created or mounted": [ "Ayrıca, aşağıdaki bölümler oluşturulacak veya bağlanacaktır" @@ -1187,7 +1209,7 @@ export default { "Ağ" ], "Network details": [ - "Ağ detayları" + "Ağ ayrıntıları" ], "Network not found or lost": [ "Ağ bulunamadı veya kaybedildi" @@ -1241,7 +1263,7 @@ export default { "Henüz mantıksal birimler tanımlanmadı" ], "No partitions will be automatically configured for booting. Use with caution.": [ - "Önyükleme için hiçbir bölüm otomatik olarak yapılandırılmayacak. Dikkatli kullanın." + "Önyükleme için hiçbir bölüm kendiliğinden yapılandırılmayacak. Dikkatli kullanın." ], "No support is planned.": [ "Herhangi bir destek planlanmamaktadır." @@ -1289,7 +1311,7 @@ export default { "Henüz uygulanmadı (%s)" ], "Not possible with the current setup. Click to know more.": [ - "Mevcut kurulum mümkün değil. Daha fazlasını öğrenmek için tıklayın." + "Şu anki kurulum olanaksız. Daha çoğunu öğrenmek için tıklayın." ], "Not protected network": [ "Korunmayan ağ" @@ -1315,12 +1337,6 @@ export default { "Options toggle": [ "Seçenekler geçişi" ], - "Other options": [ - "Diğer seçenekler" - ], - "Other options toggle": [ - "Diğer seçenekler arasında geçiş" - ], "Overview": [ "Genel bakış" ], @@ -1330,6 +1346,9 @@ export default { "Partition Info": [ "Bölüm Bilgisi" ], + "Partitions": [ + "Bölümler" + ], "Partitions needed for booting will also be adapted": [ "Önyükleme için gereken bölümler de uyarlanacak" ], @@ -1345,14 +1364,11 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Tekrar kullanılmayan bölümler gerektiğinde yeniden boyutlandırılacaktır." ], - "Partitions to boot will be allocated at the following device.": [ - "Önyükleme için bölümler aşağıdaki aygıta tahsis edilecektir." - ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Önyükleme için bölümler kurulum diski %s'de tahsis edilecektir." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], - "Partitions to boot will be allocated at the installation disk.": [ - "Önyükleme için gerekli bölümler kurulum diskinde tahsis edilecektir." + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], "Partitions will be used and created for %s": [ "Bölümler %s için kullanılacak ve oluşturulacak" @@ -1417,9 +1433,6 @@ export default { "Product is already registered": [ "Ürün zaten kayıtlı" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Veriler, programlar ve sistem dosyaları dahil olmak üzere yeni dosya sistemlerinde depolanan bilgilerin korunması." - ], "Provide email address": [ "E-posta adresini belirtin" ], @@ -1493,13 +1506,13 @@ export default { "Depo yüklemesi başarısız oldu" ], "Rescan devices": [ - "Cihazları yeniden tara" + "Aygıtları yeniden tara" ], "Reset to defaults": [ - "Varsayılanlara sıfırla" + "Öntanımlılara sıfırla" ], "Reset to the default configuration": [ - "Varsayılan yapılandırmaya sıfırla" + "Öntanımlı yapılandırmaya sıfırla" ], "Resource not found or lost": [ "Kaynak bulunamadı veya kayboldu" @@ -1507,6 +1520,9 @@ export default { "Result": [ "Sonuç" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "Yeniden kullanılan bölümler küçültülmeyecektir" ], @@ -1556,7 +1572,7 @@ export default { "Güvenlik" ], "See more details": [ - "Daha fazla ayrıntı görün" + "Daha çok ayrıntı gör" ], "Select": [ "Seç" @@ -1567,20 +1583,8 @@ export default { "Select a disk": [ "Bir disk seçin" ], - "Select a disk to configure": [ - "Yapılandırılacak bir disk seçin" - ], - "Select a disk to create %s": [ - "%s oluşturmak için bir disk seçin" - ], "Select a disk to define partitions or to mount": [ - "Bölümleri tanımlamak veya bağlamak için bir disk seçin" - ], - "Select a disk to format as %s": [ - "%s olarak biçimlendirilecek bir disk seçin" - ], - "Select a disk to install the system": [ - "Sistemi kurmak için bir disk seçin" + "Bölümleri tanımlamak veya bağlamak için disk seç" ], "Select a product": [ "Bir ürün seçin" @@ -1592,13 +1596,13 @@ export default { "Bölümleri tanımlamak veya bağlamak için başka bir cihaz seçin" ], "Select another disk to define partitions or to mount": [ - "Bölümleri tanımlamak veya bağlamak için başka bir disk seçin" + "Bölümleri tanımlamak veya bağlamak için başka disk seç" ], "Select at least one disk.": [ - "En az bir disk seçin." + "En az bir disk seç." ], "Select devices to enable bulk actions.": [ - "Toplu işlemleri etkinleştirmek için cihazları seçin." + "Toplu işlemleri etkinleştirmek için aygıtları seç." ], "Select or enter a mount point": [ "Bir bağlama noktası seçin veya girin" @@ -1609,9 +1613,6 @@ export default { "Select or enter a valid mount point": [ "Geçerli bir bağlama noktası seçin veya girin" ], - "Select the disk to configure partitions for booting": [ - "Önyükleme için bölümleri yapılandırmak üzere diski seçin" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Yeni sisteme yer açmak için her bölümle ne yapılacağını seçin." ], @@ -1665,7 +1666,7 @@ export default { "Daha az eylem göster" ], "Show more actions": [ - "Daha fazla eylem göster" + "Daha çok eylem göster" ], "Shrink existing partitions": [ "Mevcut bölümleri küçült" @@ -1731,13 +1732,13 @@ export default { "Bir temel bir kurulumu yapılandırmaya başlayın" ], "Start from scratch with the default configuration": [ - "Varsayılan yapılandırmayla sıfırdan başlayın" + "Öntanımlı yapılandırmayla sıfırdan başla" ], "Startup": [ "Başlangıç" ], "Static hostname": [ - "Statik ana bilgisayar adı" + "Durağan ana bilgisayar adı" ], "Status": [ "Durum" @@ -1746,7 +1747,7 @@ export default { "Depolama" ], "Structure of the new system, including disks to use and additional devices like LVM volume groups.": [ - "Kullanılacak diskler ve LVM birim grupları gibi ek cihazlar da dahil olmak üzere yeni sistemin yapısı." + "Kullanılacak diskler ve LVM birim grupları gibi ek aygıtlar da olmak üzere yeni sistemin yapısı." ], "Suggested mount points": [ "Önerilen bağlama noktaları" @@ -1767,7 +1768,11 @@ export default { "LVM grubu '%1$s' %2$s konumunda kalacak" ], "The configuration has been updated externally.": [ - "Yapılandırma harici olarak güncellendi." + "Yapılandırma dışardan güncellendi." + ], + "The configuration must be adapted to address the following issue:": [ + "Kuruluma başlamadan önce aşağıdaki sorunu gidermeniz gerekmektedir:", + "Kuruluma başlamadan önce aşağıdaki sorunları gidermeniz gerekmektedir:" ], "The configured LVM groups will remain at %s": [ "Yapılandırılan LVM grupları %s konumunda kalacaktır" @@ -1794,8 +1799,8 @@ export default { "Mevcut dosya sistemi %s konumuna bağlanacak" ], "The current storage configuration has the following issue:": [ - "", - "" + "Mevcut depolama konfigürasyonunda şu sorun var:", + "Mevcut depolama konfigürasyonunda şu sorunlar var:" ], "The data is kept, but the current partitions will be resized as needed.": [ "Veriler tutulacak, ancak mevcut bölümler ihtiyaç halinde yeniden boyutlandırılacak." @@ -1843,7 +1848,19 @@ export default { "Ekstra boş alanı doldurmak için son boyut daha büyük olabilir." ], "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ - "Güvenilir Platform Modülünü (Trusted Platform Module) (TPM) şifrelenmiş cihazları otomatik olarak açacak şekilde yapılandırmanın son adımı, yeni sistemin ilk önyüklemesi sırasında gerçekleştirilecektir. Bunun çalışması için makinenin doğrudan yeni önyükleyiciye önyükleme yapması gerekir." + "Güvenilir Platform Modülünü (TPM) şifrelenmiş aygıtları kendiliğinden açacak biçimde yapılandırmanın son adımı, yeni sistemin ilk önyüklemesi sırasında gerçekleştirilecektir. Bunun çalışması için makine doğrudan yeni önyükleyiciye önyüklemelidir." + ], + "The following logical volume will be created": [ + "Aşağıdaki mantıksal birim oluşturulacak", + "Aşağıdaki mantıksal birimler oluşturulacak" + ], + "The following partition will be created.": [ + "Aşağıdaki bölüm oluşturulacak veya bağlanacak.", + "Aşağıdaki bölümler oluşturulacak veya bağlanacak." + ], + "The following partition will be mounted.": [ + "Aşağıdaki bölüm bağlanacak.", + "Aşağıdaki bölümler bağlanacak." ], "The following partitions will be created or mounted": [ "Aşağıdaki bölümler oluşturulacak veya bağlanacak" @@ -1869,6 +1886,10 @@ export default { "The installer requires [root] user privileges.": [ "Yükleyici [root] kullanıcı ayrıcalıklarını gerektirir." ], + "The logical volume will also be deleted": [ + "Mantıksal birimde silinecek", + "Mantıksal birimlerdede silinecek" + ], "The maximum must be a number followed by a unit like GiB or GB": [ "Maksimum, GiB veya GB gibi bir birimin izlediği bir sayı olmalıdır" ], @@ -1896,6 +1917,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "TPM sistemin bütünlüğünü doğrulayabiliyorsa, verileri başlatmak ve erişmek için parolaya gerek kalmayacaktır. TPM yalıtımı, yeni sistemin ilk çalıştırmada doğrudan başlatılmasını gerektirir." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "%1$s için boyut, sistemdeki RAM miktarına ve %2$s için ayrı bir dosya sisteminin varlığına bağlı olarak dinamik olarak ayarlanacaktır." ], @@ -1942,7 +1966,7 @@ export default { "Sistem muhtemelen eksik veya devre dışı donanım nedeniyle Wi-Fi bağlantılarını desteklemiyor." ], "The system will use %s as its default language.": [ - "Sistem varsayılan dil olarak %s dilini kullanacaktır." + "Sistem öntanımlı olarak %s dilini kullanacaktır." ], "The whole device will be used for %s": [ "Tüm cihaz %s için kullanılacak" @@ -1954,17 +1978,21 @@ export default { "Kurulum için kullanılabilir bir disk yok." ], "There are not disks available for the installation. You may need to configure some device.": [ - "Kurulum için kullanılabilir disk yok. Bazı cihazları yapılandırmanız gerekebilir." + "Kurulum için kullanılabilir disk yok. Bazı aygıtları yapılandırmanız gerekebilir." ], "There are not usable partitions": [ "Kullanılabilir bölüm yok" ], + "There is %d destructive action planned": [ + "yıkıcı %d eylemi planlandı", + "yıkıcı %d eylemleri planlandı" + ], "There is %d destructive action planned affecting %s": [ - "", - "" + "%d planlanan yıkım askiyonu %s'i etkiliyor", + "%d planlanan yıkım askiyonları %s'i etkiliyor" ], "These are the most relevant installation settings. Feel free to browse the sections in the menu for further details.": [ - "Bunlar en alakalı kurulum ayarlarıdır. Daha fazla ayrıntı için menüdeki bölümlere göz atmaktan çekinmeyin." + "Bunlar belirgin kurulum ayarlarıdır. Daha çok ayrıntı için menüdeki bölümlere göz atmaktan çekinmeyin." ], "These are the settings for the product to install. The installer language and keyboard layout can be adjusted via the [settings panel] accessible from the top bar.": [ "Bunlar, ürünün kurulacağı ayarlardır. Yükleyici dili ve klavye düzeni, üst çubuktan erişilebilen [ayarlar paneli] aracılığıyla ayarlanabilir." @@ -1982,7 +2010,7 @@ export default { "Bu uzantı sunucuda mevcut değil. Sunucu yöneticisinden uzantıyı yansıtmasını isteyin." ], "This hostname is dynamic and may change after a reboot or network update, as configured by the local network administrator.": [ - "Bu ana bilgisayar adı dinamiktir ve yerel ağ yöneticisi tarafından yapılandırıldığı şekilde yeniden başlatma veya ağ güncellemesinden sonra değişebilir." + "Bu ana bilgisayar adı değişkendir ve yeniden başlatma veya ağ güncellemesinden sonra yerel ağ yöneticisince yapılandırıldığı biçimde değişebilir." ], "This license is not available in %s.": [ "Bu lisans %s'de mevcut değil." @@ -1991,7 +2019,7 @@ export default { "Güncellemeler tamamlanana kadar bu işlem biraz zaman alabilir." ], "This message will close automatically when everything is done.": [ - "Her şey tamamlandığında bu mesaj otomatik olarak kapanacaktır." + "Her şey tamamlandığında bu ileti kendiliğinden kapanacaktır." ], "This pattern strikes a balance between clarity and efficiency: the modal keeps things lightweight for simple selections, while the full view supports deeper exploration and more complex actions, specially for users with tons of devices.": [ "Bu desen, netlik ve verimlilik arasında bir denge kurar: modal, basit seçimler için her şeyi hafif tutarken, tam görünüm daha derin keşifleri ve özellikle çok sayıda cihaza sahip kullanıcılar için daha karmaşık eylemleri destekler." @@ -2078,40 +2106,40 @@ export default { "RAID %s'yi kullan" ], "Use RAID %s for LVM and additional partitions": [ - "LVM ve ek bölümler için RAID %s kullanın" + "LVM ve ek bölümler için RAID %s kullan" ], "Use RAID %s for LVM, additional partitions and booting": [ - "LVM, ek bölümler ve önyükleme için RAID %s kullanın" + "LVM, ek bölümler ve önyükleme için RAID %s kullan" ], "Use RAID %s for additional partitions": [ - "Ek bölümler için RAID %s kullanın" + "Ek bölümler için RAID %s kullan" ], "Use RAID %s for additional partitions and booting": [ - "Ek bölümler ve önyükleme için RAID %s kullanın" + "Ek bölümler ve önyükleme için RAID %s kullan" ], "Use RAID %s to configure boot partitions": [ - "Önyükleme bölümlerini yapılandırmak için RAID %s kullanın" + "Önyükleme bölümlerini yapılandırmak için RAID %s kullan" ], "Use RAID %s to host LVM": [ - "LVM'yi barındırmak için RAID %s kullanın" + "LVM'yi barındırma için RAID %s kullan" ], "Use RAID %s to host LVM and boot": [ - "LVM'yi barındırmak ve önyükleme yapmak için RAID %s'yi kullanın" + "LVM'yi barındırma ve önyükleme için RAID %s'yi kullan" ], "Use RAID %s to install": [ - "Kurulum için RAID %s kullanın" + "Kurulum için RAID %s kullan" ], "Use RAID %s to install and boot": [ - "Yükleme ve önyükleme için RAID %s kullanın" + "Kurulum ve önyükleme için RAID %s kullan" ], "Use RAID %s to install and host LVM": [ - "LVM'yi yüklemek ve barındırmak için RAID %s'yi kullanın" + "Kurulum ve LVM'yi barındırmak için RAID %s'yi kullan" ], "Use RAID %s to install, host LVM and boot": [ - "LVM'yi yüklemek, barındırmak ve önyüklemek için RAID %s'yi kullanın" + "Kurulum, LVM'yi barındırmak ve önyüklemek için RAID %s'yi kullan" ], "Use actions below to set up your devices or click %s to start from scratch with the default configuration.": [ - "Aygıtlarınızı ayarlamak için aşağıdaki eylemleri kullanın veya varsayılan yapılandırmayla sıfırdan başlamak için %s öğesine tıklayın." + "Aygıtlarınızı ayarlamak için aşağıdaki eylemleri kullanın veya öntanımlı yapılandırmayla sıfırdan başlamak için %s ögesine tıklayın." ], "Use available space": [ "Mevcut alanı kullan" @@ -2123,7 +2151,7 @@ export default { "LVM ve ek bölümler için %s diskini kullan" ], "Use disk %s for LVM, additional partitions and booting": [ - "LVM, ek bölümler ve önyükleme için %s diskini kullanın" + "LVM, ek bölümler ve önyükleme için %s diskini kullan" ], "Use disk %s for additional partitions": [ "Ek bölümler için %s diskini kullan" @@ -2132,31 +2160,31 @@ export default { "Ek bölümler ve önyükleme için %s diskini kullan" ], "Use disk %s to configure boot partitions": [ - "Önyükleme bölümlerini yapılandırmak için %s diskini kullanın" + "Önyükleme bölümlerini yapılandırmak için %s diskini kullan" ], "Use disk %s to host LVM": [ - "LVM'yi barındırmak için %s diskini kullanın" + "LVM'yi barındırmak için %s diskini kullan" ], "Use disk %s to host LVM and boot": [ - "LVM'yi barındırmak ve önyükleme yapmak için %s diskini kullanın" + "LVM'yi barındırmak ve önyükleme için %s diskini kullan" ], "Use disk %s to install": [ - "Yüklemek için %s diskini kullanın" + "Kurulum için %s diskini kullan" ], "Use disk %s to install and boot": [ - "Yükleme ve önyükleme için %s diskini kullanın" + "Kurulum ve önyükleme için %s diskini kullan" ], "Use disk %s to install and host LVM": [ - "LVM'yi yüklemek ve barındırmak için %s diskini kullanın" + "Kurulum ve LVM'yi barındırma için %s diskini kullan" ], "Use disk %s to install, host LVM and boot": [ - "LVM'yi yüklemek, barındırmak ve önyüklemek için %s diskini kullanın" + "Kurulum, LVM'yi barındırma ve önyükleme %s diskini kullan" ], "Use for installation only": [ - "Sadece kurulum için kullanın" + "Yalnızca kurulum için kullan" ], "Use for the selected product too": [ - "Seçili ürün için de kullanın" + "Seçili ürün için de kullan" ], "Use password": [ "Şifre kullan" @@ -2165,7 +2193,7 @@ export default { "Genel SSH Anahtarını Kullan" ], "Use static hostname": [ - "Statik ana bilgisayar adını kullan" + "Durağan ana bilgisayar adı kullan" ], "Use suggested username": [ "Önerilen kullanıcı adını kullan" @@ -2174,13 +2202,13 @@ export default { "RAID'i bölümler olmadan kullan" ], "Use the Trusted Platform Module (TPM) to decrypt automatically on each boot": [ - "Her önyüklemede otomatik olarak şifre çözmek için Güvenilir Platform Modülünü (TPM) kullanın" + "Her önyüklemede kendiliğinden şifre çözümü için Güvenilir Platform Modülünü (TPM) kullan" ], "Use the disk without partitions": [ "Bölümlendirme olmadan diski kullan" ], "Use these same settings for the selected product": [ - "Seçili ürün için aynı ayarları kullanın" + "Seçili ürün için aynı ayarları kullan" ], "Used space": [ "Kullanılan alan" @@ -2291,7 +2319,7 @@ export default { "en az %s" ], "auto selected": [ - "otomatik seçildi" + "kendiliğinden seçildi" ], "hostname": [ "ana bilgisayar adı" @@ -2318,7 +2346,7 @@ export default { "salt_okunur" ], "reset to defaults": [ - "varsayılanlara sıfırla" + "öntanımlılara sıfırla" ], "yes": [ "evet" diff --git a/web/src/po/po.uk.js b/web/src/po/po.uk.js index 2bf42d6030..9608de406d 100644 --- a/web/src/po/po.uk.js +++ b/web/src/po/po.uk.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " Вибір часового пояса" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -143,9 +149,6 @@ export default { "Add another address": [ "Додати іншу адресу" ], - "Add another partition or mount an existing one": [ - "Додати новий розділ або змонтувати наявний" - ], "Add device menu": [ "Меню додавання пристроїв" ], @@ -333,9 +336,6 @@ export default { "Change Language": [ "Змінити мову" ], - "Change boot options": [ - "Змінити параметри завантаження" - ], "Change device menu": [ "Меню зміни пристрою" ], @@ -360,15 +360,27 @@ export default { "Change selection": [ "Змінити вибір" ], + "Change the disk to configure": [ + "Змініть диск для налаштування" + ], + "Change the disk to create %s": [ + "Змініть диск для створення %s" + ], + "Change the disk to format as %s": [ + "Змініть диск для форматування на %s" + ], + "Change the disk to install the system": [ + "Змініть диск для встановлення системи" + ], "Change the file system or mount point": [ "Змінити файлову систему або точку монтування" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "Зміни в цих налаштуваннях негайно оновлять розділ «Результат» нижче." + ], "Channel ID": [ "Ідентифікатор каналу" ], - "Check the %d planned actions": [ - "Перевірити %d заплановані дії" - ], "Check the authentication parameters.": [ "Перевірте параметри автентифікації." ], @@ -402,9 +414,6 @@ export default { "Close": [ "Закрити" ], - "Collapse the list of planned actions": [ - "Згорнути список запланованих дій" - ], "Configuration out of sync": [ "Конфігурація не синхронізована" ], @@ -615,9 +624,6 @@ export default { "Details": [ "Подробиці" ], - "Details for %s": [ - "Подробиці для %s" - ], "Details will appear after the connection is successfully established.": [ "Подробиці з'являться після того як з'єднання буде успішно встановлено." ], @@ -672,9 +678,6 @@ export default { "Download logs": [ "Завантажити журнали" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "Під час інсталяції буде виконано кілька дій, щоб налаштувати схему, як показано в таблиці нижче." - ], "Edit": [ "Редагувати" ], @@ -738,8 +741,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "Приклад: https://myserver.com" + "Example: %s": [ + "Приклад: %s" ], "Excellent signal": [ "Відмінний сигнал" @@ -799,8 +802,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "Фільтр за територією, коду часового пояса або зміщенню UTC" ], - "Find space": [ - "Знайти місце" + "Final layout": [ + "Кінцевий варіант" + ], + "Final structure of the system after installation.": [ + "Остаточна структура системи після встановлення." ], "Find space in %s": [ "Знайти місце в %s" @@ -927,6 +933,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "Якщо Ви продовжите, розділи на вашому жорсткому диску буде змінено відповідно до наданих налаштувань встановлення." ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "В процесі" ], @@ -987,8 +996,8 @@ export default { "Install using several devices without modifying existing partitions.": [ "Встановлення з використанням кількох пристроїв без зміни наявних розділів." ], - "Installation Devices": [ - "Пристрої для встановлення" + "Installation devices": [ + "Пристрої встановлення" ], "Installation will take %s.": [ "Встановлення займе %s." @@ -1167,6 +1176,9 @@ export default { "More languages might be available for the selected product at [Localization] page": [ "Більше мов може бути доступно на сторінці [Локалізації]" ], + "More storage options": [ + "Більше варіантів зберігання" + ], "Moreover, the following partition will be created.": [ "Крім того, буде створено такий розділ.", "Крім того, буде створено такі розділи.", @@ -1282,6 +1294,9 @@ export default { "No logical volumes are defined yet": [ "Логічні томи ще не задано" ], + "No partitions will be automatically configured for booting.": [ + "Для завантаження автоматично не буде налаштовано жодних розділів." + ], "No partitions will be automatically configured for booting. Use with caution.": [ "Жоден розділ не буде автоматично налаштовано для завантаження. Використовуйте з обережністю." ], @@ -1354,24 +1369,27 @@ export default { "Only reused partitions will be used.": [ "Буде використано лише повторно використовувані розділи." ], + "Options for partition %s": [ + "Параметри розділу %s" + ], "Options toggle": [ "Показ налаштувань" ], - "Other options": [ - "Інші опції" - ], - "Other options toggle": [ - "Показати інші налаштування" - ], "Overview": [ "Огляд" ], "Package installation failed": [ "Не вдалося встановити пакунок" ], + "Partition %s": [ + "Розділ %s" + ], "Partition Info": [ "Інформація про розділ" ], + "Partitions": [ + "Розділи" + ], "Partitions needed for booting will also be adapted": [ "Розділи, необхідні для завантаження, також будуть адаптовані" ], @@ -1387,14 +1405,23 @@ export default { "Partitions that are not reused would be resized if needed.": [ "Розділи, які не використовуються повторно, за необхідності будуть змінені в розмірах." ], - "Partitions to boot will be allocated at the following device.": [ - "Розділи для завантаження буде виділено на наступному пристрої." + "Partitions to boot will be set up if needed at %s.": [ + "Розділи для завантаження будуть налаштовані за необхідності в %s." + ], + "Partitions to boot will be set up if needed at the following device.": [ + "Розділи для завантаження будуть налаштовані за необхідності на наступному пристрої." ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "Розділи для завантаження буде виділено на інсталяційному диску %s." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Розділи для завантаження будуть налаштовані за необхідності на інсталяційному диску, виходячи з розташування файлової системи %s." ], - "Partitions to boot will be allocated at the installation disk.": [ - "Розділи для завантаження буде виділено на інсталяційному диску." + "Partitions to boot will be set up if needed at the installation disk, based on the location of the %s file system.": [ + "Розділи для завантаження будуть налаштовані за необхідності на інсталяційному диску, виходячи з розташування файлової системи %s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Розділи для завантаження будуть налаштовані за необхідності на інсталяційному диску. Наразі %1$s, виходячи з розташування файлової системи %2$s." + ], + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "Розділи для завантаження будуть налаштовані за необхідності на інсталяційному диску. Наразі %1$s, виходячи з розташування файлової системи %2$s." ], "Partitions will be used and created for %s": [ "Буде використано та створено розділи для %s" @@ -1459,8 +1486,8 @@ export default { "Product is already registered": [ "Продукт вже зареєстровано" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "Захист інформації, що зберігається на нових файлових системах, включно з даними, програмами та системними файлами." + "Protection for the information stored at the new file systems, including data, programs, and system files.": [ + "Захист інформації, що зберігається в нових файлових системах, включаючи дані, програми та системні файли." ], "Provide email address": [ "Вкажіть адресу електронної пошти" @@ -1549,6 +1576,9 @@ export default { "Result": [ "Результат" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "Результат застосування конфігурації, описаної у розділі «Налаштування» вище." + ], "Reused partitions will not be shrunk": [ "Повторно використані розділи не будуть зменшені" ], @@ -1609,21 +1639,9 @@ export default { "Select a disk": [ "Оберіть диск" ], - "Select a disk to configure": [ - "Виберіть диск для налаштування" - ], - "Select a disk to create %s": [ - "Виберіть диск для створення %s" - ], "Select a disk to define partitions or to mount": [ "Виберіть диск для визначення розділів або монтування" ], - "Select a disk to format as %s": [ - "Виберіть диск для форматування як %s" - ], - "Select a disk to install the system": [ - "Оберіть диск для встановлення системи" - ], "Select a product": [ "Оберіть продукт" ], @@ -1651,9 +1669,6 @@ export default { "Select or enter a valid mount point": [ "Виберіть або введіть дійсну точку монтування" ], - "Select the disk to configure partitions for booting": [ - "Виберіть диск для налаштування розділів для завантаження" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "Виберіть, що робити з кожним розділом, щоб знайти місце для розміщення нової системи." ], @@ -1894,6 +1909,9 @@ export default { "The final step to configure the Trusted Platform Module (TPM) to automatically open encrypted devices will take place during the first boot of the new system. For that to work, the machine needs to boot directly to the new boot loader.": [ "Останній крок з налаштування модуля довіреної платформи (TPM) для автоматичного відкриття зашифрованих пристроїв відбудеться під час першого завантаження нової системи. Щоб це спрацювало, комп'ютер повинен завантажитися безпосередньо з новим завантажувачем." ], + "The following actions will be performed in the system during installation.": [ + "Під час інсталяції в системі будуть виконані наступні дії." + ], "The following logical volume will be created": [ "Буде створено такий логічний том", "Будуть створені такі логічні томи", @@ -1965,6 +1983,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "Пароль не знадобиться для завантаження та доступу до даних, якщо TPM зможе перевірити цілісність системи. Запечатування TPM вимагає, щоб нова система завантажувалася безпосередньо під час першого запуску." ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "Розмір для %1$s буде динамічно коригуватися залежно від обсягу оперативної пам'яті в системі та наявності окремої файлової системи для %2$s." ], @@ -2095,6 +2116,9 @@ export default { "Tmpfs": [ "Tmpfs" ], + "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ + "Щоб забезпечити можливість завантаження нової системи, інсталятору може знадобитися створити або налаштувати деякі розділи на відповідному диску." + ], "To ensure the new system is able to boot, the installer may need to create or configure some partitions in the appropriate disk.": [ "Щоб забезпечити можливість завантаження нової системи, програмі встановлення може знадобитися створити або налаштувати деякі розділи на відповідному диску." ], @@ -2284,6 +2308,9 @@ export default { "Using transient hostname: %s": [ "Використання перехідного імені хоста: %s" ], + "Volume group %s": [ + "Група томів %s" + ], "Volume group '%s' already exists. Enter a different name.": [ "Група томів „%s“ вже існує. Введіть іншу назву." ], diff --git a/web/src/po/po.zh-CN.js b/web/src/po/po.zh-CN.js index d504a06bb5..f770e7d022 100644 --- a/web/src/po/po.zh-CN.js +++ b/web/src/po/po.zh-CN.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " 时区选择" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -135,9 +141,6 @@ export default { "Add another address": [ "添加另一个地址" ], - "Add another partition or mount an existing one": [ - "添加另一个分区或挂载一个现有分区" - ], "Add device menu": [ "添加设备菜单" ], @@ -321,9 +324,6 @@ export default { "Change Language": [ "更改语言" ], - "Change boot options": [ - "更改启动选项" - ], "Change device menu": [ "更改设备菜单" ], @@ -351,12 +351,12 @@ export default { "Change the file system or mount point": [ "更改文件系统或挂载点" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "通道 ID" ], - "Check the %d planned actions": [ - "检查 %d 项已计划的操作" - ], "Check the authentication parameters.": [ "请检查身份验证参数。" ], @@ -390,9 +390,6 @@ export default { "Close": [ "关闭" ], - "Collapse the list of planned actions": [ - "收起已计划操作列表" - ], "Configuration out of sync": [ "配置未同步" ], @@ -603,9 +600,6 @@ export default { "Details": [ "细节" ], - "Details for %s": [ - "%s 的细节" - ], "Details will appear after the connection is successfully established.": [ "成功建立连接后将会显示详细信息。" ], @@ -660,9 +654,6 @@ export default { "Download logs": [ "下载日志" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "安装期间,将执行多项操作以设置布局(如下表所示)。" - ], "Edit": [ "编辑" ], @@ -726,8 +717,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "示例:https://myserver.com" + "Example: %s": [ + "示例:%s" ], "Excellent signal": [ "信号极佳" @@ -783,8 +774,8 @@ export default { "Filter by territory, time zone code or UTC offset": [ "按地区、时区代码或 UTC 偏移量过滤" ], - "Find space": [ - "查找空间" + "Final layout": [ + "最终布局" ], "Find space in %s": [ "在 %s 中查找可用空间" @@ -909,6 +900,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "如果继续,硬盘上的分区将会根据已提供的安装设置进行修改。" ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "进行中" ], @@ -969,9 +963,6 @@ export default { "Install using several devices without modifying existing partitions.": [ "使用多个设备进行安装,不修改现有分区。" ], - "Installation Devices": [ - "安装设备" - ], "Installation will take %s.": [ "安装将会占用 %s。" ], @@ -1335,12 +1326,6 @@ export default { "Options toggle": [ "选项切换开关" ], - "Other options": [ - "其他选项" - ], - "Other options toggle": [ - "其他选项切换开关" - ], "Overview": [ "概览" ], @@ -1350,6 +1335,9 @@ export default { "Partition Info": [ "分区信息" ], + "Partitions": [ + "分区" + ], "Partitions needed for booting will also be adapted": [ "引导所需的分区也会进行调整" ], @@ -1365,14 +1353,11 @@ export default { "Partitions that are not reused would be resized if needed.": [ "不重复使用的分区将根据需要调整大小。" ], - "Partitions to boot will be allocated at the following device.": [ - "引导分区将在以下设备上分配。" + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "引导分区将在安装磁盘 %s 上进行分配。" - ], - "Partitions to boot will be allocated at the installation disk.": [ - "引导分区将会分配在安装磁盘上。" + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], "Partitions will be used and created for %s": [ "将会为 %s 使用和创建多个分区" @@ -1437,9 +1422,6 @@ export default { "Product is already registered": [ "产品已注册" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "用于保护存储在新文件系统中的信息(包括数据、程序以及系统文件)的机制。" - ], "Provide email address": [ "提供电子邮件地址" ], @@ -1527,6 +1509,9 @@ export default { "Result": [ "结果" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "将不收缩重复使用的分区" ], @@ -1587,21 +1572,9 @@ export default { "Select a disk": [ "选择一个磁盘" ], - "Select a disk to configure": [ - "选择要配置的磁盘" - ], - "Select a disk to create %s": [ - "选择用于创建 %s 的磁盘" - ], "Select a disk to define partitions or to mount": [ "选择一个要定义分区或要挂载的磁盘" ], - "Select a disk to format as %s": [ - "选择一个要格式化为 %s 的磁盘" - ], - "Select a disk to install the system": [ - "选择用于安装系统的磁盘" - ], "Select a product": [ "请选择产品" ], @@ -1629,9 +1602,6 @@ export default { "Select or enter a valid mount point": [ "请选择或输入有效的挂载点" ], - "Select the disk to configure partitions for booting": [ - "选择要配置引导分区的磁盘" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "选择如何处理每个分区,以便为新系统分配空间。" ], @@ -1929,6 +1899,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "若 TPM 可以验证系统的完整性,启动和访问数据的时候将无需使用密码。 TPM 密封要求新系统在首次启动时直接开始引导。" ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "%1$s 的大小将会动态调整,考量因素包括系统中的 RAM 容量以及 %2$s 是否存在单独的文件系统。" ], diff --git a/web/src/po/po.zh-TW.js b/web/src/po/po.zh-TW.js index c0317ff2bc..aabe5ae479 100644 --- a/web/src/po/po.zh-TW.js +++ b/web/src/po/po.zh-TW.js @@ -6,6 +6,12 @@ export default { " Timezone selection": [ " 時區選擇" ], + "\"%s\"": [ + "" + ], + "\"%s\" does not exist or is no longer available.": [ + "" + ], "%1$s (%2$s)": [ "%1$s (%2$s)" ], @@ -135,9 +141,6 @@ export default { "Add another address": [ "新增另一個位址" ], - "Add another partition or mount an existing one": [ - "新增另一個分割區或掛接一個現有分割區" - ], "Add device menu": [ "新增裝置功能表" ], @@ -321,9 +324,6 @@ export default { "Change Language": [ "變更語言" ], - "Change boot options": [ - "變更開機選項" - ], "Change device menu": [ "變更裝置功能表" ], @@ -351,12 +351,12 @@ export default { "Change the file system or mount point": [ "變更檔案系統或掛接點" ], + "Changes in these settings will immediately update the 'Result' section below.": [ + "" + ], "Channel ID": [ "通道 ID" ], - "Check the %d planned actions": [ - "檢查 %d 項計劃的動作" - ], "Check the authentication parameters.": [ "請檢查驗證參數。" ], @@ -390,9 +390,6 @@ export default { "Close": [ "關閉" ], - "Collapse the list of planned actions": [ - "收起計劃的動作清單" - ], "Configuration out of sync": [ "組態未同步" ], @@ -603,9 +600,6 @@ export default { "Details": [ "詳細資料" ], - "Details for %s": [ - "%s 的詳細資料" - ], "Details will appear after the connection is successfully established.": [ "成功建立連接後將會顯示詳細資料。" ], @@ -660,9 +654,6 @@ export default { "Download logs": [ "下載記錄" ], - "During installation, several actions will be performed to setup the layout shown at the table below.": [ - "安裝期間,將執行多項動作以設定配置 (如下表所示)。" - ], "Edit": [ "編輯" ], @@ -726,8 +717,8 @@ export default { "ExFAT": [ "ExFAT" ], - "Example: https://myserver.com": [ - "範例:https://myserver.com" + "Example: %s": [ + "範例:%s" ], "Excellent signal": [ "訊號極佳" @@ -783,8 +774,11 @@ export default { "Filter by territory, time zone code or UTC offset": [ "依地區、時區代碼或 UTC 偏移過濾" ], - "Find space": [ - "尋找空間" + "Final layout": [ + "" + ], + "Final structure of the system after installation.": [ + "" ], "Find space in %s": [ "在 %s 中尋找可用空間" @@ -909,6 +903,9 @@ export default { "If you continue, partitions on your hard disk will be modified according to the provided installation settings.": [ "如果繼續操作,系統將依照提供的安裝設定修改硬碟上的分割區。" ], + "If you want to disable this check, please specify \"inst.ay_check=0\" at kernel's command-line": [ + "" + ], "In progress": [ "進行中" ], @@ -969,9 +966,6 @@ export default { "Install using several devices without modifying existing partitions.": [ "使用多部裝置進行安裝,不修改現有分割區。" ], - "Installation Devices": [ - "安裝裝置" - ], "Installation will take %s.": [ "安裝將會佔用 %s。" ], @@ -1335,12 +1329,6 @@ export default { "Options toggle": [ "選項切換鈕" ], - "Other options": [ - "其他選項" - ], - "Other options toggle": [ - "其他選項切換鈕" - ], "Overview": [ "綜覽" ], @@ -1350,6 +1338,9 @@ export default { "Partition Info": [ "分割區資訊" ], + "Partitions": [ + "分割區" + ], "Partitions needed for booting will also be adapted": [ "開機所需的分割區也將進行調整" ], @@ -1365,14 +1356,11 @@ export default { "Partitions that are not reused would be resized if needed.": [ "將視需要調整不重複使用的分割區的大小。" ], - "Partitions to boot will be allocated at the following device.": [ - "將會在以下裝置上配置開機分割區。" + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], - "Partitions to boot will be allocated at the installation disk %s.": [ - "將會在安裝磁碟 %s 上配置開機分割區。" - ], - "Partitions to boot will be allocated at the installation disk.": [ - "將會在安裝磁碟上配置開機分割區。" + "Partitions to boot will be set up if needed at the installation disk. Currently %1$s, based on the location of the %2$s file system.": [ + "" ], "Partitions will be used and created for %s": [ "將會為 %s 使用和建立多個分割區" @@ -1437,9 +1425,6 @@ export default { "Product is already registered": [ "產品已註冊" ], - "Protection for the information stored at the new file systems, including data, programs, and system files.": [ - "該機制用於保護儲存在新檔案系統中的資訊,包括資料、程式以及系統檔案。" - ], "Provide email address": [ "提供電子郵件地址" ], @@ -1527,6 +1512,9 @@ export default { "Result": [ "結果" ], + "Result of applying the configuration described at the 'Settings' section above.": [ + "" + ], "Reused partitions will not be shrunk": [ "將不縮小重複使用的分割區" ], @@ -1587,21 +1575,9 @@ export default { "Select a disk": [ "選取一個磁碟" ], - "Select a disk to configure": [ - "選取要設定的磁碟" - ], - "Select a disk to create %s": [ - "選取用於建立 %s 的磁碟" - ], "Select a disk to define partitions or to mount": [ "選取一個要定義分割區或要掛接的磁碟" ], - "Select a disk to format as %s": [ - "選取一個要格式化為 %s 的磁碟" - ], - "Select a disk to install the system": [ - "選取用於安裝系統的磁碟" - ], "Select a product": [ "請選取產品" ], @@ -1629,9 +1605,6 @@ export default { "Select or enter a valid mount point": [ "請選取或輸入有效的掛接點" ], - "Select the disk to configure partitions for booting": [ - "選取要設定開機分割區的磁碟" - ], "Select what to do with each partition in order to find space for allocating the new system.": [ "選擇如何處理每個分割區,以便為新系統配置空間。" ], @@ -1929,6 +1902,9 @@ export default { "The password will not be needed to boot and access the data if the TPM can verify the integrity of the system. TPM sealing requires the new system to be booted directly on its first run.": [ "如果 TPM 可以驗證系統的完整性,則開機和存取資料時將無需輸入密碼。TPM 封存功能要求新系統在首次執行時直接開機。" ], + "The product will be registered with \"%s\" hostname": [ + "" + ], "The size for %1$s will be dynamically adjusted based on the amount of RAM in the system and the presence of a separate file system for %2$s.": [ "%1$s 的大小將會動態調整,考量因素包括系統中的 RAM 容量以及 %2$s 是否存在單獨的檔案系統。" ], diff --git a/web/src/test-utils.tsx b/web/src/test-utils.tsx index e5243e7ada..0c0cd8b78d 100644 --- a/web/src/test-utils.tsx +++ b/web/src/test-utils.tsx @@ -36,6 +36,7 @@ import { render, within } from "@testing-library/react"; import { createClient } from "~/client/index"; import { InstallerClientProvider } from "~/context/installer"; import { InstallerL10nProvider } from "~/context/installerL10n"; +import { StorageUiStateProvider } from "~/context/storage-ui-state"; import { isObject, noop } from "radashi"; import { DummyWSClient } from "./client/ws"; @@ -128,12 +129,18 @@ const Providers = ({ children, withL10n }) => { // }); return ( - {children} + + {children} + ); } - return {children}; + return ( + + {children} + + ); }; /** diff --git a/web/src/utils.ts b/web/src/utils.ts index ebd97eeaf0..51bcce1950 100644 --- a/web/src/utils.ts +++ b/web/src/utils.ts @@ -20,6 +20,8 @@ * find current contact information at www.suse.com. */ +import { mapEntries } from "radashi"; +import { generatePath } from "react-router"; import { ISortBy, sort } from "fast-sort"; /** @@ -158,6 +160,25 @@ const mask = (value: string, visible: number = 4, maskChar: string = "*"): strin return maskChar.repeat(maskedLength) + visiblePart; }; +/** + * A wrapper around React Router's `generatePath` that ensures all path parameters + * are URI-encoded using `encodeURIComponent`. This prevents broken URLs caused by + * special characters such as spaces, `#`, `$`, and others. + * + * @example + * ```ts + * // Returns "/network/Wired%20%231" + * generateEncodedPath("/network/:id", { id: "Wired #1" }); + * ``` + */ +const generateEncodedPath = (...args: Parameters) => { + const [path, params] = args; + return generatePath( + path, + mapEntries(params, (key, value) => [key, encodeURIComponent(value)]), + ); +}; + /** * A lightweight wrapper around `fast-sort`. * @@ -192,5 +213,6 @@ export { localConnection, timezoneTime, mask, + generateEncodedPath, sortCollection, };