1

私はいくつかのオープン ソース ソフトウェアのパッチを作成しようとしています。なぜなら、それは私が望んでいたことをまったく実行しないからです。ただし、私は Python をまったく知りません! これは非常に単純だと思いますが、私を打ち負かしています。

背景:私が書いているパッチは、KVM 仮想マシン クラスタの管理に使用している Ganeti 用のものですが、USB パススルーなど、KVM と Qemu の可能なすべてのコマンド ライン オプションをサポートしていないため、これを許可するように変更します。

kvm_cmd.extend()VM の起動時に渡される KVM CLI 引数の配列に追加するために使用されます。引数がスペースで区切られている場合、各引数は個別の文字列に-usb -device usb-host,hostbus=1,hostdev=14なり"-usb", "-device", "usb-host,hostbus=1,hostdev=14"ます。

コードをコンパイルした後、次のコマンドを実行しています。

gnt-instance modify -H usb_pass="1;14"

これをコマンド ライン引数の既存のリストに追加します"-usb -device usb-host,hostbus=1,hostdev=14"。これは私が追加したコードです(変数を他の場所で宣言するだけでなくHV_USBPASSTHROUGH、文字列ですが、ここで魔法が起こります)

usb_pass = instance.hvparams[constants.HV_USBPASSTHROUGH]
if usb_pass:
    usb_pass_arr = []
    usb_pass_arr = usb_pass.split(";")
    kvm_cmd.extend(["-usb", "-device", "usb-host,hostbus=%s,hostaddr=%s" %
                    usb_pass_arr])

上記のコードで上記のコマンドを実行すると、次のエラーが発生します。 Could not start instance: Error while executing backend function: not enough arguments for format string

4

7 に答える 7

7

