Home
qmenu-vm - qmenu - 🇶 manage qubes os via dmenu - fixed forked version HTML git clone https://git.drkhsh.at/qmenu.git DIR Log DIR Files DIR Refs DIR README DIR LICENSE --- qmenu-vm (39095B) --- 1 #!/bin/sh 2 3 fmenu_fqubes() ( 4 5 dmenu_fmc="-f -m 0" 6 7 chosefrom=0 8 9 while [ -n "$chosefrom" ]; do 10 11 chosefrom=$(printf "New qube\nGlobal preferences\nLogs" |\ 12 dmenu -l 3 -i -p "dom0:" $dmenu_fmc | awk '{print $1}') 13 14 case $chosefrom in 15 16 New) 17 18 fqvm_create;; 19 20 Global) 21 22 fqubes_preferences;; 23 24 Logs) 25 26 fqvm_logs;; 27 28 *) 29 esac 30 done 31 ) 32 33 fmenu_fqvm() ( 34 35 get_qube_label 36 37 chosefrom=0 38 39 while [ -n "$chosefrom" ]; do 40 41 chosefrom=$(printf "Applications\nAudio input devices\nBlock devices\nBoot\nBootfrom\nClone\nCommand\nDisk\nFirewall\nKeyboard\nKill\nLogs\nPause\nPCI devices\nPreferences\nReboot\nRemove\nServices\nShutdown\nTags\nUnpause\nUSB devices" |\ 42 dmenu -l 22 -i -p "$target_qube:" $dmenu_fmc |\ 43 awk '{print $1}') 44 45 case $chosefrom in 46 47 Applications) 48 49 fqvm_applications;; 50 51 Audio) 52 53 fqvm_devices;; 54 55 Block) 56 57 fqvm_devices;; 58 59 Boot) 60 61 qvm-start --skip-if-running "$target_qube"&;; 62 63 Bootfrom) 64 65 qubes-vm-boot-from-device "$target_qube";; 66 67 Clone) 68 69 fqvm_clone;; 70 71 Command) 72 73 fqvm_run;; 74 75 Disk) 76 77 fqvm_disk;; 78 79 Firewall) 80 81 fqvm_firewall;; 82 83 Keyboard) 84 85 fqvm_keyboard;; 86 87 Kill) 88 89 answer=$(printf "No\nYes" | dmenu -i -p "Kill $target_qube?" $dmenu_fmc) 90 91 if [ "$answer" = "Yes" ]; then 92 93 qvm-kill "$target_qube"& fi;; 94 95 Logs) 96 97 fqvm_logs;; 98 99 Pause) 100 101 answer=$(printf "No\nYes" | dmenu -i -p "Pause $target_qube?" $dmenu_fmc) 102 103 if [ "$answer" = "Yes" ]; then 104 105 qvm-pause "$target_qube"& fi;; 106 107 PCI) 108 109 fqvm_pci;; 110 111 Preferences) 112 113 fqvm_preferences;; 114 115 Reboot) 116 117 answer=$(printf "No\nYes" |\ 118 dmenu -i -p "Reboot $target_qube?" $dmenu_fmc) 119 120 if [ "$answer" = "Yes" ]; then 121 122 if qvm-check --running "$target_qube" > /dev/null 2>&1; then 123 124 $(qvm-shutdown --wait "$target_qube" && qvm-start "$target_qube")& 125 fi 126 fi;; 127 128 Remove) 129 130 fqvm_remove;; 131 132 Services) 133 134 fqvm_service;; 135 136 Shutdown) 137 138 answer=$(printf "No\nYes" |\ 139 dmenu -i -p "Shutdown $target_qube?" $dmenu_fmc) 140 141 if [ "$answer" = "Yes" ]; then 142 143 qvm-shutdown "$target_qube"& fi;; 144 145 Tags) 146 147 fqvm_tags;; 148 149 Unpause) 150 151 qvm-unpause "$target_qube"&;; 152 153 USB) 154 155 fqvm_devices;; 156 157 *) 158 esac 159 done 160 ) 161 162 fqubes_preferences() ( 163 164 property=0 165 166 while [ -n "$property" ]; do 167 168 property=$(qubes-prefs |\ 169 dmenu -l 16 -p "Global preferences:" $dmenu_fmc |\ 170 awk '{print $1}') 171 172 case $property in 173 174 check_updates_vm) 175 176 value_selected=$(printf "False\nTrue" |\ 177 dmenu -i -p "Should the system periodically check for domU updates?"\ 178 $dmenu_fmc);; 179 180 clockvm) 181 182 # List netvms via 'qvm-ls'. 183 value_selected=$(printf "$(qvm-ls --raw-data --fields NAME,FLAGS |\ 184 grep '|...N....$' | cut -d '|' -f1)" |\ 185 dmenu -l 50 -p "Select new ClockVM" $dmenu_fmc);; 186 187 default_dispvm) 188 189 if [ -n "$LIST_OF_DISPTEMP" ]; then unset LIST_OF_DISPTEMP; fi 190 191 # [mediocre] Look up disposable templates. 192 for n in $(qvm-ls --raw-data -O NAME,FLAGS |\ 193 grep '|a.......$' | cut -d '|' -f1); do 194 195 if qvm-prefs --get "$n" template_for_dispvms |\ 196 grep True > /dev/null 2>&1; then 197 198 LIST_OF_DISPTEMP="$LIST_OF_DISPTEMP\n$n" 199 fi 200 done 201 202 value_selected=$(printf "(None)$LIST_OF_DISPTEMP" |\ 203 dmenu -l 50 -p "Select default dispvm"\ 204 $dmenu_fmc) 205 206 if [ "$value_selected" = "(None)" ]; then 207 208 value_selected="none" 209 fi;; 210 211 default_kernel) 212 213 value_selected=$(true |\ 214 dmenu -p "Enter the kernel that is to be used as default"\ 215 $dmenu_fmc) 216 217 if [ -n "$value_selected" ]; then 218 219 answer_selected=$(printf "No\nYes" |\ 220 dmenu -i -p "Set default kernel to $value_selected?"\ 221 $dmenu_fmc) 222 223 if [ "$answer_selected" != "Yes" ]; then 224 225 unset $value_selected 226 fi 227 fi;; 228 229 default_netvm) 230 231 # List netvms via 'qvm-ls'. 232 value_selected=$(printf "$(qvm-ls --raw-data --fields NAME,FLAGS |\ 233 grep '|...N....$' | cut -d '|' -f1)" |\ 234 dmenu -l 50 -p "Select default netvm" $dmenu_fmc);; 235 236 default_pool) 237 238 value_selected=$(qvm-pool --list | sed '1d' |\ 239 dmenu -i -l 30 -p "Select default storage pool" \ 240 $dmenu_fmc | awk '{print $1}');; 241 242 default_pool_kernel) 243 244 value_selected=$(qvm-pool --list | sed '1d' |\ 245 dmenu -i -l 30 -p "Select default storage pool for kernel volumes" \ 246 $dmenu_fmc | awk '{print $1}');; 247 248 default_pool_private) 249 250 value_selected=$(qvm-pool --list | sed '1d' |\ 251 dmenu -i -l 30 -p "Select default storage pool for private volumes" \ 252 $dmenu_fmc | awk '{print $1}');; 253 254 default_pool_root) 255 256 value_selected=$(qvm-pool --list | sed '1d' |\ 257 dmenu -i -l 30 -p "Select default storage pool for root volumes" \ 258 $dmenu_fmc | awk '{print $1}');; 259 260 default_pool_volatile) 261 262 value_selected=$(qvm-pool --list | sed '1d' |\ 263 dmenu -i -l 30 -p "Select default storage pool for volatile volumes" \ 264 $dmenu_fmc | awk '{print $1}');; 265 266 default_qrexec_timeout) 267 268 value_selected=$(qubes-prefs --get default_qrexec_timeout |\ 269 dmenu -p "Enter the time in seconds, after which qrexec connection attempts are deemed a failure"\ 270 $dmenu_fmc);; 271 272 default_shutdown_timeout) 273 274 value_selected=$(qubes-prefs --get default_shutdown_timeout |\ 275 dmenu -p "Enter the default time in seconds for vm shutdowns to complete"\ 276 $dmenu_fmc);; 277 278 default_template) 279 280 # List templatevm's via 'qvm-ls'. 281 value_selected=$(qvm-ls --raw-data --fields NAME,FLAGS |\ 282 grep '|t.......$' | cut -d '|' -f1 |\ 283 dmenu -l 50 -p "Select default template for" $dmenu_fmc);; 284 285 management_dispvm) 286 287 if [ -n "$LIST_OF_DISPTEMP" ]; then unset LIST_OF_DISPTEMP; fi 288 289 # [mediocre] Look up disposable templates. 290 for n in $(qvm-ls --raw-data -O NAME,FLAGS |\ 291 grep '|a.......$' | cut -d '|' -f1); do 292 293 if qvm-prefs --get "$n" template_for_dispvms |\ 294 grep True > /dev/null 2>&1; then 295 296 if [ -z "$LIST_OF_DISPTEMP" ] 297 298 then LIST_OF_DISPTEMP=$n 299 300 else LIST_OF_DISPTEMP="$LIST_OF_DISPTEMP\n$n" 301 fi 302 fi 303 done 304 305 value_selected=$(printf "$LIST_OF_DISPTEMP" |\ 306 dmenu -l 50 -p "Select management dispvm"\ 307 $dmenu_fmc);; 308 309 stats_interval) 310 311 value_selected=$(true |\ 312 dmenu -p "Enter interval in seconds for VM stats reporting" $dmenu_fmc);; 313 314 updatevm) 315 316 # List netvms via 'qvm-ls'. 317 value_selected=$(printf "$(qvm-ls --raw-data --fields NAME,FLAGS |\ 318 grep '|...N....$' | cut -d '|' -f1)" |\ 319 dmenu -l 50 -p "Select new UpdateVM" $dmenu_fmc) 320 321 if [ -n "$value_selected" ]; then 322 323 if ! qvm-check --running "$value_selected" > /dev/null 2>&1; then 324 325 unset value_selected 326 327 echo "Go back..." |\ 328 dmenu -p "$value_selected needs to be running!"\ 329 $dmenu_fmc > /dev/null 2>&1 330 fi 331 fi;; 332 333 *) 334 esac 335 336 if [ -n "$value_selected" ]; then 337 338 if ! qubes-prefs --set "$property" "$value_selected"; then 339 340 echo "Go back..." |\ 341 dmenu -p "Error: Could not set $property to '$value_selected'!"\ 342 $dmenu_fmc > /dev/null 2>&1 343 fi 344 fi 345 done 346 ) 347 348 fqvm_applications() ( 349 350 option=0 351 352 while [ -n "$option" ]; do 353 354 option=$(printf "Available\nSelected" |\ 355 dmenu -i -l 2 -p "$target_qube:" $dmenu_fmc) 356 357 if [ "$option" = "Available" ]; then 358 359 applications=0 360 361 while [ -n "$applications" ]; do 362 363 # Only show applications that arent already selected for $target_qube via 'grep -v'. 364 applications=$(qvm-appmenus --get-available --i-understand-format-is-unstable "$target_qube" |\ 365 grep -vw "$(qvm-appmenus --get-whitelist --i-understand-format-is-unstable "$target_qube")" |\ 366 dmenu -l 50 -p "$target_qube:" $dmenu_fmc | awk '{print $1}') 367 368 if [ -n "$applications" ]; then 369 370 # Check validity of input. 371 if qvm-appmenus --get-available --i-understand-format-is-unstable "$target_qube" |\ 372 awk '{print $1}' | grep -w "$applications" > /dev/null 2>&1; then 373 374 printf "\n$applications" >> "$HOME"/.local/share/qubes-appmenus/"$target_qube"/whitelisted-appmenus.list 375 376 applications_modified=1 377 fi 378 fi 379 done 380 381 elif [ "$option" = "Selected" ]; then 382 383 applications=0 384 385 while [ -n "$applications" ]; do 386 387 # Show complete application and .desktop names via 'grep'. 388 applications=$(qvm-appmenus --get-available --i-understand-format-is-unstable "$target_qube" |\ 389 grep -w "$(qvm-appmenus --get-whitelist --i-understand-format-is-unstable "$target_qube")" |\ 390 dmenu -l 50 -p "$target_qube:" $dmenu_fmc | awk '{print $1}') 391 392 if [ -n "$applications" ]; then 393 394 for application in $applications; do 395 396 # Look up linenumber above $application in 397 # /whitelisted-appmenus.list and delete whitespace. 398 whitespace=$(grep -B1 -wn "$application" <\ 399 "$HOME"/.local/share/qubes-appmenus/"$target_qube"/whitelisted-appmenus.list |\ 400 cut -c 1 | sed 2d) 401 402 sed -i "${whitespace}{/^$/d;}" "$HOME"/.local/share/qubes-appmenus/"$target_qube"/whitelisted-appmenus.list 403 sed -i "/$application/d" "$HOME"/.local/share/qubes-appmenus/"$target_qube"/whitelisted-appmenus.list 404 405 applications_modified=1 406 done 407 fi 408 done 409 fi 410 411 # Only update qvm-appmenus down here, *after* the user 412 # has quit the application selection. 413 if [ -n "$applications_modified" ]; then 414 415 qvm-appmenus --update "$target_qube" > /dev/null 2>&1 416 417 unset applications_modified 418 fi 419 done 420 ) 421 422 fqvm_clone() ( 423 424 clone_name=$(true |\ 425 dmenu -p "Enter the name for the clone of $target_qube" $dmenu_fmc) 426 427 if [ -n "$clone_name" ]; then 428 429 option=0 430 431 while [ -n "$option" ]; do 432 433 option=$(printf "Create the clone\nAdvanced options" |\ 434 dmenu -i -l 2 -p "$target_qube:" $dmenu_fmc | awk '{print $1}') 435 436 if [ "$option" = "Advanced" ]; then 437 438 option_adv=0 439 440 while [ -n "$option_adv" ]; do 441 442 option_adv=$(printf "Class\nPool" |\ 443 dmenu -i -l 2 -p "$clone_name($target_qube):" $dmenu_fmc) 444 445 if [ "$option_adv" = "Class" ]; then 446 447 class=$(printf "AppVM\nDispVM\nStandaloneVM\nTemplateVM" |\ 448 dmenu -i -l 4 -p "Choose a class for $clone_name" $dmenu_fmc) 449 450 if [ -n "$pool" ]; then class="-C $class"; fi 451 452 elif [ "$option_adv" = "Pool" ]; then 453 454 pool=$(qvm-pool --list | sed '1d' |\ 455 dmenu -i -l 10 -p "Select a pool for $clone_name"\ 456 $dmenu_fmc | awk '{print $1}') 457 458 if [ -n "$pool" ]; then pool="-P $pool"; fi 459 fi 460 done 461 462 elif [ "$option" = "Create" ]; then 463 464 unset option 465 466 qvm-clone $class $pool "$target_qube" "$clone_name"& 467 fi 468 done 469 fi 470 ) 471 472 fqvm_create() ( 473 474 new_name=$(true | dmenu -p "Enter the name of the qube to create:" $dmenu_fmc) 475 476 if [ -n "$new_name" ]; then 477 478 label=$(printf "Purple\nBlue\nGray\nGreen\nYellow\nOrange\nRed\nBlack" |\ 479 dmenu -i -l 8 -p "Select label for $new_name" $dmenu_fmc |\ 480 awk '{print tolower($0)}') 481 482 if [ -n "$label" ]; then 483 484 QUBEARGS="-l $label" 485 486 class=$(printf "AppVM\nDispVM\nStandaloneVM\nTemplateVM" |\ 487 dmenu -i -l 4 -p "Choose a class for $new_name" $dmenu_fmc) 488 489 if [ -n "$class" ]; then 490 491 QUBEARGS="$QUBEARGS -C $class" 492 fi 493 494 # List templatevm's via 'qvm-ls'. 495 template=$(printf "(Default)\n(None)\n$(qvm-ls --raw-data --fields NAME,FLAGS |\ 496 grep '|t.......$' | cut -d '|' -f1)" |\ 497 dmenu -l 50 -p "Select template for $new_name" $dmenu_fmc) 498 499 if [ "$template" != "(Default)" ] && [ "$template" != "(None)" ]; then 500 501 QUBEARGS="$QUBEARGS -t $template" 502 fi 503 504 netvm=$(printf "(Default)\n(None)\n$(qvm-ls --raw-data --fields NAME,FLAGS |\ 505 grep '|...N....$' | cut -d '|' -f1)" |\ 506 dmenu -l 50 -p "Select netvm for $new_name" $dmenu_fmc) 507 508 if [ "$netvm" != "(Default)" ]; then 509 510 if [ "$netvm" = "(None)" ]; then unset netvm; fi 511 512 QUBEARGS="$QUBEARGS --prop netvm=$netvm" 513 fi 514 515 provides_network=$(printf "No\nYes" |\ 516 dmenu -i -p "Should $new_name provide networking for other qubes?" $dmenu_fmc) 517 518 if [ "$provides_network" = "Yes" ]; then 519 520 QUBEARGS="$QUBEARGS --prop provides_network=true" 521 fi 522 523 option=0 524 525 while [ -n "$option" ]; do 526 527 option=$(printf "Create the new qube\nAdvanced options" |\ 528 dmenu -i -l 2 -p "dom0:" $dmenu_fmc | awk '{print $1}') 529 530 if [ "$option" = "Advanced" ]; then 531 532 option_adv=$(printf "Pool" | dmenu -l 1 -p "$new_name:" $dmenu_fmc) 533 534 if [ "$option_adv" = "Pool" ]; then 535 536 pool=$(qvm-pool --list | sed '1d' |\ 537 dmenu -i -l 10 -p "Select a pool for $new_name" $dmenu_fmc |\ 538 awk '{print $1}') 539 540 if [ -n "$pool" ]; then pool="-P $pool"; fi 541 fi 542 543 elif [ "$option" = "Create" ]; then 544 545 qvm-create $QUBEARGS $pool "$new_name"& 546 547 unset option 548 fi 549 done 550 fi 551 fi 552 ) 553 554 fqvm_devices() ( 555 556 if ! qvm-check --running "$target_qube" > /dev/null 2>&1; then 557 558 echo "Go back..." |\ 559 dmenu -p "$target_qube needs to be running, in order to attach devices to it"\ 560 $dmenu_fmc > /dev/null 2>&1 561 else 562 563 # Depending on the device type, we have to 564 # 'awk' different fields later on. 565 if [ "$chosefrom" = "Audio" ]; then 566 567 device_type="device mic" 568 569 awk_devicename0=2 570 awk_devicename1=10 571 awk_targetqube=3 572 573 elif [ "$chosefrom" = "Block" ]; then 574 575 device_type="block" 576 577 awk_devicename0=2 578 awk_devicename1=3 579 awk_targetqube=4 580 581 elif [ "$chosefrom" = "USB" ]; then 582 583 device_type="usb" 584 585 awk_devicename0=2 586 awk_devicename1=10 587 awk_targetqube=3 588 fi 589 590 devices_list=$(qvm-$device_type) 591 592 device=0 593 594 while [ -n "$device" ]; do 595 596 device=$(echo "$devices_list" |\ 597 dmenu -l 16 -p "$target_qube:" $dmenu_fmc) 598 599 device_id=$(echo "$device" | awk '{print $1}') 600 601 device_name=$(echo "$device" |\ 602 awk '{print $'$awk_devicename0'$'$awk_devicename1'}') 603 604 if [ -n "$device" ]; then 605 606 holds_qube=$(echo "$devices_list" | grep "$device_id" |\ 607 awk '{print $'$awk_targetqube'}') 608 609 if [ -z "$holds_qube" ]; then 610 611 answer=$(printf "No\nYes" |\ 612 dmenu -i -p "Attach $device_name to $target_qube?"\ 613 $dmenu_fmc) 614 615 if [ "$answer" = "Yes" ]; then 616 617 unset device 618 619 qvm-$device_type attach "$target_qube" "$device_id"& 620 fi 621 622 elif [ "$holds_qube" = "$target_qube" ]; then 623 624 answer=$(printf "No\nYes" |\ 625 dmenu -i -p "Detach $device_name from $target_qube?"\ 626 $dmenu_fmc) 627 628 if [ "$answer" = "Yes" ]; then 629 630 unset device 631 632 qvm-$device_type detach "$holds_qube" "$device_id"& 633 fi 634 else 635 636 answer=$(printf "No\nYes" |\ 637 dmenu -i -p "Detach $device_name from $holds_qube and attach it to $target_qube?"\ 638 $dmenu_fmc) 639 640 if [ "$answer" = "Yes" ]; then 641 642 unset device 643 644 $(qvm-$device_type detach "$holds_qube" "$device_id" && 645 qvm-$device_type attach "$target_qube" "$device_id")& 646 fi 647 fi 648 fi 649 done 650 fi 651 ) 652 653 fqvm_disk() ( 654 655 qube_class=$(qvm-ls --raw-data -O flags "$target_qube" | cut -c 1) 656 657 # If $target_qube is template or standalone, give option to extend root storage. 658 if [ "$qube_class" = "t" ] ||\ 659 [ "$qube_class" = "s" ] ||\ 660 [ "$qube_class" = "S" ]; then 661 662 volume=$(printf "Root\nPrivate" |\ 663 dmenu -l 2 -i -p "$target_qube:" $dmenu_fmc | awk '{print tolower($0)}') 664 665 else 666 667 volume="private" 668 fi 669 670 if [ -n "$volume" ]; then 671 672 current_storage=$(( $(qvm-volume info "$target_qube:$volume" size) / 1024/1024 )) 673 674 mebibyte=$(echo "$current_storage" |\ 675 dmenu -p "Enter the maximum size of $volume storage in MiB to be allocated to $target_qube"\ 676 $dmenu_fmc) 677 678 if [ -n "$mebibyte" ]; then 679 680 if [ "$mebibyte" -gt "$current_storage" ]; then 681 682 byte=$(( mebibyte * 1024*1024 )) 683 684 answer=$(printf "No\nYes" |\ 685 dmenu -i -p "Increase the maximum $volume storage size of $target_qube from $current_storage MiB to $mebibyte MiB?"\ 686 $dmenu_fmc) 687 688 if [ "$answer" = "Yes" ]; then 689 690 qvm-volume extend "$target_qube:$volume" "$byte"& 691 fi 692 else 693 694 echo "Go back..." |\ 695 dmenu -p "Error: Can not decrease the maximum $volume storage!"\ 696 $dmenu_fmc > /dev/null 2>&1 697 fi 698 fi 699 fi 700 ) 701 702 fqvm_firewall() ( 703 704 rulenumber_selected=0 705 706 while [ -n "$rulenumber_selected" ]; do 707 708 rulenumber_selected=$(qvm-firewall $target_qube list |\ 709 dmenu -l 50 -p "$target_qube:" $dmenu_fmc | awk '{print $1}') 710 711 if [ -n "$rulenumber_selected" ]; then 712 713 # This will equal "NO" if the user selects the top row, 714 # instead of any existing rule. 715 if [ "$rulenumber_selected" != "NO" ]; then 716 717 option=$(printf "Add new rule above rule $rulenumber_selected\nRemove rule $rulenumber_selected" |\ 718 dmenu -i -l 2 -p "$target_qube:" $dmenu_fmc | awk '{print $1}') 719 else 720 721 option="Add" 722 fi 723 724 if [ "$option" = "Remove" ]; then 725 726 answer=$(printf "No\nYes" |\ 727 dmenu -i -p "Remove rule $rulenumber_selected?" $dmenu_fmc) 728 729 if [ "$answer" = "Yes" ]; then 730 731 qvm-firewall "$target_qube" del --rule-no "$rulenumber_selected" 732 fi 733 734 elif [ "$option" = "Add" ]; then 735 736 if [ -n "$RULEARGS" ]; then unset RULEARGS; fi 737 738 action=$(printf "Accept\nDrop" |\ 739 dmenu -i -l 2 -p "Select action for the new firewall rule" $dmenu_fmc |\ 740 awk '{print tolower($0)}') 741 742 if [ -n "$action" ]; then 743 744 RULEARGS="$action" 745 746 specialtarget=$(true |\ 747 dmenu -p "ACTION=$RULEARGS <specialtarget>" $dmenu_fmc) 748 749 if [ -n "$specialtarget" ]; then 750 751 RULEARGS="$RULEARGS SPECIALTARGET=$specialtarget" 752 fi 753 754 dsthost=$(true |\ 755 dmenu -p "ACTION=$RULEARGS <dsthost>" $dmenu_fmc) 756 757 if [ -n "$dsthost" ]; then 758 759 RULEARGS="$RULEARGS DSTHOST=$dsthost" 760 fi 761 762 proto=$(true |\ 763 dmenu -p "ACTION=$RULEARGS <proto>" $dmenu_fmc) 764 765 if [ -n "$proto" ]; then 766 767 RULEARGS="$RULEARGS PROTO=$proto" 768 fi 769 770 if [ "$proto" = "tcp" ] || [ "$proto" = "udp" ]; then 771 772 dstports=$(true |\ 773 dmenu -p "ACTION=$RULEARGS <dstports>" $dmenu_fmc) 774 775 if [ -n "$dstports" ]; then 776 777 RULEARGS="$RULEARGS DSTPORTS=$dstports" 778 fi 779 780 elif [ "$proto" = "icmp" ]; then 781 782 icmptype=$(true |\ 783 dmenu -p "ACTION=$RULEARGS <icmptype>" $dmenu_fmc) 784 785 if [ -n "$icmptype" ]; then 786 787 RULEARGS="$RULEARGS ICMPTYPE=$icmptype" 788 fi 789 fi 790 791 expire=$(true |\ 792 dmenu -p "ACTION=$RULEARGS <expire>" $dmenu_fmc) 793 794 if [ -n "$expire" ]; then 795 796 RULEARGS="EXPIRE=$expire" 797 fi 798 799 comment=$(true |\ 800 dmenu -p "ACTION=$RULEARGS <comment>" $dmenu_fmc) 801 802 if [ -n "$comment" ]; then 803 804 RULEARGS="$RULEARGS COMMENT=$comment" 805 fi 806 807 answer=$(printf "No\nYes" |\ 808 dmenu -i -p "Add the following rule to $target_qube? {{ ACTION=$RULEARGS }}"\ 809 $dmenu_fmc) 810 811 if [ "$answer" = "Yes" ]; then 812 813 if [ -n "$beforerule" ]; then unset beforerule; fi 814 815 if [ "$rulenumber_selected" != "NO" ]; then 816 817 beforerule=$(echo --before "$rulenumber_selected") 818 fi 819 820 RULEARGS=$(echo "$RULEARGS" | awk '{print tolower($0)}') 821 822 if ! qvm-firewall "$target_qube" add $beforerule $RULEARGS; then 823 824 echo "Go back..." | dmenu $dmenu_fmc\ 825 -p "Error: Failed to add firewall rule! See 'qvm-firewall --help' for more information."\ 826 > /dev/null 2>&1 827 fi 828 fi 829 fi 830 fi 831 fi 832 done 833 ) 834 835 fqvm_keyboard() ( 836 837 # 'qmenu-vm' does not get informed about the installed layouts by the vm itself 838 # so it is possible that the selected layout is missing inside the vm. 839 # Getting the info from the vm itself however would have security implications 840 # so we will not switch to use that method. 841 LAYOUT=$(ls /usr/share/X11/xkb/symbols |\ 842 dmenu -l 50 -p "$target_qube:" $dmenu_fmc) 843 844 if [ -n "$LAYOUT" ]; then 845 846 if test -d /usr/share/X11/xkb/symbols/$LAYOUT; then 847 848 LAYOUT="$LAYOUT/"$(ls /usr/share/X11/xkb/symbols/"$LAYOUT" |\ 849 dmenu -l 50 -p "$target_qube:" $dmenu_fmc) 850 fi 851 852 if ! qvm-run "$target_qube" "setxkbmap $LAYOUT"; then 853 854 echo "Go back..." |\ 855 dmenu -p "Error: Could not set keyboard layout to '$LAYOUT' in $target_qube! Please check the installed layouts inside the qube itself."\ 856 $dmenu_fmc > /dev/null 2>&1 857 fi 858 fi 859 ) 860 861 fqvm_logs() ( 862 863 if [ "$target_qube" = "dom0" ]; then 864 865 logs="/var/log/xen/console/hypervisor.log" 866 else 867 868 logs="/var/log/xen/console/guest-$target_qube.log\n/var/log/qubes/guid.$target_qube.log\n/var/log/qubes/qrexec.$target_qube.log" 869 fi 870 871 entry=0 872 873 while [ -n "$entry" ]; do 874 875 entry=$(printf "$logs" |\ 876 dmenu -i -l 3 -p "$target_qube:" $dmenu_fmc) 877 878 if [ -n "$entry" ]; then 879 880 log=$(dmenu -l 20 -p "$target_qube:" $dmenu_fmc < "$entry") 881 882 if [ -n "$log" ]; then 883 884 echo "$log" > /var/run/qubes/qubes-clipboard.bin 885 886 printf "dom0" > /var/run/qubes/qubes-clipboard.bin.source 887 fi 888 fi 889 done 890 ) 891 892 fqvm_pci() ( 893 894 if qvm-check --running "$target_qube" > /dev/null 2>&1; then 895 896 echo "Go back..." |\ 897 dmenu -p "$target_qube needs to be powered off, in order to attach or detach PCI devices"\ 898 $dmenu_fmc > /dev/null 2>&1 899 else 900 901 list_pci=$(qvm-pci) 902 903 if ! qvm-prefs --get "$target_qube" maxmem | grep -w 0 > /dev/null 2>&1; then 904 905 answer_memorybalancing=$(printf "Continue anyways\nDisable dynamic memory balancing" |\ 906 dmenu -l 2 -i -p "Dynamic memory balancing is enabled in $target_qube, some devices might not work!"\ 907 $dmenu_fmc | awk '{print $1}') 908 909 if [ "$answer_memorybalancing" = "Disable" ]; then 910 911 qvm-prefs --set "$target_qube" maxmem 0 912 fi 913 fi 914 915 if qvm-prefs --get "$target_qube" virt_mode |\ 916 grep -w pvh > /dev/null 2>&1; then 917 918 answer_virtmode=$(printf "Continue anyways\nSelect another virtualisation mode" |\ 919 dmenu -l 2 -i -p "$target_qube is using PVH for its virtualisation mode, which does not support PCI passthrough!"\ 920 $dmenu_fmc | awk '{print $1}') 921 922 if [ "$answer_virtmode" = "Select" ]; then 923 924 virtmode_selected=$(printf "HVM\nPV" |\ 925 dmenu -l 2 -i -p "Select virtualisation mode for $target_qube" $dmenu_fmc) 926 927 if [ -n "$virtmode_selected" ]; then 928 929 qvm-prefs --set "$target_qube" virt_mode "$virtmode_selected" 930 fi 931 fi 932 fi 933 934 device_selected=0 935 936 while [ -n "$device_selected" ]; do 937 938 device_selected=$(echo "$list_pci" |\ 939 dmenu -l 30 -p "$target_qube:" $dmenu_fmc) 940 941 if [ -n "$device_selected" ]; then 942 943 device_src=$(echo "$device_selected" | awk '{print $1}' | sed 's/:.*//') 944 device_bdf=$(echo "$device_selected" | awk '{print $1}' | sed 's/.*://') 945 946 if echo "$device_selected" | grep -w "$target_qube"; then 947 948 answer=$(printf "No\nYes" |\ 949 dmenu -i -p "Detach \"$device_bdf\" from $target_qube?" $dmenu_fmc) 950 951 if [ "$answer" = "Yes" ]; then 952 953 if ! test_qvm-pci detach "$target_qube" "$device_src":"$device_bdf"; then 954 955 echo "Go back..." |\ 956 dmenu -p "Error: Failed to detach \"$device_bdf\" from $target_qube!"\ 957 $dmenu_fmc > /dev/null 2>&1 958 fi 959 960 list_pci=$(qvm-pci) 961 fi 962 else 963 964 answer=$(printf "No\nYes" |\ 965 dmenu -i -p "Attach \"$device_bdf\" to $target_qube?" $dmenu_fmc) 966 967 if [ "$answer" = "Yes" ]; then 968 969 # Check if there is more than one function 970 # that belongs to the same device. 971 bdf_count=$(echo "$list_pci" | awk '{print $1}' |\ 972 grep -c $(echo "$device_bdf" | sed 's/\..*//')) 973 974 if [ "$bdf_count" -gt 1 ]; then 975 976 if [ -n "$pci_option" ]; then unset pci_option; fi 977 978 answer_nsrt=$(printf "No\nYes" |\ 979 dmenu -i -p "\"$device_bdf\" is most likely to be attached with the option 'no-strict-reset' enabled. Please be aware of the security implications! Do you want to attach \"$device_bdf\" with the option 'no-strict-reset' set to true?"\ 980 $dmenu_fmc) 981 982 if [ "$answer_nsrt" = "Yes" ]; then 983 984 pci_option="-o no-strict-reset=True" 985 fi 986 fi 987 988 if ! qvm-pci attach --persistent $pci_option "$target_qube" "$device_src:$device_bdf"; then 989 990 echo "Go back..." |\ 991 dmenu -p "Error: Failed to attach \"$device_bdf\" to $target_qube!"\ 992 $dmenu_fmc > /dev/null 2>&1 993 fi 994 995 list_pci=$(qvm-pci) 996 fi 997 fi 998 fi 999 done 1000 fi 1001 ) 1002 1003 fqvm_preferences() ( 1004 1005 property=0 1006 1007 while [ -n "$property" ]; do 1008 1009 property=$(qvm-prefs "$target_qube" |\ 1010 dmenu -l 45 -p "$target_qube:" $dmenu_fmc |\ 1011 awk '{print $1}') 1012 1013 if [ -n "$property" ]; then 1014 1015 case $property in 1016 1017 autostart) 1018 1019 value_selected=$(printf "False\nTrue" |\ 1020 dmenu -i -p "Set autostart of $target_qube to:" $dmenu_fmc);; 1021 1022 debug) 1023 1024 value_selected=$(printf "False\nTrue" |\ 1025 dmenu -i -p "Set debug mode of $target_qube to:" $dmenu_fmc);; 1026 1027 default_dispvm) 1028 1029 if [ -n "$LIST_OF_DISPTEMP" ]; then unset LIST_OF_DISPTEMP; fi 1030 1031 # [mediocre] Look up disposable templates. 1032 for n in $(qvm-ls --raw-data -O NAME,FLAGS |\ 1033 grep '|a.......$' | cut -d '|' -f1); do 1034 1035 if qvm-prefs --get "$n" template_for_dispvms |\ 1036 grep True > /dev/null 2>&1; then 1037 1038 LIST_OF_DISPTEMP="$LIST_OF_DISPTEMP\n$n" 1039 fi 1040 done 1041 1042 value_selected=$(printf "(Default)\n(None)$LIST_OF_DISPTEMP" |\ 1043 dmenu -l 50 -p "Select default dispvm for $target_qube" $dmenu_fmc) 1044 1045 if [ "$value_selected" = "(None)" ]; then 1046 1047 value_selected="None" 1048 1049 elif [ "$value_selected" = "(Default)" ]; then 1050 1051 value_selected="--default" 1052 fi;; 1053 1054 default_user) 1055 1056 value_selected=$(echo "--default" |\ 1057 dmenu -p "Enter the name of the default user for $target_qube"\ 1058 $dmenu_fmc);; 1059 1060 include_in_backups) 1061 1062 value_selected=$(printf "False\nTrue" |\ 1063 dmenu -i -p "Include $target_qube in backups?" $dmenu_fmc);; 1064 1065 kernel) 1066 1067 value_selected=$(echo "--default" |\ 1068 dmenu -p "Enter kernel to be used by $target_qube" $dmenu_fmc) 1069 1070 if [ -n "$value_selected" ]; then 1071 1072 answer_selected=$(printf "No\nYes" |\ 1073 dmenu -i -p "Set kernel of $target_qube to $value_selected?"\ 1074 $dmenu_fmc) 1075 1076 if [ "$answer_selected" != "Yes" ]; then 1077 1078 unset value_selected 1079 fi 1080 fi;; 1081 1082 kernelopts) 1083 1084 value_selected=$(echo "--default" |\ 1085 dmenu -p "Enter kernel options for $target_qube" $dmenu_fmc) 1086 1087 if [ -n "$value_selected" ]; then 1088 1089 answer_selected=$(printf "No\nYes" |\ 1090 dmenu -i -p "Set kernel options for $target_qube to \"$value_selected\"?"\ 1091 $dmenu_fmc) 1092 1093 if [ "$answer_selected" != "Yes" ]; then 1094 1095 unset value_selected 1096 fi 1097 fi;; 1098 1099 label) 1100 1101 if qvm-check --running "$target_qube" > /dev/null 2>&1; then 1102 1103 echo "Go back..." |\ 1104 dmenu -p "$target_qube needs to be powered off, in order to change its label"\ 1105 $dmenu_fmc > /dev/null 2>&1 1106 else 1107 1108 value_selected=$(printf "Purple\nBlue\nGray\nGreen\nYellow\nOrange\nRed\nBlack" |\ 1109 dmenu -i -l 8 -p "Select label for $target_qube" $dmenu_fmc |\ 1110 awk '{print tolower($0)}') 1111 fi;; 1112 1113 mac) 1114 1115 value_selected=$(echo "--default" |\ 1116 dmenu -p "Enter new MAC address for $target_qube" $dmenu_fmc) 1117 1118 if [ -n "$value_selected" ]; then 1119 1120 answer_selected=$(printf "No\nYes" |\ 1121 dmenu -i -p "Set MAC address of $target_qube to $value_selected?"\ 1122 $dmenu_fmc) 1123 1124 if [ "$answer_selected" != "Yes" ]; then 1125 1126 unset value_selected 1127 fi 1128 fi;; 1129 1130 maxmem) 1131 1132 value_selected=$(echo "--default" |\ 1133 dmenu -p "Enter the maximum amount of memory in MB to be allocated to $target_qube. Setting it to 0 will disable dynamic memory balancing."\ 1134 $dmenu_fmc) 1135 1136 if [ -n "$value_selected" ]; then 1137 1138 answer_selected=$(printf "No\nYes" |\ 1139 dmenu -i -p "Set maximum memory of $target_qube to $value_selected MB?"\ 1140 $dmenu_fmc) 1141 1142 if [ "$answer_selected" != "Yes" ]; then 1143 1144 unset value_selected 1145 fi 1146 fi;; 1147 1148 memory) 1149 1150 value_selected=$(echo "--default" |\ 1151 dmenu -p "Enter the amount of initial memory in MB to be allocated to $target_qube"\ 1152 $dmenu_fmc) 1153 1154 if [ -n "$value_selected" ]; then 1155 1156 answer_selected=$(printf "No\nYes" |\ 1157 dmenu -i -p "Set initial memory of $target_qube to $value_selected MB?" $dmenu_fmc) 1158 1159 if [ "$answer_selected" != "Yes" ]; then 1160 1161 unset answer_selected 1162 fi 1163 fi;; 1164 1165 netvm) 1166 1167 # List netvms via 'qvm-ls'. 1168 value_selected=$(printf "(Default)\n(None)\n$(qvm-ls --raw-data --fields NAME,FLAGS |\ 1169 grep '|...N....$' | cut -d '|' -f1)" |\ 1170 dmenu -l 50 -p "Select netvm for $target_qube" $dmenu_fmc) 1171 1172 if [ "$value_selected" = "(None)" ]; then 1173 1174 value_selected="None" 1175 1176 elif [ "$value_selected" = "(Default)" ]; then 1177 1178 value_selected="--default" 1179 fi;; 1180 1181 provides_network) 1182 1183 value_selected=$(printf "False\nTrue" |\ 1184 dmenu -i -p "Should $target_qube provide networking for other qubes?"\ 1185 $dmenu_fmc);; 1186 1187 qrexec_timeout) 1188 1189 value_selected=$(echo "--default" |\ 1190 dmenu -p "Enter the time in seconds, after which qrexec attempt is deemed a failure for $target_qube"\ 1191 $dmenu_fmc) 1192 1193 if [ -n "$value_selected" ]; then 1194 1195 answer_selected=$(printf "No\nYes" |\ 1196 dmenu -i -p "Set qrexec timeout for $target_qube to $value_selected seconds?"\ 1197 $dmenu_fmc) 1198 1199 if [ "$answer_selected" != "Yes" ]; then 1200 1201 unset value_selected 1202 fi 1203 fi;; 1204 1205 shutdown_timeout) 1206 1207 value_selected=$(echo "--default" |\ 1208 dmenu -p "Enter the time in seconds for shutdown, after which $target_qube may be forcefully powered off"\ 1209 $dmenu_fmc) 1210 1211 if [ -n "$value_selected" ]; then 1212 1213 answer_selected=$(printf "No\nYes" |\ 1214 dmenu -i -p "Set shutdown timeout for $target_qube to $value_selected seconds?"\ 1215 $dmenu_fmc) 1216 1217 if [ "$answer_selected" != "Yes" ]; then 1218 1219 unset value_selected 1220 fi 1221 fi;; 1222 1223 template) 1224 1225 if qvm-check --running "$target_qube" > /dev/null 2>&1; then 1226 1227 echo "Go back..." |\ 1228 dmenu -p "$target_qube needs to be powered off, in order to change its template"\ 1229 $dmenu_fmc > /dev/null 2>&1 1230 else 1231 1232 # List templatevm's via 'qvm-ls'. 1233 value_selected=$(printf "(Default)\n$(qvm-ls --raw-data --fields NAME,FLAGS |\ 1234 grep '|t.......$' | cut -d '|' -f1)" |\ 1235 dmenu -l 50 -p "Select template for $target_qube" $dmenu_fmc) 1236 1237 if [ "$value_selected" = "(Default)" ]; then 1238 1239 value_selected="--default" 1240 fi 1241 fi;; 1242 1243 template_for_dispvms) 1244 1245 value_selected=$(printf "False\nTrue" |\ 1246 dmenu -i -p "Should $target_qube be used as a template for disposable qubes?"\ 1247 $dmenu_fmc);; 1248 1249 vcpus) 1250 1251 value_selected=$(echo "--default" |\ 1252 dmenu -p "Enter the number of CPU cores that should be made available to $target_qube"\ 1253 $dmenu_fmc) 1254 1255 if [ -n "$value_selected" ]; then 1256 1257 answer_selected=$(printf "No\nYes" |\ 1258 dmenu -i -p "Set number of CPU cores available to $target_qube to $value_selected?"\ 1259 $dmenu_fmc) 1260 1261 if [ "$answer_selected" != "Yes" ]; then 1262 1263 unset value_selected 1264 fi 1265 fi;; 1266 1267 virt_mode) 1268 1269 value_selected=$(printf "PVH\nHVM\nPV" |\ 1270 dmenu -i -l 3 -p "Select virtualisation mode for $target_qube"\ 1271 $dmenu_fmc);; 1272 1273 *) 1274 esac 1275 1276 if [ -n "$value_selected" ]; then 1277 1278 if ! qvm-prefs --set "$target_qube" "$property" "$value_selected"; then 1279 1280 echo "Go back..." |\ 1281 dmenu -p "Error: Could not set $property to '$value_selected'!"\ 1282 $dmenu_fmc > /dev/null 2>&1 1283 fi 1284 1285 unset value_selected 1286 fi 1287 fi 1288 done 1289 ) 1290 1291 fqvm_remove() { 1292 1293 if qvm-check --running "$target_qube" > /dev/null 2>&1; then 1294 1295 echo "Go back..." |\ 1296 dmenu -p "$target_qube needs to be powered off, in order to be removed"\ 1297 $dmenu_fmc > /dev/null 2>&1 1298 else 1299 1300 confirmation=$(true |\ 1301 dmenu -p "Enter the name of the qube '$target_qube' in order to remove it"\ 1302 $dmenu_fmc) 1303 1304 if [ "$target_qube" = "$confirmation" ]; then 1305 1306 confirmation_semifinal=$(printf "No\nYes" |\ 1307 dmenu -i -p "Are you sure you want to remove $target_qube permanently?"\ 1308 $dmenu_fmc) 1309 1310 if [ "$confirmation_semifinal" = "Yes" ]; then 1311 1312 confirmation_final=$(printf "No\nYes" | 1313 dmenu -i -p "Are you really sure you want to remove $target_qube permanently?"\ 1314 $dmenu_fmc) 1315 1316 if [ "$confirmation_final" = "Yes" ]; then 1317 1318 qvm-remove -f "$target_qube"& 1319 1320 unset chosefrom 1321 fi 1322 fi 1323 fi 1324 fi 1325 } 1326 1327 fqvm_run() ( 1328 1329 commandtr=$(true |\ 1330 dmenu -p "Run command in $target_qube:" $dmenu_fmc) 1331 1332 if [ -n "$commandtr" ]; then qvm-run "$target_qube" "$commandtr"& fi 1333 ) 1334 1335 fqvm_service() ( 1336 1337 service=0 1338 1339 while [ -n "$service" ]; do 1340 1341 service=$(qvm-service "$target_qube" --list |\ 1342 dmenu -l 32 -p "$target_qube:" $dmenu_fmc | awk '{print $1}') 1343 1344 if [ -n "$service" ]; then 1345 1346 # If the service has already been added to the list, 1347 # give option to unset it. 1348 if qvm-service "$target_qube" --list | grep -w "$service"; then 1349 1350 unset="\nUnset" 1351 fi 1352 1353 value=$(printf "Disable\nEnable$unset" |\ 1354 dmenu -l 3 -i -p "Select value for '$service'" $dmenu_fmc) 1355 1356 if [ "$value" = "Disable" ]; then 1357 1358 if ! qvm-service "$target_qube" "$service" off; then 1359 1360 echo "Go back..." | dmenu -p "Error: Could not deactivate $service!"\ 1361 $dmenu_fmc > /dev/null 2>&1 1362 fi 1363 1364 elif [ "$value" = "Enable" ]; then 1365 1366 if ! qvm-service "$target_qube" "$service" on; then 1367 1368 echo "Go back..." | dmenu -p "Error: Could not activate $service!"\ 1369 $dmenu_fmc > /dev/null 2>&1 1370 fi 1371 1372 elif [ "$value" = "Unset" ]; then 1373 1374 if ! qvm-service "$target_qube" "$service" --unset; then 1375 1376 echo "Go back..." | dmenu -p "Error: Could not unset $service!"\ 1377 $dmenu_fmc > /dev/null 2>&1 1378 fi 1379 fi 1380 1381 if [ -n "$unset" ]; then unset unset; fi 1382 fi 1383 done 1384 ) 1385 1386 fqvm_tags() ( 1387 1388 tag=0 1389 1390 while [ -n "$tag" ]; do 1391 1392 tag=$(qvm-tags "$target_qube" list |\ 1393 dmenu -l 15 -p "$target_qube:" $dmenu_fmc | awk '{print $1}') 1394 1395 if [ -n "$tag" ]; then 1396 1397 if qvm-tags "$target_qube" list | grep -w "$tag"; then 1398 1399 answer=$(printf "No\nYes" |\ 1400 dmenu -i -p "Remove tag '$tag' from $target_qube?" $dmenu_fmc) 1401 1402 if [ "$answer" = "Yes" ]; then 1403 1404 qvm-tags "$target_qube" del "$tag" 1405 fi 1406 else 1407 1408 qvm-tags "$target_qube" add "$tag" 1409 fi 1410 fi 1411 done 1412 ) 1413 1414 get_qube_label() { 1415 1416 qube_label=$(qvm-ls --raw-data "$target_qube" -O LABEL) 1417 1418 # Change label colors according to ~/.config/qmenu.conf if that file exists. 1419 if [ -f "$HOME/.config/qmenu.conf" ]; then 1420 1421 qube_label=$(grep "^$qube_label=" "$HOME"/.config/qmenu.conf | cut -d= -f2) 1422 fi 1423 1424 # Note that the '-m 0' option in 'dmenu' is important 1425 # for security, as it restricts it to monitor 0. 1426 dmenu_fmc="-f -m 0 -sb $qube_label" 1427 } 1428 1429 rearrange_qube_list() { 1430 1431 qube_list=$(echo "$qube_list" |\ 1432 awk -v ListInOrder="LABEL,purple,blue,gray,green,yellow,orange,red,black" ' 1433 BEGIN { 1434 split(ListInOrder, a, ",") 1435 for (i = 1; i <= length(a); ++i) ListToOrdinal[a[i]] = i 1436 } 1437 {print ListToOrdinal[$3] "-" $0} 1438 ' | sort -t- -k1,1n | cut -d- -f2-) 1439 } 1440 1441 case $1 in 1442 1443 --all) 1444 1445 # As of 20190823, 'qvm-ls --all' will not list dom0 because of a bug. 1446 # As a workaround, we will 'shift' $1 and, if needed, $2. 1447 shift 1448 if [ -n "$1" ]; then shift; fi;; 1449 1450 --focused) 1451 1452 target_qube=$(xprop -id "$(xdotool getwindowfocus)" |\ 1453 grep -w '^_QUBES_VMNAME(STRING)' | cut -d\" -f2) 1454 1455 if [ -z "$target_qube" ]; then 1456 1457 target_qube=dom0 1458 1459 fmenu_fqubes 1460 else 1461 1462 fmenu_fqvm 1463 fi 1464 1465 exit 1;; 1466 1467 --halted|--paused|--running|--tags=*);; 1468 1469 *) 1470 1471 printf "qmenu-vm [OPTION]\nList, manage and configure your qubes.\n\n --all\n --focused\n --halted\n --paused\n --running\n --tags=[TAG]\n\n\nqmenu v1.3\n<https://github.com/sine3o14nnae/qmenu/>\n<https://gitlab.com/sine3o14nnae/qmenu/>\n\n" 1472 1473 if [ "$1" = "--help" ]; then exit 0; else exit 2; fi 1474 esac 1475 1476 while true; do 1477 1478 # Load 'qvm-ls' into a variable so that it doesnt 1479 # need to reload again after every user operation. 1480 qube_list=$(qvm-ls --no-spinner $1 -O NAME,STATE,LABEL,CLASS\ 1481 ,TEMPLATE,NETVM,IP,PRIV-MAX,PRIV-CURR,PRIV-USED,ROOT-MAX\ 1482 ,ROOT-CURR,ROOT-USED,KERNEL,KERNELOPTS) 1483 1484 rearrange_qube_list 1485 1486 if [ -n "$target_qube" ]; then unset target_qube; fi 1487 1488 # Get out of the while loop and refresh 'qvm-ls' by loading it again 1489 # into $qube_list, whenever the user selects the 'qvm-ls' top row. 1490 while [ "$target_qube" != "NAME" ]; do 1491 1492 target_qube=$(echo "$qube_list" | dmenu -f -m 0 -l 69 |\ 1493 awk '{print $1}') 1494 1495 if [ -z "$target_qube" ]; then exit 1 1496 1497 elif [ "$target_qube" != "NAME" ]; then 1498 1499 if [ "$target_qube" = "dom0" ]; then 1500 1501 fmenu_fqubes 1502 else 1503 1504 fmenu_fqvm 1505 fi 1506 fi 1507 done 1508 done