From 438bb7dabdcfa866df18302071bae0daad641332 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Mon, 10 Aug 2026 19:58:59 +0000 Subject: op-mode: T7250: restore image/file path completion for show/copy/delete file The imagefiles comptype dispatched to _vyatta_image_file_complete, a function that was never ported when the legacy vyatta-op bash completion script was imported in commit 72a704d2e2 ("T6527: add legacy Vyatta interpreter files still in us"), causing "Invalid command: [_vyatta_image_file_complete]" on tab-completion. Port the original vyatta-image-complete interpreter so completion of works again as it did on VyOS 1.4.x. --- src/etc/bash_completion.d/vyatta-op | 151 ++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/src/etc/bash_completion.d/vyatta-op b/src/etc/bash_completion.d/vyatta-op index fbd2045f3..9099cfa70 100644 --- a/src/etc/bash_completion.d/vyatta-op +++ b/src/etc/bash_completion.d/vyatta-op @@ -619,6 +619,157 @@ _vyatta_set_comptype () done } +# comptype: imagefiles +# Port of the legacy Vyatta vyatta-image-complete interpreter, which +# completes ://, running://, disk-install:// and +# remote scheme://... targets for `show file`, `copy file`, +# `copy file ... to`, and `delete file`. +# https://github.com/vyos-legacy/vyatta-op/blob/current/functions/interpreter/vyatta-image-complete +declare -a _vyatta_image_noncomps=( \ + "http(s)://:@/" \ + "scp://:@/" \ + "sftp://:@/" \ + "ftp(s)://:@/" \ + "tftp:///" ) + +_vyatta_image_is_file () +{ + local cur=$1 + local topdir + if ! [[ ${cur:0:1} =~ "/" ]]; then + cur=${cur/:/} + topdir=${cur%%/*} + cur=${cur#$topdir/} + fi + if [[ $topdir == "running" ]]; then + cur="/${cur}" + elif [[ $topdir == "disk-install" ]]; then + cur="/lib/live/mount/persistence/${cur}" + elif [[ ${cur:0:1} =~ "/" ]]; then + cur=${cur} + else + cur="/lib/live/mount/persistence/boot/${topdir}/rw/${cur}" + fi + if [[ -f ${cur} ]]; then + return 0 + else + return 1 + fi +} + +_vyatta_image_path_complete () +{ + compopt -o nospace + local -a reply + local topdir isrunningimg isdiskinstall file + if _vyatta_image_is_file $cur ; then + _vyatta_op_completions=( "${cur} " ) + _vyatta_op_noncompletions=( ) + return 0 + fi + if [[ ${cur:0:1} =~ "/" ]]; then + reply=( $(compgen -f ${cur}) ) + for ((i=0; i < ${#reply[@]}; i++)); do + [[ -d ${reply[i]} ]] && reply[i]="${reply[i]}"/ + done + _vyatta_op_completions=( "${reply[@]}" ) + return + fi + if [[ ${cur} == "" ]]; then + reply=( $(compgen -d /lib/live/mount/persistence/boot/ | grep -v grub) ) + for i in `seq 0 $[${#reply[@]}-1]`; do + file=${reply[$i]} + reply[$i]=${file/#\/lib\/live\/mount\/persistence\/boot\//} + reply[$i]="${reply[$i]}://" + done + reply+=( "running://" ) + if [[ -d /lib/live/mount/persistence/opt/vyatta/etc/config || -d /lib/live/mount/persistence/config ]]; then + reply+=( "disk-install://" ) + fi + _vyatta_op_noncompletions=( "${_vyatta_image_noncomps[@]}" ) + else + _vyatta_op_noncompletions=( ) + if ! [[ $cur =~ .*:\/\/ ]]; then + if [[ $cur =~ .*:\/ ]]; then + cur=${cur/:\//} + fi + if [[ $cur =~ .*: ]]; then + cur=${cur/:/} + fi + isrunningimg=$(compgen -W "running" -- ${cur}) + isdiskinstall=$(compgen -W "disk-install" -- ${cur}) + if [[ $isrunningimg == "running" ]]; then + cur="/" + elif [[ $isdiskinstall == "disk-install" ]]; then + cur="/lib/live/mount/persistence/" + else + cur="/lib/live/mount/persistence/boot/${cur}" + fi + reply=( $(compgen -f ${cur} | grep -v grub) ) + for i in `seq 0 $[${#reply[@]}-1]`; do + file=${reply[$i]} + if [[ $isrunningimg == "running" ]]; then + reply[$i]="running://" + elif [[ $isdiskinstall == "disk-install" ]]; then + reply[$i]="disk-install://" + else + reply[$i]=${file/#\/lib\/live\/mount\/persistence\/boot\//} + if [[ -d /lib/live/mount/persistence/boot/${reply[$i]} ]]; then + reply[$i]="${reply[$i]/#\//}://" + fi + fi + done + else + cur=${cur/:/} + topdir=${cur%%/*} + cur=${cur#$topdir//} + if [[ $topdir == "running" ]]; then + cur="/${cur}" + elif [[ $topdir == "disk-install" ]]; then + cur="/lib/live/mount/persistence/${cur}" + else + cur="/lib/live/mount/persistence/boot/${topdir}/rw/${cur}" + fi + reply=( $(compgen -f ${cur}) ) + # for loop from _filedirs() in /etc/bash_completion + for ((i=0; i < ${#reply[@]}; i++)); do + if [[ ${cur:0:1} != "'" ]]; then + [[ -d ${reply[i]} ]] && reply[i]="${reply[i]}"/ + if [[ ${cur:0:1} == '"' ]]; then + reply[i]=${reply[i]//\\/\\\\} + reply[i]=${reply[i]//\"/\\\"} + reply[i]=${reply[i]//\$/\\\$} + else + reply[i]=$(printf %q ${reply[i]}) + fi + fi + done + for i in `seq 0 $[${#reply[@]}-1]`; do + file=${reply[$i]} + if [[ $topdir == "running" ]]; then + reply[$i]=${file/#\//"$topdir://"} + elif [[ $topdir == "disk-install" ]]; then + reply[$i]=${file/#\/lib\/live\/mount\/persistence\//"$topdir://"} + else + reply[$i]=${file/#\/lib\/live\/mount\/persistence\/boot\/$topdir/"$topdir://"} + reply[$i]=${reply[$i]/\/rw\/} + fi + done + fi + fi + _vyatta_op_completions=( "${reply[@]}" ) + return 0 +} + +_vyatta_image_file_complete () +{ + if _vyatta_image_is_file ${COMP_WORDS[(( ${#COMP_WORDS[@]}-2 ))]}; then + _vyatta_op_completions=( "" " " ) + return 0 + fi + _vyatta_image_path_complete +} + _filedir_xspec_vyos() { local cur prev words cword -- cgit v1.2.3