あなたは2つ持って`%s"usb-host,hostbus=%s,hostaddr=%s"ますが、タプルが期待されるリストである引数を1つだけ提供します。

使用する

"usb-host,hostbus=%s,hostaddr=%s" % tuple(usb_pass_arr)

tuple()ビルトインは iterable をタプルに変換します。

于 2012-10-04T11:18:39.893 に答える
3

変化する

"usb-host,hostbus=%s,hostaddr=%s" % usb_pass_arr

"usb-host,hostbus=%s,hostaddr=%s" % tuple(usb_pass_arr)

また、新しいリストを返すため、の事前初期化usb_pass_arrは必要ありません。split()

于 2012-10-04T11:22:56.970 に答える
3

「古い」スタイルのフォーマットに対する答えはすでにあります。で新しいスタイルの書式設定を使用すると、可変長引数構文.format()を使用して次のように実行し、次の関数引数に自動的に解凍できます。usb_passformat()

'usb-host,hostbus={},hostaddr={}'.format(*usb_pass)
于 2012-10-04T11:49:40.173 に答える
1

人々がすでに書いたように、 を使用してリストをタプルに変換する必要がありますtuple(usb_pass_arr)。Python ドキュメントの次の段落を参照してください。

format が単一の引数を必要とする場合、値は単一の非タプル オブジェクトである可能性があります。それ以外の場合、値は、書式文字列で指定された正確な数の項目を持つタプル、または単一のマッピング オブジェクト (辞書など) である必要があります。

于 2012-10-04T11:27:11.070 に答える
1

usb_pass_arrタプルとして渡すだけで済みます。これは、文字列の書式設定で想定されていることです。

usb_pass = instance.hvparams[constants.HV_USBPASSTHROUGH]
if usb_pass:
    usb_pass_arr = [] #you can remove this line
    usb_pass_arr = tuple(usb_pass.split(";")) #a tuple is an immutable list
    kvm_cmd.extend(["-usb", "-device", "usb-host,hostbus=%s,hostaddr=%s" %
                    usb_pass_arr])
于 2012-10-04T11:25:15.813 に答える
0

こんにちは、David Morton およびその他の関心のある方。これは、インスタンスごとに 1 つの USB デバイスの Ganeti 2.6.0 USB パススルー用です。

    diff -r -c ganeti-2.6.0_original/lib/constants.py ganeti-2.6.0_changed/lib/constants.py
*** ganeti-2.6.0_original/lib/constants.py  2012-07-27 12:31:48.000000000 +0100
--- ganeti-2.6.0_changed/lib/constants.py   2012-10-04 13:46:15.881572099 +0100
***************
*** 770,775 ****
--- 770,776 ----
  HV_KVM_USE_CHROOT = "use_chroot"
  HV_CPU_MASK = "cpu_mask"
  HV_MEM_PATH = "mem_path"
+ HV_USBPASSTHROUGH = "usb_pass"
  HV_BLOCKDEV_PREFIX = "blockdev_prefix"
  HV_REBOOT_BEHAVIOR = "reboot_behavior"

***************
*** 824,829 ****
--- 825,831 ----
    HV_KVM_USE_CHROOT: VTYPE_BOOL,
    HV_CPU_MASK: VTYPE_STRING,
    HV_MEM_PATH: VTYPE_STRING,
+   HV_USBPASSTHROUGH: VTYPE_STRING,
    HV_BLOCKDEV_PREFIX: VTYPE_STRING,
    HV_REBOOT_BEHAVIOR: VTYPE_STRING,
    }
***************
*** 1809,1814 ****
--- 1811,1817 ----
      HV_MEM_PATH: "",
      HV_REBOOT_BEHAVIOR: INSTANCE_REBOOT_ALLOWED,
      HV_CPU_MASK: CPU_PINNING_ALL,
+     HV_USBPASSTHROUGH: "",
      },
    HT_FAKE: {
      },
Only in ganeti-2.6.0_changed/lib/: .dir
Only in ganeti-2.6.0_changed/lib/: _generated_rpc.py
Only in ganeti-2.6.0_changed/lib/http: .dir
Only in ganeti-2.6.0_changed/lib/hypervisor: .dir
diff -r -c ganeti-2.6.0_original/lib/hypervisor/hv_kvm.py ganeti-2.6.0_changed/lib/hypervisor/hv_kvm.py
*** ganeti-2.6.0_original/lib/hypervisor/hv_kvm.py  2012-07-27 13:27:41.000000000 +0100
--- ganeti-2.6.0_changed/lib/hypervisor/hv_kvm.py   2012-10-04 13:46:54.993572107 +0100
***************
*** 490,495 ****
--- 490,496 ----
      constants.HV_VHOST_NET: hv_base.NO_CHECK,
      constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
      constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK,
+     constants.HV_USBPASSTHROUGH:  hv_base.NO_CHECK,
      constants.HV_REBOOT_BEHAVIOR:
        hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
      constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
***************
*** 1257,1262 ****
--- 1258,1268 ----
      kvm_nics = instance.nics
      hvparams = hvp

+     usb_pass = instance.hvparams[constants.HV_USBPASSTHROUGH]
+     if usb_pass:
+         usb_pass_arr = usb_pass.split(";")
+         kvm_cmd.extend(["-usb", "-device", "usb-host,hostbus=%s,hostaddr=%s" % tuple(usb_pass_arr)])
+ 
      return (kvm_cmd, kvm_nics, hvparams)

    def _WriteKVMRuntime(self, instance_name, data):
Only in ganeti-2.6.0_changed/lib/impexpd: .dir
Only in ganeti-2.6.0_changed/lib/masterd: .dir
diff -r -c ganeti-2.6.0_original/lib/query.py ganeti-2.6.0_changed/lib/query.py
*** ganeti-2.6.0_original/lib/query.py  2012-07-27 12:31:48.000000000 +0100
--- ganeti-2.6.0_changed/lib/query.py   2012-10-04 13:46:26.625572103 +0100
***************
*** 1745,1750 ****
--- 1745,1751 ----
      constants.HV_NIC_TYPE: "NIC_type",
      constants.HV_PAE: "PAE",
      constants.HV_VNC_BIND_ADDRESS: "VNC_bind_address",
+     constants.HV_USBPASSTHROUGH: "usb_pass",
      }

    fields = [
Only in ganeti-2.6.0_changed/lib/rapi: .dir
Only in ganeti-2.6.0_changed/lib/server: .dir
Only in ganeti-2.6.0_changed/lib/tools: .dir
Only in ganeti-2.6.0_changed/lib/utils: .dir
Only in ganeti-2.6.0_changed/lib/: _vcsversion.py
Only in ganeti-2.6.0_changed/lib/watcher: .dir
于 2012-10-04T12:48:37.797 に答える
0

おおまかな推測 -- 代わりにこれを使用する必要があります。

"usb-host,hostbus=%s,hostaddr=%s" % (usb_pass_arr[0], usb_pass_arr[1])
于 2012-10-04T11:24:08.030 に答える