2012-10-04 14 views
1

我正在嘗試爲某些開源軟件編寫補丁,因爲它不會執行相當於我想 - 除了我根本不認識Python!我期望這很簡單,但它正在擊敗我。Python新手;分割字符串

背景:我寫的補丁是用於管理KVM虛擬機集羣的Ganeti,但它不支持KVM和Qemu所有可能的命令行選項,例如USB直通,所以我試圖修改它以允許這樣做。

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

+0

你怎麼能夠得到管理程序配置在python W/ instance.hvparams [constants.HV_USBPASSTHROUGH]? $ GNT實例修改--help 使用 ===== GNT實例修改 改變一個實例的參數 選項 ======= --debug,-d打開 --force調試,-f強制執行操作 --hypervisor = HYPERVISOR,-H HYPERVISOR變更管理程序參數 --backend = BEPARAMS,-B BEPARAMS更改後臺參數 --disk =磁盤的磁盤改變 - net = NICS NIC更改 --submit提交作業並返回作業ID,但不要等待e工作完成 – damzam

+0

如果我對Python有很多瞭解,我會遇到這個問題:)我將發佈一個答案,即USB傳遞的完整補丁,因爲現在這一切都在發揮作用,這要歸功於已發佈答案的優秀人物和女孩下面。 – jwbensley

回答

7

您有兩個`%s"usb-host,hostbus=%s,hostaddr=%s"但只提供一個參數,一個列表,其中一個元組預計。

使用

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

tuple()內建轉換可迭代到的元組。

3

變化

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

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

而且不需要的usb_pass_arr預初始化,作爲split()返回一個新的列表。

0

走馬猜測 - 你需要使用它代替:

"usb-host,hostbus=%s,hostaddr=%s" % (usb_pass_arr[0], usb_pass_arr[1]) 
+1

哦。 DERP。元組()也可以工作。這種方式更清潔。 –

+0

嗯,不知道爲什麼downvote - 真的,你不需要「需要使用」這種方法,但它是完全有效的,將解決OP的問題,所以+1從我的反動作-1 –

1

所有你需要做的是通過usb_pass_arr作爲一個元組,這是string formatting期待。

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]) 
1

正如人們已經寫道,您需要使用tuple(usb_pass_arr)將列表轉換爲元組。 參見在python文檔this段:

如果格式需要一個參數,值可以是單個非元組對象。否則,值必須是包含格式字符串或單個映射對象(例如字典)指定的項目數的正確元組。

0

嗨大衛·莫頓和其他任何人有興趣,這是對的Ganeti 2.6.0 USB pass-每個實例通過單個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 
+0

謝謝。 Javano! – damzam