install-guest-agent.sh 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/bin/bash
  2. # KVM 虚拟机 QEMU Guest Agent 一键安装脚本
  3. # 用法: ./install-guest-agent.sh [VM_NAME]
  4. set -e
  5. AGENT_XML="/tmp/ga-channel.xml"
  6. CONTROLLER_XML="/tmp/ga-controller.xml"
  7. # 检查 virtio-serial controller 是否存在
  8. check_controller() {
  9. local vm="$1"
  10. if virsh dumpxml "$vm" | grep -q "type='virtio-serial'"; then
  11. return 0 # 存在
  12. fi
  13. return 1 # 不存在
  14. }
  15. # 添加 virtio-serial controller
  16. add_controller() {
  17. local vm="$1"
  18. cat > "$CONTROLLER_XML" << 'EOF'
  19. <controller type='virtio-serial' index='0'/>
  20. EOF
  21. virsh attach-device "$vm" "$CONTROLLER_XML" --config 2>/dev/null || true
  22. rm -f "$CONTROLLER_XML"
  23. }
  24. # 添加 guest agent channel
  25. add_channel() {
  26. local vm="$1"
  27. cat > "$AGENT_XML" << 'EOF'
  28. <channel type='unix'>
  29. <source mode='bind'/>
  30. <target type='virtio' name='org.qemu.guest_agent.0'/>
  31. </channel>
  32. EOF
  33. virsh attach-device "$vm" "$AGENT_XML" --live --config 2>/dev/null
  34. rm -f "$AGENT_XML"
  35. }
  36. # 安装 guest agent 到虚拟机内部
  37. install_agent_in_vm() {
  38. local vm="$1"
  39. echo "安装 Guest Agent 到 $vm ..."
  40. # 获取虚拟机 IP(用于 SSH)
  41. local ip=""
  42. if command -v virsh &>/dev/null; then
  43. ip=$(virsh domifaddr "$vm" 2>/dev/null | grep -oP '(\d+\.){3}\d+' | head -1)
  44. fi
  45. if [ -z "$ip" ]; then
  46. echo " 无法获取 $vm 的 IP 地址,跳过 Agent 安装"
  47. echo " 请手动在虚拟机内执行以下命令安装 Agent:"
  48. echo " CentOS/RHEL: yum install qemu-guest-agent"
  49. echo " Ubuntu/Debian: apt install qemu-guest-agent"
  50. return 0
  51. fi
  52. # 尝试 SSH 连接并安装
  53. ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 "$ip" "command -v yum &>/dev/null && yum install -y qemu-guest-agent || (command -v apt &>/dev/null && apt update && apt install -y qemu-guest-agent) || echo 'Agent 安装失败,请手动安装'" 2>/dev/null || true
  54. }
  55. # 单个虚拟机配置
  56. setup_one_vm() {
  57. local vm="$1"
  58. echo "=========================================="
  59. echo "配置虚拟机: $vm"
  60. # 检查虚拟机是否存在
  61. if ! virsh domstate "$vm" &>/dev/null; then
  62. echo " 错误: 虚拟机 $vm 不存在"
  63. return 1
  64. fi
  65. local state=$(virsh domstate "$vm")
  66. echo " 当前状态: $state"
  67. # 检查是否已有 guest-agent channel
  68. if virsh dumpxml "$vm" | grep -q "org.qemu.guest_agent"; then
  69. echo " ✓ Guest Agent channel 已配置,跳过"
  70. if [ "$state" = "running" ]; then
  71. echo " 检测 Guest Agent 连接状态..."
  72. virsh qemu-agent-command "$vm" '{"execute":"guest-info"}' 2>/dev/null && echo " ✓ Guest Agent 运行正常" || echo " ✗ Guest Agent 未响应"
  73. fi
  74. return 0
  75. fi
  76. # 检查 controller
  77. if ! check_controller "$vm"; then
  78. echo " 添加 virtio-serial 控制器..."
  79. add_controller "$vm"
  80. echo " ✓ 控制器添加成功(需要重启生效)"
  81. else
  82. echo " ✓ virtio-serial 控制器已存在"
  83. fi
  84. # 添加 channel
  85. echo " 添加 Guest Agent channel..."
  86. if add_channel "$vm"; then
  87. echo " ✓ Channel 配置成功"
  88. else
  89. echo " ✗ Channel 配置失败(虚拟机可能需要关机)"
  90. echo " 建议: virsh shutdown $vm && virsh edit $vm"
  91. return 1
  92. fi
  93. # 如果运行中,尝试安装 Agent
  94. if [ "$state" = "running" ]; then
  95. install_agent_in_vm "$vm"
  96. fi
  97. echo "=========================================="
  98. echo ""
  99. }
  100. # 批量配置所有运行中的虚拟机
  101. setup_all_vms() {
  102. echo "===== 批量配置所有虚拟机 ====="
  103. echo ""
  104. local vms=$(virsh list --all --name 2>/dev/null)
  105. if [ -z "$vms" ]; then
  106. echo "没有找到虚拟机"
  107. return
  108. fi
  109. for vm in $vms; do
  110. # 跳过模板和特殊虚拟机
  111. [[ "$vm" =~ ^(Template|base|.*-template)$ ]] && continue
  112. setup_one_vm "$vm"
  113. done
  114. echo "===== 配置完成 ====="
  115. echo ""
  116. echo "提示: 如果 Guest Agent 未响应,请重启虚拟机:"
  117. echo " virsh reboot <VM_NAME>"
  118. }
  119. # 主程序
  120. main() {
  121. echo "=========================================="
  122. echo " KVM Guest Agent 一键安装脚本"
  123. echo "=========================================="
  124. echo ""
  125. if [ -z "$1" ]; then
  126. echo "用法:"
  127. echo " $0 <VM_NAME> # 配置单个虚拟机"
  128. echo " $0 --all # 配置所有虚拟机"
  129. echo ""
  130. echo "示例:"
  131. echo " $0 myvm"
  132. echo " $0 --all"
  133. echo ""
  134. setup_all_vms
  135. elif [ "$1" = "--all" ]; then
  136. setup_all_vms
  137. else
  138. setup_one_vm "$1"
  139. fi
  140. }
  141. main "$@"