/
githubmirror
/
ndctl
Обзор
Документация
Войти
/
githubmirror
/
ndctl
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v72
contrib/ndctl
760 строк
15 KB
Vishal Verma
cxl-cli: add bash completion
10 дек 2021, 00:06
10 дек 2021, 00:06
02c40b9
Код
Авторство
О чём код?
# ndctl bash and zsh completion # Taken from perf's completion script. ### common helpers between ndctl and daxctl __my_reassemble_comp_words_by_ref() { local exclude i j first # Which word separators to exclude? exclude="${1//[^$COMP_WORDBREAKS]}" cword_=$COMP_CWORD if [ -z "$exclude" ]; then words_=("${COMP_WORDS[@]}") return fi # List of word completion separators has shrunk; # re-assemble words to complete. for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do # Append each nonempty word consisting of just # word separator characters to the current word. first=t while [ $i -gt 0 ] && [ -n "${COMP_WORDS[$i]}" ] && # word consists of excluded word separators [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] do # Attach to the previous token, # unless the previous token is the command name. if [ $j -ge 2 ] && [ -n "$first" ]; then ((j--)) fi first= words_[$j]=${words_[j]}${COMP_WORDS[i]} if [ $i = $COMP_CWORD ]; then cword_=$j fi if (($i < ${#COMP_WORDS[@]} - 1)); then ((i++)) else # Done. return fi done words_[$j]=${words_[j]}${COMP_WORDS[i]} if [ $i = $COMP_CWORD ]; then cword_=$j fi done } # Define preload_get_comp_words_by_ref="false", if the function # __nd_common_get_comp_words_by_ref() is required instead. preload_get_comp_words_by_ref="true" if [ $preload_get_comp_words_by_ref = "true" ]; then type _get_comp_words_by_ref &>/dev/null || preload_get_comp_words_by_ref="false" fi [ $preload_get_comp_words_by_ref = "true" ] || __nd_common_get_comp_words_by_ref() { local exclude cur_ words_ cword_ if [ "$1" = "-n" ]; then exclude=$2 shift 2 fi __my_reassemble_comp_words_by_ref "$exclude" cur_=${words_[cword_]} while [ $# -gt 0 ]; do case "$1" in cur) cur=$cur_ ;; prev) prev=${words_[$cword_-1]} ;; words) words=("${words_[@]}") ;; cword) cword=$cword_ ;; esac shift done } __nd_common_prev_skip_opts () { local i cmd_ cmds_ let i=cword-1 cmds_=$($cmd $1 --list-cmds) prev_skip_opts=() while [ $i -ge 0 ]; do if [[ ${words[i]} == $1 ]]; then return fi for cmd_ in $cmds_; do if [[ ${words[i]} == $cmd_ ]]; then prev_skip_opts=${words[i]} return fi done ((i--)) done } ### ndctl __ndctlcomp() { local i=0 COMPREPLY=( $( compgen -W "$1" -- "$2" ) ) for cword in "${COMPREPLY[@]}"; do if [[ "$cword" == @(--bus|--region|--type|--mode|--size|--dimm|--reconfig|--uuid|--name|--sector-size|--map|--namespace|--input|--output|--label-version|--align|--block|--count|--firmware|--media-temperature|--ctrl-temperature|--spares|--media-temperature-threshold|--ctrl-temperature-threshold|--spares-threshold|--media-temperature-alarm|--ctrl-temperature-alarm|--spares-alarm|--numa-node|--log|--dimm-event|--config-file|--key-handle|--key-path|--tpm-handle) ]]; then COMPREPLY[$i]="${cword}=" else COMPREPLY[$i]="${cword} " fi ((i++)) done } __ndctl_get_buses() { local opts="--buses $*" [ -n "$dimm_filter" ] && opts="$opts --dimm=$dimm_filter" [ -n "$reg_filter" ] && opts="$opts --region=$reg_filter" [ -n "$ns_filter" ] && opts="$opts --namespace=$ns_filter" echo "$(ndctl list $opts | grep -E "^\s*\"provider\":" | cut -d\" -f4)" } __ndctl_get_regions() { local opts="--regions $*" [ -n "$bus_filter" ] && opts="$opts --bus=$bus_filter" [ -n "$dimm_filter" ] && opts="$opts --dimm=$dimm_filter" [ -n "$ns_filter" ] && opts="$opts --namespace=$ns_filter" [ -n "$type_filter" ] && opts="$opts --type=$type_filter" [ -n "$idle_filter" ] && opts="$opts --idle" echo "$(ndctl list $opts | grep -E "^\s*\"dev\":" | cut -d\" -f4)" } __ndctl_get_ns() { opts="--namespaces $*" [ -n "$bus_filter" ] && opts="$opts --bus=$bus_filter" [ -n "$dimm_filter" ] && opts="$opts --dimm=$dimm_filter" [ -n "$reg_filter" ] && opts="$opts --region=$reg_filter" [ -n "$mode_filter" ] && opts="$opts --mode=$mode_filter" [ -n "$type_filter" ] && opts="$opts --type=$type_filter" [ -n "$idle_filter" ] && opts="$opts --idle" echo "$(ndctl list $opts | grep -E "^\s*\"dev\":" | cut -d\" -f4)" } __ndctl_get_dimms() { opts="--dimms $*" [ -n "$bus_filter" ] && opts="$opts --bus=$bus_filter" [ -n "$reg_filter" ] && opts="$opts --region=$reg_filter" [ -n "$ns_filter" ] && opts="$opts --namespace=$ns_filter" echo "$(ndctl list $opts | grep -E "^\s*\"dev\":" | cut -d\" -f4)" } __ndctl_get_sector_sizes() { if [[ "$mode_filter" == @(raw|memory|fsdax) ]]; then echo "512 4096" elif [[ "$mode_filter" == @(dax|devdax) ]]; then return else echo "512 520 528 4096 4104 4160 4224" fi } __ndctl_get_nodes() { local nlist="" for node in /sys/devices/system/node/node*; do node="$(basename $node)" if [[ $node =~ node([0-9]+) ]]; then nlist="$nlist ${BASH_REMATCH[1]}" else continue fi done echo "$nlist" } saveopts="" __ndctl_file_comp() { local cur="$1" _filedir saveopts="${COMPREPLY[*]}" } __ndctl_comp_options() { local cur=$1 local opts if [[ "$cur" == *=* ]]; then local cur_subopt=${cur%%=*} local cur_arg=${cur##*=} case $cur_subopt in --bus) opts=$(__ndctl_get_buses) ;; --region) opts=$(__ndctl_get_regions) ;; --dimm) opts=$(__ndctl_get_dimms -i) ;; --namespace) opts=$(__ndctl_get_ns) ;; --reconfig) # It is ok to reconfig disabled namespaces opts=$(__ndctl_get_ns -i) ;; --type) opts="pmem blk" if [[ "$mode_filter" == @(dax|memory|fsdax|devdax) ]]; then opts="pmem" fi ;; --mode) opts="raw sector fsdax devdax" if [[ "$type_filter" == "blk" ]]; then opts="raw sector" fi ;; --sector-size) opts=$(__ndctl_get_sector_sizes) ;; --map) opts="mem dev" ;; --output) ;& --input) ;& --firmware) __ndctl_file_comp "$cur_arg" return ;; --label-version) opts="1.1 1.2" ;; --media-temperature-alarm) ;& --ctrl-temperature-alarm) ;& --spares-alarm) opts="on off" ;; --numa-node) opts=$(__ndctl_get_nodes) ;; --log) local my_args=( "standard" "syslog" ) __ndctl_file_comp "$cur_arg" if [ -n "$cur_arg" ]; then # if $cur_arg is a substring of $my_args (as # determined by compgen), then we continue to # manually construct opts using $my_args, but # if it is not a substring (compgen returns # empty), then we defer to _ndctl_file_comp # and return immediately. (NOTE: subscripting # of the my_args array here is fragile). # If this pattern repeats, where we need to # complete with filenames and some custom # options, find a better way to generalize this if [ -z "$(compgen -W "${my_args[*]}" -- "$cur_arg")" ]; then return fi fi opts="${my_args[*]} $saveopts" ;; --dimm-event) opts="all \ dimm-spares-remaining \ dimm-media-temperature \ dimm-controller-temperature \ dimm-health-state \ dimm-unclean-shutdown \ " ;; --config-file) __ndctl_file_comp "$cur_arg" return ;; --key-path) __ndctl_file_comp "$cur_arg" return ;; *) return ;; esac __ndctlcomp "$opts" "$cur_arg" fi } __ndctl_comp_non_option_args() { local subcmd=$1 local cur=$2 local opts case $subcmd in enable-namespace) opts="$(__ndctl_get_ns -i) all" ;; disable-namespace) ;& destroy-namespace) opts="$(__ndctl_get_ns -i) all" ;; check-namespace) opts="$(__ndctl_get_ns -i) all" ;; clear-errors) opts="$(__ndctl_get_ns) all" ;; enable-region) opts="$(__ndctl_get_regions -i) all" ;; disable-region) opts="$(__ndctl_get_regions) all" ;; enable-dimm) opts="$(__ndctl_get_dimms -i) all" ;; disable-dimm) opts="$(__ndctl_get_dimms) all" ;; init-labels) ;& check-labels) ;& read-labels) ;& write-labels) ;& zero-labels) opts="$(__ndctl_get_dimms -i) all" ;; inject-error) opts="$(__ndctl_get_ns -i)" ;; inject-smart) opts="$(__ndctl_get_dimms -i)" ;; wait-scrub) ;& start-scrub) opts="$(__ndctl_get_buses) all" ;; setup-passphrase) ;& update-passphrase) ;& remove-passphrase) ;& freeze-security) ;& sanitize-dimm) ;& wait-overwrite) opts="$(__ndctl_get_dimms -i) all" ;; *) return ;; esac __ndctlcomp "$opts" "$cur" } __ndctl_add_special_opts() { local subcmd=$1 case $subcmd in create-namespace) opts="$opts --no-autolabel" ;; esac } __ndctl_init_filters() { bus_filter='' reg_filter='' ns_filter='' dimm_filter='' type_filter='' idle_filter='' mode_filter='' for __word in "${words[@]}"; do if [[ "$__word" =~ --bus=(.*) ]]; then bus_filter="${BASH_REMATCH[1]}" # lets make sure this is in the list of buses local buses=$(__ndctl_get_buses) [[ "$buses" == *"$bus_filter"* ]] || bus_filter='' fi if [[ "$__word" =~ --region=(.*) ]]; then reg_filter="${BASH_REMATCH[1]}" # lets make sure this is in the list of regions local regions=$(__ndctl_get_regions -i) [[ "$regions" == *"$reg_filter"* ]] || reg_filter='' fi if [[ "$__word" =~ --namespace=(.*) ]]; then ns_filter="${BASH_REMATCH[1]}" # lets make sure this is in the list of namespaces local nss=$(__ndctl_get_ns -i) [[ "$nss" == *"$ns_filter"* ]] || ns_filter='' fi if [[ "$__word" =~ --dimm=(.*) ]]; then dimm_filter="${BASH_REMATCH[1]}" # lets make sure this is in the list of dimms local dimms=$(__ndctl_get_dimms) [[ "$dimms" == *"$dimm_filter"* ]] || dimm_filter='' fi if [[ "$__word" =~ --idle ]]; then idle_filter="1" fi if [[ "$__word" =~ --type=(.*) ]]; then type_filter="${BASH_REMATCH[1]}" fi if [[ "$__word" =~ --mode=(.*) ]]; then mode_filter="${BASH_REMATCH[1]}" fi done } __ndctl_main() { local cmd subcmd cmd=${words[0]} COMPREPLY=() __ndctl_init_filters # Skip options backward and find the last ndctl command __nd_common_prev_skip_opts subcmd=$prev_skip_opts # List ndctl subcommands or long options if [ -z $subcmd ]; then if [[ $cur == --* ]]; then cmds="--version --help --list-cmds" else cmds=$($cmd --list-cmds) fi __ndctlcomp "$cmds" "$cur" else # List long option names if [[ $cur == --* ]]; then opts=$($cmd $subcmd --list-opts) __ndctl_add_special_opts "$subcmd" __ndctlcomp "$opts" "$cur" __ndctl_comp_options "$cur" else [ -z "$subcmd" ] && return __ndctl_comp_non_option_args "$subcmd" "$cur" fi fi } if [[ -n ${ZSH_VERSION-} ]]; then autoload -U +X compinit && compinit __ndctlcomp() { emulate -L zsh local c IFS=$' \t\n' local -a array for c in ${=1}; do case $c in --*=*|*.) ;; *) c="$c " ;; esac array[${#array[@]}+1]="$c" done compset -P '*[=:]' compadd -Q -S '' -a -- array && _ret=0 } _ndctl() { local _ret=1 cur cword prev cur=${words[CURRENT]} prev=${words[CURRENT-1]} let cword=CURRENT-1 emulate ksh -c __ndctl_main let _ret && _default && _ret=0 return _ret } compdef _ndctl ndctl return fi type ndctl &>/dev/null && _ndctl() { local cur words cword prev if [ $preload_get_comp_words_by_ref = "true" ]; then _get_comp_words_by_ref -n =: cur words cword prev else __nd_common_get_comp_words_by_ref -n =: cur words cword prev fi __ndctl_main } ### daxctl ### __daxctl_get_devs() { local opts=("--devices" "$*") daxctl list "${opts[@]}" | grep -E "^\s*\"chardev\":" | cut -d'"' -f4 } __daxctl_get_regions() { local opts=("--regions" "$*") daxctl list "${opts[@]}" | grep -E "^\s*\"id\":" | grep -Eo "[0-9]+" } __daxctlcomp() { local i=0 COMPREPLY=( $( compgen -W "$1" -- "$2" ) ) for cword in "${COMPREPLY[@]}"; do if [[ "$cword" == @(--region|--dev|--mode) ]]; then COMPREPLY[$i]="${cword}=" else COMPREPLY[$i]="${cword} " fi ((i++)) done } __daxctl_comp_options() { local cur=$1 local opts if [[ "$cur" == *=* ]]; then local cur_subopt=${cur%%=*} local cur_arg=${cur##*=} case $cur_subopt in --region) opts="$(__daxctl_get_regions -i)" ;; --dev) opts="$(__daxctl_get_devs -i)" ;; --mode) opts="system-ram devdax" ;; *) return ;; esac __daxctlcomp "$opts" "$cur_arg" fi } __daxctl_comp_non_option_args() { local subcmd=$1 local cur=$2 local opts case $subcmd in reconfigure-device) ;& online-memory) ;& offline-memory) opts="$(__daxctl_get_devs -i) all" ;; *) return ;; esac __daxctlcomp "$opts" "$cur" } __daxctl_main() { local cmd subcmd cmd=${words[0]} COMPREPLY=() # Skip options backward and find the last daxctl command __nd_common_prev_skip_opts subcmd=$prev_skip_opts # List daxctl subcommands or long options if [ -z $subcmd ]; then if [[ $cur == --* ]]; then cmds="--version --help --list-cmds" else cmds=$($cmd --list-cmds) fi __daxctlcomp "$cmds" "$cur" else # List long option names if [[ $cur == --* ]]; then opts=$($cmd $subcmd --list-opts) __daxctlcomp "$opts" "$cur" __daxctl_comp_options "$cur" else [ -z "$subcmd" ] && return __daxctl_comp_non_option_args "$subcmd" "$cur" fi fi } type daxctl &>/dev/null && _daxctl() { local cur words cword prev if [ $preload_get_comp_words_by_ref = "true" ]; then _get_comp_words_by_ref -n =: cur words cword prev else __nd_common_get_comp_words_by_ref -n =: cur words cword prev fi __daxctl_main } ### cxl-cli ### __cxl_get_devs() { local opts=("--memdevs" "$*") cxl list "${opts[@]}" | grep -E "^\s*\"memdev\":" | cut -d'"' -f4 } __cxlcomp() { local i=0 COMPREPLY=( $( compgen -W "$1" -- "$2" ) ) for cword in "${COMPREPLY[@]}"; do if [[ "$cword" == @(--memdev|--offset|--size|--input|--output) ]]; then COMPREPLY[$i]="${cword}=" else COMPREPLY[$i]="${cword} " fi ((i++)) done } __cxl_comp_options() { local cur=$1 local opts if [[ "$cur" == *=* ]]; then local cur_subopt=${cur%%=*} local cur_arg=${cur##*=} case $cur_subopt in --memdev) opts="$(__cxl_get_devs -i)" ;; *) return ;; esac __cxlcomp "$opts" "$cur_arg" fi } __cxl_comp_non_option_args() { local subcmd=$1 local cur=$2 local opts case $subcmd in read-labels) ;& write-labels) ;& zero-labels) opts="$(__cxl_get_devs -i) all" ;; *) return ;; esac __cxlcomp "$opts" "$cur" } __cxl_main() { local cmd subcmd cmd=${words[0]} COMPREPLY=() # Skip options backward and find the last cxl command __nd_common_prev_skip_opts subcmd=$prev_skip_opts # List cxl subcommands or long options if [ -z $subcmd ]; then if [[ $cur == --* ]]; then cmds="--version --help --list-cmds" else cmds=$($cmd --list-cmds) fi __cxlcomp "$cmds" "$cur" else # List long option names if [[ $cur == --* ]]; then opts=$($cmd $subcmd --list-opts) __cxlcomp "$opts" "$cur" __cxl_comp_options "$cur" else [ -z "$subcmd" ] && return __cxl_comp_non_option_args "$subcmd" "$cur" fi fi } type cxl &>/dev/null && _cxl() { local cur words cword prev if [ $preload_get_comp_words_by_ref = "true" ]; then _get_comp_words_by_ref -n =: cur words cword prev else __nd_common_get_comp_words_by_ref -n =: cur words cword prev fi __cxl_main } complete -o nospace -F _ndctl ndctl complete -o nospace -F _daxctl daxctl complete -o nospace -F _cxl cxl