Merge branch 'master' into ui-restyle

This commit is contained in:
Brian Federle 2013-09-26 11:01:56 -07:00
commit 23093ed05c
69 changed files with 1786 additions and 349 deletions

View File

@ -108,6 +108,7 @@ public class Networks {
},
Mido("mido", String.class),
Pvlan("pvlan", String.class),
Vxlan("vxlan", Long.class),
UnDecided(null, null);
private final String scheme;

View File

@ -39,7 +39,8 @@ public interface PhysicalNetwork extends Identity, InternalIdentity {
STT,
VNS,
MIDO,
SSP;
SSP,
VXLAN;
}
public enum BroadcastDomainRange {

View File

@ -40,7 +40,7 @@ message.acquire.ip.nic=Please confirm that you would like to acquire a new secon
message.select.affinity.groups=Please select any affinity groups you want this VM to belong to:
message.no.affinity.groups=You do not have any affinity groups. Please continue to the next step.
label.action.delete.nic=Remove NIC
message.action.delete.nic=Please confirm that want to remove this NIC, which will also remove the associated network from the VM.
message.action.delete.nic=Please confirm that want to remove this NIC, which will also remove the associated network from the VM.
changed.item.properties=Changed item properties
confirm.enable.s3=Please fill in the following information to enable support for S3-backed Secondary Storage
confirm.enable.swift=Please fill in the following information to enable support for Swift
@ -316,6 +316,7 @@ label.add.template=Add Template
label.add.to.group=Add to group
label.add.user=Add User
label.add.vlan=Add VLAN
label.add.vxlan=Add VXLAN
label.add.VM.to.tier=Add VM to tier
label.add.vm=Add VM
label.add.vms.to.lb=Add VM(s) to load balancer rule
@ -413,6 +414,11 @@ label.cluster.type=Cluster Type
label.cluster=Cluster
label.clusters=Clusters
label.clvm=CLVM
label.rbd=RBD
label.rbd.monitor=Ceph monitor
label.rbd.pool=Ceph pool
label.rbd.id=Cephx user
label.rbd.secret=Cephx secret
label.code=Code
label.community=Community
label.compute.and.storage=Compute and Storage
@ -541,6 +547,7 @@ label.end.IP=End IP
label.end.port=End Port
label.end.reserved.system.IP=End Reserved system IP
label.end.vlan=End Vlan
label.end.vxlan=End Vxlan
label.endpoint.or.operation=Endpoint or Operation
label.endpoint=Endpoint
label.enter.token=Enter token
@ -1027,12 +1034,14 @@ label.source.nat=Source NAT
label.source=Source
label.specify.IP.ranges=Specify IP ranges
label.specify.vlan=Specify VLAN
label.specify.vxlan=Specify VXLAN
label.SR.name = SR Name-Label
label.srx=SRX
label.start.IP=Start IP
label.start.port=Start Port
label.start.reserved.system.IP=Start Reserved system IP
label.start.vlan=Start Vlan
label.start.vxlan=Start Vxlan
label.state=State
label.static.nat.enabled=Static NAT Enabled
label.static.nat.to=Static NAT to
@ -1159,6 +1168,9 @@ label.virtual.routers=Virtual Routers
label.vlan.id=VLAN ID
label.vlan.range=VLAN Range
label.vlan=VLAN
label.vxlan.id=VXLAN ID
label.vxlan.range=VXLAN Range
label.vxlan=VXLAN
label.vm.add=Add Instance
label.vm.destroy=Destroy
label.vm.display.name=VM display name

View File

@ -224,6 +224,7 @@ label.add.system.service.offering=System-Service-Angebot hinzuf\u00fcgen
label.add.template=Vorlage hinzuf\u00fcgen
label.add.user=Benutzer hinzuf\u00fcgen
label.add.vlan=VLAN hinzuf\u00fcgen
label.add.vxlan=VXLAN hinzuf\u00fcgen
label.add.volume=Volume hinzuf\u00fcgen
label.add.zone=Zone hinzuf\u00fcgen
label.admin.accounts=Administrator-Konten
@ -621,6 +622,9 @@ label.virtual.network=Virtuelles Netzwerk
label.vlan.id=VLAN ID
label.vlan.range=VLAN Reichweite
label.vlan=VLAN
label.vxlan.id=VXLAN ID
label.vxlan.range=VXLAN Reichweite
label.vxlan=VXLAN
label.vm.add=Instanz hinzuf\u00fcgen
label.vm.destroy=Zerst\u00f6ren
label.VMFS.datastore=VMFS Datenspeicher

View File

@ -238,6 +238,7 @@ label.add.template=A\u00c3\u00b1adir plantilla
label.add.to.group=Agregar al grupo
label.add.user=Agregar usuario
label.add.vlan=A\u00c3\u00b1adir VLAN
label.add.vxlan=A\u00c3\u00b1adir VXLAN
label.add.volume=A\u00c3\u00b1adir volumen
label.add.zone=A\u00c3\u00b1adir Zona
label.admin.accounts=Administrador de Cuentas
@ -606,6 +607,7 @@ label.snapshot.s=Instant\u00c3\u00a1nea (s)
label.snapshots=instant\u00c3\u00a1neas
label.source.nat=NAT Fuente
label.specify.vlan=Especifique VLAN
label.specify.vxlan=Especifique VXLAN
label.SR.name = SR Nombre de etiqueta
label.start.port=Iniciar Puerto
label.state=Estado
@ -685,6 +687,9 @@ label.virtual.network=Red Virtual
label.vlan.id=ID de VLAN
label.vlan.range=VLAN Gama
label.vlan=VLAN
label.vxlan.id=ID de VXLAN
label.vxlan.range=VXLAN Gama
label.vxlan=VXLAN
label.vm.add=A\u00c3\u00b1adir Instancia
label.vm.destroy=Destroy
label.VMFS.datastore=VMFS de datos tienda

View File

@ -300,6 +300,7 @@ label.add.template=Ajouter un mod\u00e8le
label.add.to.group=Ajouter au groupe
label.add.user=Ajouter un utilisateur
label.add.vlan=Ajouter un VLAN
label.add.vxlan=Ajouter un VXLAN
label.add.vm=Ajouter VM
label.add.vms=Ajouter VMs
label.add.vms.to.lb=Ajouter une/des VM(s) \u00e0 la r\u00e8gle de r\u00e9partition de charge
@ -512,6 +513,7 @@ label.endpoint=Terminaison
label.end.port=Port de fin
label.end.reserved.system.IP=Adresse IP de fin r\u00e9serv\u00e9e Syst\u00e8me
label.end.vlan=VLAN de fin
label.end.vxlan=VXLAN de fin
label.enter.token=Entrez le jeton unique
label.error.code=Code d\\'erreur
label.error=Erreur
@ -995,12 +997,14 @@ label.source.nat=NAT Source
label.source=Origine
label.specify.IP.ranges=Sp\u00e9cifier des plages IP
label.specify.vlan=Pr\u00e9ciser le VLAN
label.specify.vxlan=Pr\u00e9ciser le VXLAN
label.SR.name = Nom du point de montage
label.srx=SRX
label.start.IP=Plage de d\u00e9but IP
label.start.port=Port de d\u00e9but
label.start.reserved.system.IP=Adresse IP de d\u00e9but r\u00e9serv\u00e9e Syst\u00e8me
label.start.vlan=VLAN de d\u00e9part
label.start.vxlan=VXLAN de d\u00e9part
label.state=\u00c9tat
label.static.nat.enabled=NAT statique activ\u00e9
label.static.nat=NAT Statique
@ -1127,6 +1131,9 @@ label.virtual.routers=Routeurs virtuels
label.vlan.id=ID du VLAN
label.vlan.range=Plage du VLAN
label.vlan=VLAN
label.vxlan.id=VXLAN ID
label.vxlan.range=Plage du VXLAN
label.vxlan=VXLAN
label.vm.add=Ajouter une instance
label.vm.destroy=D\u00e9truire
label.vm.display.name=Nom commun VM

View File

@ -1,4 +1,4 @@
# Licensed to the Apache Software Foundation (ASF) under one
a# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
@ -313,6 +313,7 @@ label.add.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u8ffd\u52a0
label.add.to.group=\u8ffd\u52a0\u5148\u30b0\u30eb\u30fc\u30d7
label.add.user=\u30e6\u30fc\u30b6\u30fc\u306e\u8ffd\u52a0
label.add.vlan=VLAN \u306e\u8ffd\u52a0
label.add.vxlan=VXLAN \u306e\u8ffd\u52a0
label.add.VM.to.tier=\u968e\u5c64\u3078\u306e VM \u306e\u8ffd\u52a0
label.add.vm=VM \u306e\u8ffd\u52a0
label.add.vms.to.lb=\u8ca0\u8377\u5206\u6563\u898f\u5247\u3078\u306e VM \u306e\u8ffd\u52a0
@ -532,6 +533,7 @@ label.end.IP=\u7d42\u4e86 IP \u30a2\u30c9\u30ec\u30b9
label.end.port=\u7d42\u4e86\u30dd\u30fc\u30c8
label.end.reserved.system.IP=\u4e88\u7d04\u6e08\u307f\u7d42\u4e86\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9
label.end.vlan=\u7d42\u4e86 VLAN
label.end.vxlan=\u7d42\u4e86 VXLAN
label.endpoint.or.operation=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u307e\u305f\u306f\u64cd\u4f5c
label.endpoint=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8
label.enter.token=\u30c8\u30fc\u30af\u30f3\u306e\u5165\u529b
@ -1007,12 +1009,14 @@ label.source.nat=\u9001\u4fe1\u5143 NAT
label.source=\u9001\u4fe1\u5143
label.specify.IP.ranges=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u6307\u5b9a
label.specify.vlan=VLAN \u3092\u6307\u5b9a\u3059\u308b
label.specify.vxlan=VXLAN \u3092\u6307\u5b9a\u3059\u308b
label.SR.name = SR \u540d\u30e9\u30d9\u30eb
label.srx=SRX
label.start.IP=\u958b\u59cb IP \u30a2\u30c9\u30ec\u30b9
label.start.port=\u958b\u59cb\u30dd\u30fc\u30c8
label.start.reserved.system.IP=\u4e88\u7d04\u6e08\u307f\u958b\u59cb\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9
label.start.vlan=\u958b\u59cb VLAN
label.start.vxlan=\u958b\u59cb VXLAN
label.state=\u72b6\u614b
label.static.nat.enabled=\u9759\u7684 NAT \u6709\u52b9
label.static.nat.to=\u9759\u7684 NAT \u306e\u8a2d\u5b9a\u5148:
@ -1139,6 +1143,9 @@ label.virtual.routers=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc
label.vlan.id=VLAN ID
label.vlan.range=VLAN \u306e\u7bc4\u56f2
label.vlan=VLAN
label.vxlan.id=VXLAN ID
label.vxlan.range=VXLAN \u306e\u7bc4\u56f2
label.vxlan=VXLAN
label.vm.add=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u8ffd\u52a0
label.vm.destroy=\u7834\u68c4
label.vm.display.name=VM \u8868\u793a\u540d

View File

@ -289,6 +289,7 @@ label.add.to.group=\uadf8\ub8f9\uc5d0 \ucd94\uac00
label.add=\ucd94\uac00
label.add.user=\uc0ac\uc6a9\uc790 \ucd94\uac00
label.add.vlan=VLAN \ucd94\uac00
label.add.vxlan=VXLAN \ucd94\uac00
label.add.vms.to.lb=\ub124\ud2b8\uc6cc\ud06c \ub85c\ub4dc \uacf5\uc720 \uaddc\uce59\uc5d0 VM \ucd94\uac00
label.add.vms=VM \ucd94\uac00
label.add.VM.to.tier=\uacc4\uce35\uc5d0 VM \ucd94\uac00
@ -479,6 +480,7 @@ label.endpoint.or.operation=\uc5d4\ub4dc \ud3ec\uc778\ud2b8 \ub610\ub294 \uc791\
label.end.port=\uc885\ub8cc \ud3ec\ud1a0
label.end.reserved.system.IP=\uc608\uc57d\ub41c \uc885\ub8cc \uc2dc\uc2a4\ud15c IP \uc8fc\uc18c
label.end.vlan=\uc885\ub8cc VLAN
label.end.vxlan=\uc885\ub8cc VXLAN
label.enter.token=\ud1a0\ud070 \uc785\ub825
label.error.code=\uc624\ub958 \ucf54\ub4dc
label.error=\uc624\ub958
@ -925,12 +927,14 @@ label.source.nat=\uc804\uc1a1\uc6d0 NAT
label.source=\uc2dc\uc791 \uc704\uce58
label.specify.IP.ranges=IP \uc8fc\uc18c \ubc94\uc704 \uc9c0\uc815
label.specify.vlan=VLAN \uc9c0\uc815
label.specify.vxlan=VXLAN \uc9c0\uc815
label.SR.name = SR \uba85 \ub77c\ubca8
label.srx=SRX
label.start.IP=\uc2dc\uc791 IP \uc8fc\uc18c
label.start.port=\uc2dc\uc791 \ud3ec\ud1a0
label.start.reserved.system.IP=\uc608\uc57d\ub41c \uc2dc\uc791 \uc2dc\uc2a4\ud15c IP \uc8fc\uc18c
label.start.vlan=\uc2dc\uc791 VLAN
label.start.vxlan=\uc2dc\uc791 VXLAN
label.state=\uc0c1\ud0dc
label.static.nat.enabled=\uc815\uc801 NAT \uc720\ud6a8
label.static.nat.to=\uc815\uc801 NAT \uc124\uc815 \uc704\uce58\:
@ -1055,6 +1059,9 @@ label.virtual.router=\uac00\uc0c1 \ub77c\uc6b0\ud130
label.vlan.id=VLAN ID
label.vlan.range=VLAN \ubc94\uc704
label.vlan=\uac00\uc0c1 \ub124\ud2b8\uc6cc\ud06c(VLAN)
label.vxlan.id=VXLAN ID
label.vxlan.range=VXLAN \ubc94\uc704
label.vxlan=VXLAN
label.vm.add=\uc778\uc2a4\ud134\uc2a4 \ucd94\uac00
label.vm.destroy=\ud30c\uae30
label.vm.display.name=VM \ud45c\uc2dc\uba85

View File

@ -288,6 +288,7 @@ label.add.template=Adicionar Template
label.add.to.group=Adicionar ao grupo
label.add.user=Adicionar Usu\u00e1rio
label.add.vlan=Adicionar VLAN
label.add.vxlan=Adicionar VXLAN
label.add.vm=Adicionar VM
label.add.vms=Adicionar VMs
label.add.vms.to.lb=Add VM(s) na regra de balanceamento de carga
@ -480,6 +481,7 @@ label.endpoint=Ponto de acesso
label.end.port=Porta Final
label.end.reserved.system.IP=Fim dos IPs reservados para o sistema
label.end.vlan=Vlan do fim
label.end.vxlan=Vxlan do fim
label.enter.token=Digite o token
label.error.code=C\u00f3digo de Erro
label.error=Erro
@ -931,12 +933,14 @@ label.source.nat=Source NAT
label.source=Origem
label.specify.IP.ranges=Especifique range de IP
label.specify.vlan=Especificar VLAN
label.specify.vxlan=Especificar VXLAN
label.SR.name = SR Name-Label
label.srx=SRX
label.start.IP=IP do in\u00edcio
label.start.port=Porta de In\u00edcio
label.start.reserved.system.IP=In\u00edcio dos IPs reservados para o sistema
label.start.vlan=Vlan do in\u00edcio
label.start.vxlan=Vxlan do in\u00edcio
label.state=Estado
label.static.nat.enabled=NAT est\u00e1tico Habilitado
label.static.nat=NAT Est\u00e1tico
@ -1059,6 +1063,9 @@ label.virtual.routers=Roteadores Virtuais
label.vlan.id=VLAN ID
label.vlan.range=Intervalo de VLAN
label.vlan=VLAN
label.vxlan.id=VXLAN ID
label.vxlan.range=Intervalo de VXLAN
label.vxlan=VXLAN
label.vm.add=Adicionar Cloud Server
label.vm.destroy=Apagar
label.vm.display.name=Nome de exibi\u00e7\u00e3o da VM

View File

@ -283,6 +283,7 @@ label.add.to.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043
label.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
label.add.user=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
label.add.vlan=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c VLAN
label.add.vxlan=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c VXLAN
label.add.vms.to.lb=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0412\u041c \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438
label.add.vms=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0412\u041c
label.add.vm=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0412\u041c
@ -454,6 +455,7 @@ label.endpoint.or.operation=\u041a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0
label.end.port=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043f\u043e\u0440\u0442
label.end.reserved.system.IP=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441
label.end.vlan=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 VLAN
label.end.vxlan=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 VXLAN
label.enter.token=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u0430\u043b\u043e\u043d
label.error.code=\u041a\u043e\u0434 \u043e\u0448\u0438\u0431\u043a\u0438
label.error=\u041e\u0448\u0438\u0431\u043a\u0430
@ -874,12 +876,14 @@ label.source.nat=Source NAT
label.source=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a
label.specify.IP.ranges=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d IP-\u0430\u0434\u0440\u0435\u0441\u043e\u0432
label.specify.vlan=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 VLAN
label.specify.vxlan=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 VXLAN
label.SR.name = SR Name-Label
label.srx=SRX
label.start.IP=\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 IP
label.start.port=\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0440\u0442
label.start.reserved.system.IP=\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441
label.start.vlan=\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 VLAN
label.start.vxlan=\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 VXLAN
label.state=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
label.static.nat.enabled=\u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 NAT \u0432\u043a\u043b\u044e\u0447\u0435\u043d
label.static.nat.to=\u0421\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0439 NAT \u043a
@ -1001,6 +1005,9 @@ label.virtual.router=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044
label.vlan.id=ID VLAN
label.vlan.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d VLAN
label.vlan=VLAN
label.vxlan.id=VXLAN ID
label.vxlan.range=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d Range
label.vxlan=VXLAN
label.vm.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u044b
label.vm.destroy=\u0423\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c
label.vm.display.name=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f \u0412\u041c

View File

@ -314,6 +314,7 @@ label.add.template=\u6dfb\u52a0\u6a21\u677f
label.add.to.group=\u6dfb\u52a0\u5230\u7ec4
label.add.user=\u6dfb\u52a0\u7528\u6237
label.add.vlan=\u6dfb\u52a0 VLAN
label.add.vxlan=\u6dfb\u52a0 VXLAN
label.add.VM.to.tier=\u5411\u5c42\u4e2d\u6dfb\u52a0 VM
label.add.vm=\u6dfb\u52a0 VM
label.add.vms.to.lb=\u5411\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219\u4e2d\u6dfb\u52a0 VM
@ -539,6 +540,7 @@ label.end.IP=\u7ed3\u675f IP
label.end.port=\u7ed3\u675f\u7aef\u53e3
label.end.reserved.system.IP=\u7ed3\u675f\u9884\u7559\u7cfb\u7edf IP
label.end.vlan=\u7ed3\u675f VLAN
label.end.vxlan=\u7ed3\u675f VXLAN
label.endpoint.or.operation=\u7aef\u70b9\u6216\u64cd\u4f5c
label.endpoint=\u7aef\u70b9
label.enter.token=\u8f93\u5165\u4ee4\u724c
@ -1025,12 +1027,14 @@ label.source.nat=\u6e90 NAT
label.source=\u6e90\u7b97\u6cd5
label.specify.IP.ranges=\u6307\u5b9a IP \u8303\u56f4
label.specify.vlan=\u6307\u5b9a VLAN
label.specify.vxlan=\u6307\u5b9a VXLAN
label.SR.name = SR \u540d\u79f0\u6807\u7b7e
label.srx=SRX
label.start.IP=\u8d77\u59cb IP
label.start.port=\u8d77\u59cb\u7aef\u53e3
label.start.reserved.system.IP=\u8d77\u59cb\u9884\u7559\u7cfb\u7edf IP
label.start.vlan=\u8d77\u59cb VLAN
label.start.vxlan=\u8d77\u59cb VXLAN
label.state=\u72b6\u6001
label.static.nat.enabled=\u5df2\u542f\u7528\u9759\u6001 NAT
label.static.nat.to=\u9759\u6001 NAT \u76ee\u6807
@ -1157,6 +1161,9 @@ label.virtual.routers=\u865a\u62df\u8def\u7531\u5668
label.vlan.id=VLAN ID
label.vlan.range=VLAN \u8303\u56f4
label.vlan=VLAN
label.vxlan.id=VXLAN ID
label.vxlan.range=VXLAN Range
label.vxlan=VXLAN
label.vm.add=\u6dfb\u52a0\u5b9e\u4f8b
label.vm.destroy=\u9500\u6bc1
label.vm.display.name=VM \u663e\u793a\u540d\u79f0

View File

@ -105,6 +105,11 @@
<artifactId>cloud-plugin-network-internallb</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-vxlan</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hypervisor-xen</artifactId>

View File

@ -91,6 +91,13 @@
<bean id="ucsBladeDaoImpl" class="com.cloud.ucs.database.UcsBladeDaoImpl" />
<bean id="ucsManagerDaoImpl" class="com.cloud.ucs.database.UcsManagerDaoImpl" />
<!--
VXLAN support components
-->
<bean id="VxlanGuestNetworkGuru" class="com.cloud.network.guru.VxlanGuestNetworkGuru">
<property name="name" value="VxlanGuestNetworkGuru"/>
</bean>
<!--
Deployment configurations of various adapters
@ -266,6 +273,7 @@
<ref bean="NiciraNvpGuestNetworkGuru"/>
<ref bean="MidoNetGuestNetworkGuru"/>
<ref bean="SspGuestNetworkGuru"/>
<ref bean="VxlanGuestNetworkGuru"/>
</list>
</property>
</bean>

View File

@ -1215,6 +1215,41 @@ public class VirtualRoutingResource implements Manager {
return "Unable to connect";
}
public boolean connect(final String ipAddress, int retry, int sleep) {
for (int i = 0; i <= retry; i++) {
SocketChannel sch = null;
try {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Trying to connect to " + ipAddress);
}
sch = SocketChannel.open();
sch.configureBlocking(true);
final InetSocketAddress addr = new InetSocketAddress(ipAddress, _port);
sch.connect(addr);
return true;
} catch (final IOException e) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Could not connect to " + ipAddress);
}
} finally {
if (sch != null) {
try {
sch.close();
} catch (final IOException e) {}
}
}
try {
Thread.sleep(sleep);
} catch (final InterruptedException e) {
}
}
s_logger.debug("Unable to logon to " + ipAddress);
return false;
}
@Override
public String getName() {
return _name;

View File

@ -63,4 +63,8 @@ public final class CopyCommand extends Command implements StorageSubSystemComman
this.cacheTO = cacheTO;
}
public int getWaitInMillSeconds() {
return this.getWait() * 1000;
}
}

View File

@ -1203,10 +1203,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
} catch (AgentUnavailableException e) {
s_logger.warn("Unable to stop vm, agent unavailable: " + e.toString());
throw e;
} catch (OperationTimedoutException e) {
s_logger.warn("Unable to stop vm, operation timed out: " + e.toString());
throw e;
} finally {
if (!stopped) {
if (!cleanUpEvenIfUnableToStop) {

View File

@ -390,7 +390,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
Map<Network.Service, Set<Network.Provider>> defaultVPCOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
defaultProviders.clear();
defaultProviders.add(Network.Provider.VirtualRouter);
defaultProviders.add(Network.Provider.VPCVirtualRouter);
defaultVPCOffProviders.put(Service.Dhcp, defaultProviders);
defaultVPCOffProviders.put(Service.Dns, defaultProviders);
defaultVPCOffProviders.put(Service.UserData, defaultProviders);
@ -600,8 +600,11 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
try {
if (predefined == null ||
(offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null && !(predefined.getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch))) {
if (predefined == null || (offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null &&
!(predefined.getBroadcastDomainType() == BroadcastDomainType.Vlan ||
predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch ||
predefined.getBroadcastDomainType() == BroadcastDomainType.Vxlan)
)) {
List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
if (configs.size() > 0) {
if (s_logger.isDebugEnabled()) {
@ -1698,6 +1701,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
}
//TODO(VXLAN): Support VNI specified
// VlanId can be specified only when network offering supports it
boolean vlanSpecified = (vlanId != null);
if (vlanSpecified != ntwkOff.getSpecifyVlan()) {

View File

@ -1084,7 +1084,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
public boolean canVmRestartOnAnotherServer(long vmId) {
List<VolumeVO> vols = _volsDao.findCreatedByInstance(vmId);
for (VolumeVO vol : vols) {
if (!vol.isRecreatable() && !vol.getPoolType().isShared()) {
StoragePoolVO storagePoolVO = _storagePoolDao.findById(vol.getPoolId());
if (!vol.isRecreatable() && storagePoolVO != null && storagePoolVO.getPoolType() != null && !(storagePoolVO.getPoolType().isShared())) {
return false;
}
}

View File

@ -383,9 +383,6 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker {
try {
String dbVersion = _dao.getCurrentVersion();
String currentVersion = this.getClass().getPackage().getImplementationVersion();
if (currentVersion == null) {
currentVersion = this.getClass().getSuperclass().getPackage().getImplementationVersion();
}
if (currentVersion == null)
return;

View File

@ -40,4 +40,5 @@ StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Even
SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role);
List<SnapshotDataStoreVO> listDestroyed(long storeId);
List<SnapshotDataStoreVO> findBySnapshotId(long snapshotId);
}

View File

@ -18,6 +18,8 @@ package org.apache.cloudstack.storage.test;
import java.io.IOException;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.dao.EventDaoImpl;
import org.apache.cloudstack.acl.APIChecker;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.service.api.OrchestrationService;
@ -107,7 +109,7 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl;
VMSnapshotDaoImpl.class, OCFS2ManagerImpl.class, ClusterDetailsDaoImpl.class, SecondaryStorageVmDaoImpl.class,
ConsoleProxyDaoImpl.class, StoragePoolWorkDaoImpl.class, StorageCacheManagerImpl.class, UserDaoImpl.class,
DataCenterDaoImpl.class, StoragePoolDetailsDaoImpl.class, DomainDaoImpl.class, DownloadMonitorImpl.class,
AccountDaoImpl.class }, includeFilters = { @Filter(value = Library.class, type = FilterType.CUSTOM) },
AccountDaoImpl.class, ActionEventUtils.class, EventDaoImpl.class}, includeFilters = { @Filter(value = Library.class, type = FilterType.CUSTOM) },
useDefaultFilters = false)
public class ChildTestConfiguration extends TestConfiguration {
@ -186,12 +188,6 @@ public class ChildTestConfiguration extends TestConfiguration {
return Mockito.mock(VirtualMachineManager.class);
}
@Bean
public SnapshotManager snapshotMgr() {
return Mockito.mock(SnapshotManager.class);
}
@Bean
public ResourceManager resourceMgr() {
return Mockito.mock(ResourceManager.class);

View File

@ -26,6 +26,10 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.host.Host;
import com.cloud.host.Status;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.utils.fsm.StateMachine2;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@ -246,6 +250,7 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa
e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return true;
}
@Override

View File

@ -18,6 +18,7 @@
*/
package org.apache.cloudstack.storage.test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -28,6 +29,7 @@ import java.util.UUID;
import javax.inject.Inject;
import com.cloud.server.LockMasterListener;
import junit.framework.Assert;
import org.junit.Before;
@ -58,6 +60,9 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import com.cloud.agent.AgentManager;
import com.cloud.agent.AgentManager;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
@ -88,6 +93,7 @@ import com.cloud.user.User;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.db.Merovingian2;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/fakeDriverTestContext.xml" })
public class EndpointSelectorTest {
@ -121,6 +127,8 @@ public class EndpointSelectorTest {
ImageStoreVO imageStore;
@Inject
AccountManager accountManager;
LockMasterListener lockMasterListener;
VolumeInfo vol = null;
FakePrimaryDataStoreDriver driver = new FakePrimaryDataStoreDriver();
@Inject

View File

@ -18,10 +18,12 @@
*/
package org.apache.cloudstack.storage.test;
import com.cloud.storage.snapshot.SnapshotScheduler;
import com.cloud.storage.snapshot.SnapshotSchedulerImpl;
import com.cloud.user.DomainManager;
import com.cloud.utils.component.ComponentContext;
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
@ -63,5 +65,5 @@ public class FakeDriverTestConfiguration extends ChildTestConfiguration{
public EndPointSelector selector() {
return ComponentContext.inject(DefaultEndPointSelector.class);
}
}

View File

@ -19,25 +19,39 @@
package org.apache.cloudstack.storage.test;
import java.util.Map;
import java.util.UUID;
import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataTO;
import com.cloud.storage.Storage;
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.host.Host;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.snapshot.SnapshotObject;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
public class MockStorageMotionStrategy implements DataMotionStrategy {
boolean success = true;
@Override
public boolean canHandle(DataObject srcData, DataObject destData) {
// TODO Auto-generated method stub
return true;
}
public void makeBackupSnapshotSucceed(boolean success) {
this.success = success;
}
@Override
public boolean canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost) {
return true;
@ -45,7 +59,32 @@ public class MockStorageMotionStrategy implements DataMotionStrategy {
@Override
public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
CopyCommandResult result = new CopyCommandResult("something", null);
CopyCmdAnswer answer = null;
DataTO data = null;
if (!success) {
CopyCommandResult result = new CopyCommandResult(null, null);
result.setResult("Failed");
callback.complete(result);
}
if (destData.getType() == DataObjectType.SNAPSHOT) {
SnapshotInfo srcSnapshot = (SnapshotInfo)srcData;
SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
newSnapshot.setPath(UUID.randomUUID().toString());
if (srcSnapshot.getParent() != null) {
newSnapshot.setParentSnapshotPath(srcSnapshot.getParent().getPath());
}
data = newSnapshot;
} else if (destData.getType() == DataObjectType.TEMPLATE) {
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(UUID.randomUUID().toString());
newTemplate.setFormat(Storage.ImageFormat.QCOW2);
newTemplate.setSize(10L);
newTemplate.setPhysicalSize(10L);
data = newTemplate;
}
answer = new CopyCmdAnswer(data);
CopyCommandResult result = new CopyCommandResult("something", answer);
callback.complete(result);
return null;
}

View File

@ -18,17 +18,37 @@
*/
package org.apache.cloudstack.storage.test;
import com.cloud.cluster.LockMasterListener;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.org.Cluster;
import com.cloud.org.Managed;
import com.cloud.storage.CreateSnapshotPayload;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotPolicyVO;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.SnapshotPolicyDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.User;
import com.cloud.utils.DateUtil;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Merovingian2;
import junit.framework.Assert;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@ -44,10 +64,14 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.volume.VolumeObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -58,13 +82,25 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.inject.Inject;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/fakeDriverTestContext.xml" })
public class SnapshotTestWithFakeData {
public class SnapshotTestWithFakeData {
@Inject
SnapshotService snapshotService;
@Inject
@ -85,30 +121,106 @@ public class SnapshotTestWithFakeData {
VolumeService volumeService;
@Inject
VolumeDataFactory volumeDataFactory;
@Inject
DataCenterDao dcDao;
Long dcId;
@Inject
HostPodDao podDao;
Long podId;
@Inject
ClusterDao clusterDao;
Long clusterId;
@Inject
ImageStoreDao imageStoreDao;
ImageStoreVO imageStore;
@Inject
AccountManager accountManager;
LockMasterListener lockMasterListener;
VolumeInfo vol = null;
FakePrimaryDataStoreDriver driver = new FakePrimaryDataStoreDriver();
@Inject
MockStorageMotionStrategy mockStorageMotionStrategy;
Merovingian2 _lockMaster;
@Inject
SnapshotPolicyDao snapshotPolicyDao;
@Before
public void setUp() {
Mockito.when(primaryDataStoreProvider.configure(Mockito.anyMap())).thenReturn(true);
// create data center
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null,
"10.0.0.1/24", null, null, DataCenter.NetworkType.Basic, null, null, true, true, null, null);
dc = dcDao.persist(dc);
dcId = dc.getId();
// create pod
HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "10.223.0.1",
"10.233.2.2/25", 8, "test");
pod = podDao.persist(pod);
podId = pod.getId();
// create xen cluster
ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
cluster.setHypervisorType(Hypervisor.HypervisorType.XenServer.toString());
cluster.setClusterType(Cluster.ClusterType.CloudManaged);
cluster.setManagedState(Managed.ManagedState.Managed);
cluster = clusterDao.persist(cluster);
clusterId = cluster.getId();
imageStore = new ImageStoreVO();
imageStore.setName(UUID.randomUUID().toString());
imageStore.setDataCenterId(dcId);
imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
imageStore.setRole(DataStoreRole.Image);
imageStore.setUrl(UUID.randomUUID().toString());
imageStore.setUuid(UUID.randomUUID().toString());
imageStore.setProtocol("nfs");
imageStore = imageStoreDao.persist(imageStore);
when(primaryDataStoreProvider.configure(Mockito.anyMap())).thenReturn(true);
Set<DataStoreProvider.DataStoreProviderType> types = new HashSet<DataStoreProvider.DataStoreProviderType>();
types.add(DataStoreProvider.DataStoreProviderType.PRIMARY);
Mockito.when(primaryDataStoreProvider.getTypes()).thenReturn(types);
Mockito.when(primaryDataStoreProvider.getName()).thenReturn(DataStoreProvider.DEFAULT_PRIMARY);
Mockito.when(primaryDataStoreProvider.getDataStoreDriver()).thenReturn(driver);
when(primaryDataStoreProvider.getTypes()).thenReturn(types);
when(primaryDataStoreProvider.getName()).thenReturn(DataStoreProvider.DEFAULT_PRIMARY);
when(primaryDataStoreProvider.getDataStoreDriver()).thenReturn(driver);
User user = mock(User.class);
when(user.getId()).thenReturn(1L);
Account account = mock(Account.class);
when(account.getId()).thenReturn(1L);
when(accountManager.getSystemAccount()).thenReturn(account);
when(accountManager.getSystemUser()).thenReturn(user);
if(Merovingian2.getLockMaster() == null) {
_lockMaster = Merovingian2.createLockMaster(1234);
} else {
_lockMaster = Merovingian2.getLockMaster();
}
_lockMaster.cleanupThisServer();
ComponentContext.initComponentsLifeCycle();
}
@After
public void tearDown() throws Exception {
_lockMaster.cleanupThisServer();
}
private SnapshotVO createSnapshotInDb() {
Snapshot.Type snapshotType = Snapshot.Type.MANUAL;
SnapshotVO snapshotVO = new SnapshotVO(1, 2, 1, 1L, 1L, UUID.randomUUID()
Snapshot.Type snapshotType = Snapshot.Type.RECURRING;
SnapshotVO snapshotVO = new SnapshotVO(dcId, 2, 1, 1L, 1L, UUID.randomUUID()
.toString(), (short) snapshotType.ordinal(), snapshotType.name(), 100,
Hypervisor.HypervisorType.XenServer);
return this.snapshotDao.persist(snapshotVO);
}
private SnapshotVO createSnapshotInDb(Long volumeId) {
Snapshot.Type snapshotType = Snapshot.Type.DAILY;
SnapshotVO snapshotVO = new SnapshotVO(dcId, 2, 1, volumeId, 1L, UUID.randomUUID()
.toString(), (short) snapshotType.ordinal(), snapshotType.name(), 100,
Hypervisor.HypervisorType.XenServer);
return this.snapshotDao.persist(snapshotVO);
}
private VolumeInfo createVolume(Long templateId, DataStore store) {
VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), 1L, 1L, 1L, 1L, 1000, 0L, 0L, "");
VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), dcId, 1L, 1L, 1L, 1000, 0L, 0L, "");
;
volume.setPoolId(store.getId());
@ -120,8 +232,8 @@ public class SnapshotTestWithFakeData {
}
private DataStore createDataStore() throws URISyntaxException {
StoragePoolVO pool = new StoragePoolVO();
pool.setClusterId(1L);
pool.setDataCenterId(1);
pool.setClusterId(clusterId);
pool.setDataCenterId(dcId);
URI uri = new URI("nfs://jfkdkf/fjdkfj");
pool.setHostAddress(uri.getHost());
pool.setPath(uri.getPath());
@ -130,14 +242,14 @@ public class SnapshotTestWithFakeData {
pool.setUuid(UUID.randomUUID().toString());
pool.setStatus(StoragePoolStatus.Up);
pool.setPoolType(Storage.StoragePoolType.NetworkFilesystem);
pool.setPodId(1L);
pool.setPodId(podId);
pool.setScope(ScopeType.CLUSTER);
pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
pool = this.primaryDataStoreDao.persist(pool);
DataStore store = this.dataStoreManager.getPrimaryDataStore(pool.getId());
return store;
}
@Test
//@Test
public void testTakeSnapshot() throws URISyntaxException {
SnapshotVO snapshotVO = createSnapshotInDb();
DataStore store = createDataStore();
@ -158,7 +270,7 @@ public class SnapshotTestWithFakeData {
}
}
@Test
//@Test
public void testTakeSnapshotWithFailed() throws URISyntaxException {
SnapshotVO snapshotVO = createSnapshotInDb();
DataStore store = null;
@ -179,7 +291,7 @@ public class SnapshotTestWithFakeData {
}
}
@Test
//@Test
public void testTakeSnapshotFromVolume() throws URISyntaxException {
DataStore store = createDataStore();
FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
@ -191,4 +303,57 @@ public class SnapshotTestWithFakeData {
Assert.assertTrue(result == null);
}
protected SnapshotPolicyVO createSnapshotPolicy(Long volId) {
SnapshotPolicyVO policyVO = new SnapshotPolicyVO(volId, "jfkd", "fdfd", DateUtil.IntervalType.DAILY, 8);
policyVO = snapshotPolicyDao.persist(policyVO);
return policyVO;
}
@Test
public void testConcurrentSnapshot() throws URISyntaxException, InterruptedException, ExecutionException {
DataStore store = createDataStore();
final FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
dataStoreDriver.makeTakeSnapshotSucceed(true);
final VolumeInfo volumeInfo = createVolume(1L, store);
Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
vol = volumeInfo;
// final SnapshotPolicyVO policyVO = createSnapshotPolicy(vol.getId());
ExecutorService pool = Executors.newFixedThreadPool(2);
boolean result = false;
List<Future<Boolean>> future = new ArrayList<Future<Boolean>>();
for(int i = 0; i < 12; i++) {
final int cnt = i;
Future<Boolean> task = pool.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
boolean r = true;
try {
SnapshotVO snapshotVO = createSnapshotInDb(vol.getId());
VolumeObject volumeObject = (VolumeObject)vol;
Account account = mock(Account.class);
when(account.getId()).thenReturn(1L);
CreateSnapshotPayload createSnapshotPayload = mock(CreateSnapshotPayload.class);
when(createSnapshotPayload.getAccount()).thenReturn(account);
when(createSnapshotPayload.getSnapshotId()).thenReturn(snapshotVO.getId());
when(createSnapshotPayload.getSnapshotPolicyId()).thenReturn(0L);
volumeObject.addPayload(createSnapshotPayload);
if (cnt > 8) {
mockStorageMotionStrategy.makeBackupSnapshotSucceed(false);
}
SnapshotInfo newSnapshot = volumeService.takeSnapshot(vol);
if (newSnapshot == null) {
r = false;
}
} catch (Exception e) {
r = false;
}
return r;
}
});
Assert.assertTrue(task.get());
}
}
}

View File

@ -48,7 +48,6 @@
<bean id="clusterScopeStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ClusterScopeStoragePoolAllocator" />
<bean id="zoneWideStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ZoneWideStoragePoolAllocator" />
<bean id="dataStoreProviderManagerImpl" class="org.apache.cloudstack.storage.datastore.provider.DataStoreProviderManagerImpl" />
<bean id="ancientDataMotionStrategy" class="org.apache.cloudstack.storage.motion.AncientDataMotionStrategy" />
<bean id="storageCacheManagerImpl" class="org.apache.cloudstack.storage.cache.manager.StorageCacheManagerImpl" />
<bean id="storageCacheRandomAllocator" class="org.apache.cloudstack.storage.cache.allocator.StorageCacheRandomAllocator" />
<bean id="xenserverSnapshotStrategy" class="org.apache.cloudstack.storage.snapshot.XenserverSnapshotStrategy" />
@ -84,4 +83,9 @@
<bean id="AccountGuestVlanMapDaoImpl" class="com.cloud.network.dao.AccountGuestVlanMapDaoImpl" />
<bean id="StorageCacheReplacementAlgorithm" class="org.apache.cloudstack.storage.cache.manager.StorageCacheReplacementAlgorithmLRU" />
<bean id="ServiceOfferingDetailsDao" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl" />
<bean id='SnapshotManagerImpl' class='com.cloud.storage.snapshot.SnapshotManagerImpl'/>
<bean id='SnapshotPolicyDao' class='com.cloud.storage.dao.SnapshotPolicyDaoImpl'/>
<bean id='SnapshotScheduleDao' class='com.cloud.storage.dao.SnapshotScheduleDaoImpl' />
<bean id='UserContextInitializer' class='com.cloud.user.UserContextInitializer' />
</beans>

View File

@ -265,7 +265,7 @@ public class SnapshotObject implements SnapshotInfo {
this.snapshotStoreDao.update(snapshotStore.getId(), snapshotStore);
// update side-effect of snapshot operation
if(snapshotTO.getVolume().getPath() != null) {
if(snapshotTO.getVolume() != null && snapshotTO.getVolume().getPath() != null) {
VolumeVO vol = this.volumeDao.findByUuid(snapshotTO.getVolume().getUuid());
if(vol != null) {
s_logger.info("Update volume path change due to snapshot operation, volume " + vol.getId() + " path: "

View File

@ -18,6 +18,8 @@ package org.apache.cloudstack.storage.snapshot;
import javax.inject.Inject;
import com.cloud.storage.Volume;
import com.cloud.utils.db.DB;
import org.apache.cloudstack.engine.subsystem.api.storage.*;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
@ -189,7 +191,7 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
if (!Snapshot.State.BackedUp.equals(snapshotVO.getState())) {
throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId
+ " due to it is not in BackedUp Status");
+ " due to it is in " + snapshotVO.getState() + " Status");
}
// first mark the snapshot as destroyed, so that ui can't see it, but we
@ -235,40 +237,65 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
}
@Override
@DB
public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) {
SnapshotResult result = snapshotSvr.takeSnapshot(snapshot);
if (result.isFailed()) {
s_logger.debug("Failed to take snapshot: " + result.getResult());
throw new CloudRuntimeException(result.getResult());
SnapshotVO snapshotVO = snapshotDao.acquireInLockTable(snapshot.getId());
if (snapshotVO == null) {
throw new CloudRuntimeException("Failed to get lock on snapshot:" + snapshot.getId());
}
snapshot = result.getSnashot();
DataStore primaryStore = snapshot.getDataStore();
SnapshotInfo backupedSnapshot = this.backupSnapshot(snapshot);
try {
SnapshotInfo parent = snapshot.getParent();
if (backupedSnapshot != null && parent != null) {
Long parentSnapshotId = parent.getId();
while (parentSnapshotId != null && parentSnapshotId != 0L) {
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(),primaryStore.getId(), parentSnapshotId);
if (snapshotDataStoreVO != null) {
parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
snapshotStoreDao.remove(snapshotDataStoreVO.getId());
} else {
parentSnapshotId = null;
}
VolumeInfo volumeInfo = snapshot.getBaseVolume();
volumeInfo.stateTransit(Volume.Event.SnapshotRequested);
SnapshotResult result = null;
try {
result = snapshotSvr.takeSnapshot(snapshot);
if (result.isFailed()) {
s_logger.debug("Failed to take snapshot: " + result.getResult());
throw new CloudRuntimeException(result.getResult());
}
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(),
snapshot.getId());
if (snapshotDataStoreVO != null) {
snapshotDataStoreVO.setParentSnapshotId(0L);
snapshotStoreDao.update(snapshotDataStoreVO.getId(), snapshotDataStoreVO);
} finally {
if (result != null && result.isSuccess()) {
volumeInfo.stateTransit(Volume.Event.OperationSucceeded);
} else {
volumeInfo.stateTransit(Volume.Event.OperationFailed);
}
}
} catch (Exception e) {
s_logger.debug("Failed to clean up snapshots on primary storage", e);
snapshot = result.getSnashot();
DataStore primaryStore = snapshot.getDataStore();
SnapshotInfo backupedSnapshot = this.backupSnapshot(snapshot);
try {
SnapshotInfo parent = snapshot.getParent();
if (backupedSnapshot != null && parent != null) {
Long parentSnapshotId = parent.getId();
while (parentSnapshotId != null && parentSnapshotId != 0L) {
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(),primaryStore.getId(), parentSnapshotId);
if (snapshotDataStoreVO != null) {
parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
snapshotStoreDao.remove(snapshotDataStoreVO.getId());
} else {
parentSnapshotId = null;
}
}
SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(),
snapshot.getId());
if (snapshotDataStoreVO != null) {
snapshotDataStoreVO.setParentSnapshotId(0L);
snapshotStoreDao.update(snapshotDataStoreVO.getId(), snapshotDataStoreVO);
}
}
} catch (Exception e) {
s_logger.debug("Failed to clean up snapshots on primary storage", e);
}
return backupedSnapshot;
} finally {
if (snapshotVO != null) {
snapshotDao.releaseFromLockTable(snapshot.getId());
}
}
return backupedSnapshot;
}
@Override

View File

@ -25,6 +25,8 @@ import java.util.Map;
import javax.naming.ConfigurationException;
import com.cloud.utils.db.DB;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
@ -51,6 +53,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
private SearchBuilder<SnapshotDataStoreVO> cacheSearch;
private SearchBuilder<SnapshotDataStoreVO> snapshotSearch;
private SearchBuilder<SnapshotDataStoreVO> storeSnapshotSearch;
private SearchBuilder<SnapshotDataStoreVO> snapshotIdSearch;
private String parentSearch = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where store_id = ? " +
" and store_role = ? and volume_id = ? and state = 'Ready'" +
" order by created DESC " +
@ -101,6 +104,10 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
storeSnapshotSearch.and("store_role", storeSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ);
storeSnapshotSearch.done();
snapshotIdSearch = createSearchBuilder();
snapshotIdSearch.and("snapshot_id", snapshotIdSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
snapshotIdSearch.done();
return true;
}
@ -173,6 +180,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
}
@Override
@DB
public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId) {
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = null;
@ -191,8 +199,6 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
}
} catch (SQLException e) {
s_logger.debug("Failed to find parent snapshot: " + e.toString());
} finally {
txn.close();
}
return null;
}
@ -205,6 +211,13 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
return findOneBy(sc);
}
@Override
public List<SnapshotDataStoreVO> findBySnapshotId(long snapshotId) {
SearchCriteria<SnapshotDataStoreVO> sc = snapshotIdSearch.create();
sc.setParameters("snapshot_id", snapshotId);
return listBy(sc);
}
@Override
public List<SnapshotDataStoreVO> listDestroyed(long id) {
SearchCriteria<SnapshotDataStoreVO> sc = destroyedSearch.create();

View File

@ -266,6 +266,12 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore {
}
} else if (obj.getType() == DataObjectType.SNAPSHOT) {
return objectInStoreMgr.create(obj, this);
} else if (obj.getType() == DataObjectType.VOLUME) {
VolumeVO vol = volumeDao.findById(obj.getId());
if (vol != null) {
vol.setPoolId(this.getId());
volumeDao.update(vol.getId(), vol);
}
}
return objectInStoreMgr.get(obj, this);

View File

@ -518,6 +518,7 @@ public class VolumeServiceImpl implements VolumeService {
if (result.isSuccess()) {
vo.processEvent(Event.OperationSuccessed, result.getAnswer());
} else {
vo.processEvent(Event.OperationFailed);
volResult.setResult(result.getResult());
// hack for Vmware: host is down, previously download template to the host needs to be re-downloaded, so we need to reset
@ -1291,20 +1292,11 @@ public class VolumeServiceImpl implements VolumeService {
@Override
public SnapshotInfo takeSnapshot(VolumeInfo volume) {
VolumeObject vol = (VolumeObject) volume;
vol.stateTransit(Volume.Event.SnapshotRequested);
SnapshotInfo snapshot = null;
try {
snapshot = snapshotMgr.takeSnapshot(volume);
} catch (Exception e) {
s_logger.debug("Take snapshot: " + volume.getId() + " failed", e);
} finally {
if (snapshot != null) {
vol.stateTransit(Volume.Event.OperationSucceeded);
} else {
vol.stateTransit(Volume.Event.OperationFailed);
}
}
return snapshot;

View File

@ -51,7 +51,6 @@
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<scope>provided</scope>
<version>${cs.jna.version}</version>
</dependency>
</dependencies>

View File

@ -58,15 +58,19 @@ public class KVMInvestigator extends AdapterBase implements Investigator {
return null;
}
CheckOnHostCommand cmd = new CheckOnHostCommand(agent);
List<HostVO> neighbors = _resourceMgr.listAllHostsInCluster(agent.getClusterId());
List<HostVO> neighbors = _resourceMgr.listHostsInClusterByStatus(agent.getClusterId(), Status.Up);
for (HostVO neighbor : neighbors) {
if (neighbor.getId() == agent.getId() || neighbor.getHypervisorType() != Hypervisor.HypervisorType.KVM) {
continue;
}
Answer answer = _agentMgr.easySend(neighbor.getId(), cmd);
return answer.getResult() ? Status.Down : Status.Up;
try {
Answer answer = _agentMgr.easySend(neighbor.getId(), cmd);
if (answer != null) {
return answer.getResult() ? Status.Down : Status.Up;
}
} catch (Exception e) {
s_logger.debug("Failed to send command to host: " + neighbor.getId());
}
}
return null;

View File

@ -23,6 +23,7 @@ import java.io.File;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.net.URI;
import javax.naming.ConfigurationException;
@ -45,6 +46,9 @@ public class BridgeVifDriver extends VifDriverBase {
private static final Object _vnetBridgeMonitor = new Object();
private String _modifyVlanPath;
private String _modifyVxlanPath;
private String bridgeNameSchema;
@Override
public void configure(Map<String, Object> params) throws ConfigurationException {
@ -59,6 +63,8 @@ public class BridgeVifDriver extends VifDriverBase {
networkScriptsDir = "scripts/vm/network/vnet";
}
bridgeNameSchema = (String) params.get("network.bridge.name.schema");
String value = (String) params.get("scripts.timeout");
_timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
@ -66,7 +72,11 @@ public class BridgeVifDriver extends VifDriverBase {
if (_modifyVlanPath == null) {
throw new ConfigurationException("Unable to find modifyvlan.sh");
}
_modifyVxlanPath = Script.findScript(networkScriptsDir, "modifyvxlan.sh");
if (_modifyVxlanPath == null) {
throw new ConfigurationException("Unable to find modifyvxlan.sh");
}
try {
createControlNetwork();
} catch (LibvirtException e) {
@ -84,9 +94,11 @@ public class BridgeVifDriver extends VifDriverBase {
LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
String vlanId = null;
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
vlanId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
String vNetId = null;
String protocol = null;
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) {
vNetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
protocol = Networks.BroadcastDomainType.getSchemeValue(nic.getBroadcastUri()).scheme();
}
else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
throw new InternalErrorException("Nicira NVP Logicalswitches are not supported by the BridgeVifDriver");
@ -94,14 +106,14 @@ public class BridgeVifDriver extends VifDriverBase {
String trafficLabel = nic.getName();
if (nic.getType() == Networks.TrafficType.Guest) {
Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
&& !vlanId.equalsIgnoreCase("untagged")) {
if (trafficLabel != null && !trafficLabel.isEmpty()) {
s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
String brName = createVlanBr(vlanId, _pifs.get(trafficLabel));
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vNetId.equalsIgnoreCase("untagged")
|| nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) {
if(trafficLabel != null && !trafficLabel.isEmpty()) {
s_logger.debug("creating a vNet dev and bridge for guest traffic per traffic label " + trafficLabel);
String brName = createVnetBr(vNetId, _pifs.get(trafficLabel), protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
} else {
String brName = createVlanBr(vlanId, _pifs.get("private"));
String brName = createVnetBr(vNetId, _pifs.get("private"), protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
}
} else {
@ -114,13 +126,13 @@ public class BridgeVifDriver extends VifDriverBase {
} else if (nic.getType() == Networks.TrafficType.Public) {
Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
&& !vlanId.equalsIgnoreCase("untagged")) {
if (trafficLabel != null && !trafficLabel.isEmpty()) {
s_logger.debug("creating a vlan dev and bridge for public traffic per traffic label " + trafficLabel);
String brName = createVlanBr(vlanId, _pifs.get(trafficLabel));
&& !vNetId.equalsIgnoreCase("untagged")) {
if(trafficLabel != null && !trafficLabel.isEmpty()){
s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel);
String brName = createVnetBr(vNetId, _pifs.get(trafficLabel), protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
} else {
String brName = createVlanBr(vlanId, _pifs.get("public"));
String brName = createVnetBr(vNetId, _pifs.get("public"), protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
}
} else {
@ -145,17 +157,22 @@ public class BridgeVifDriver extends VifDriverBase {
return "br" + pifName + "-"+ vnetId;
}
private String createVlanBr(String vlanId, String nic)
private String createVnetBr(String vNetId, String nic, String protocol)
throws InternalErrorException {
String brName = setVnetBrName(nic, vlanId);
createVnet(vlanId, nic, brName);
String brName = setVnetBrName(nic, vNetId);
createVnet(vNetId, nic, brName, protocol);
return brName;
}
private void createVnet(String vnetId, String pif, String brName)
private void createVnet(String vnetId, String pif, String brName, String protocol)
throws InternalErrorException {
synchronized (_vnetBridgeMonitor) {
final Script command = new Script(_modifyVlanPath, _timeout, s_logger);
String script = _modifyVlanPath;
if(protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
script = _modifyVxlanPath;
}
final Script command = new Script(script, _timeout, s_logger);
command.add("-v", vnetId);
command.add("-p", pif);
command.add("-b", brName);
@ -171,7 +188,7 @@ public class BridgeVifDriver extends VifDriverBase {
private void deleteVnetBr(String brName) {
synchronized (_vnetBridgeMonitor) {
String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | grep vnet");
String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | tr '\n' ' '");
if (cmdout != null && cmdout.contains("vnet")) {
// Active VM remains on that bridge
return;
@ -201,8 +218,16 @@ public class BridgeVifDriver extends VifDriverBase {
s_logger.debug("unable to get a vNet ID from name " + brName);
return;
}
final Script command = new Script(_modifyVlanPath, _timeout, s_logger);
String scriptPath = null;
if (cmdout != null && cmdout.contains("vxlan")) {
scriptPath = _modifyVxlanPath;
} else{
scriptPath = _modifyVlanPath;
}
final Script command = new Script(scriptPath, _timeout, s_logger);
command.add("-o", "delete");
command.add("-v", vNetId);
command.add("-p", pName);

View File

@ -1365,7 +1365,7 @@ ServerResource {
secondaryStorageUrl
+ volumeDestPath);
_storagePoolMgr.copyPhysicalDisk(volume,
destVolumeName,secondaryStoragePool);
destVolumeName,secondaryStoragePool, 0);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
} else {
volumePath = "/volumes/" + cmd.getVolumeId() + File.separator;
@ -1375,7 +1375,7 @@ ServerResource {
KVMPhysicalDisk volume = secondaryStoragePool
.getPhysicalDisk(cmd.getVolumePath() + ".qcow2");
_storagePoolMgr.copyPhysicalDisk(volume, volumeName,
primaryPool);
primaryPool, 0);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
}
} catch (CloudRuntimeException e) {
@ -1461,7 +1461,7 @@ ServerResource {
} else {
BaseVol = primaryPool.getPhysicalDisk(cmd.getTemplateUrl());
vol = _storagePoolMgr.createDiskFromTemplate(BaseVol, UUID
.randomUUID().toString(), primaryPool);
.randomUUID().toString(), primaryPool, 0);
}
if (vol == null) {
return new Answer(cmd, false,
@ -1522,7 +1522,7 @@ ServerResource {
/* Copy volume to primary storage */
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), primaryPool);
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), primaryPool, 0);
return primaryVol;
} catch (CloudRuntimeException e) {
s_logger.error("Failed to download template to primary storage",e);
@ -2347,7 +2347,7 @@ ServerResource {
primaryUuid);
String volUuid = UUID.randomUUID().toString();
KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot,
volUuid, primaryPool);
volUuid, primaryPool, 0);
return new CreateVolumeFromSnapshotAnswer(cmd, true, "",
disk.getName());
} catch (CloudRuntimeException e) {
@ -2498,7 +2498,7 @@ ServerResource {
QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + cmd.getUniqueName() + ".qcow2");
destFile.setFormat(PhysicalDiskFormat.QCOW2);
QemuImg q = new QemuImg();
QemuImg q = new QemuImg(0);
try {
q.convert(srcFile, destFile);
} catch (QemuImgException e) {
@ -2601,7 +2601,7 @@ ServerResource {
cmd.getPoolUuid());
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(
tmplVol, UUID.randomUUID().toString(), primaryPool);
tmplVol, UUID.randomUUID().toString(), primaryPool, 0);
return new PrimaryStorageDownloadAnswer(primaryVol.getName(),
primaryVol.getSize());
@ -3357,10 +3357,28 @@ ServerResource {
}
}
protected String getUuid(String uuid) {
if (uuid == null) {
uuid = UUID.randomUUID().toString();
} else {
try {
UUID uuid2 = UUID.fromString(uuid);
String uuid3 = uuid2.toString();
if (!uuid3.equals(uuid)) {
uuid = UUID.randomUUID().toString();
}
} catch (IllegalArgumentException e) {
uuid = UUID.randomUUID().toString();
}
}
return uuid;
}
protected LibvirtVMDef createVMFromSpec(VirtualMachineTO vmTO) {
LibvirtVMDef vm = new LibvirtVMDef();
vm.setDomainName(vmTO.getName());
vm.setDomUUID(vmTO.getUuid());
String uuid = vmTO.getUuid();
uuid = getUuid(uuid);
vm.setDomUUID(uuid);
vm.setDomDescription(vmTO.getOs());
GuestDef guest = new GuestDef();
@ -3534,15 +3552,18 @@ ServerResource {
if (vmSpec.getType() != VirtualMachine.Type.User) {
if ((_kernelVersion < 2006034) && (conn.getVersion() < 1001000)) { // CLOUDSTACK-2823: try passCmdLine some times if kernel < 2.6.34 and qemu < 1.1.0 on hypervisor (for instance, CentOS 6.4)
//wait for 5 minutes at most
for (int count = 0; count < 30; count ++) {
boolean succeed = passCmdLine(vmName, vmSpec.getBootArgs());
if (succeed) {
break;
String controlIp = null;
for (NicTO nic : nics) {
if (nic.getType() == TrafficType.Control) {
controlIp = nic.getIp();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
s_logger.trace("Ignoring InterruptedException.", e);
}
for (int count = 0; count < 30; count ++) {
passCmdLine(vmName, vmSpec.getBootArgs());
//check router is up?
boolean result = _virtRouterResource.connect(controlIp, 1, 5000);
if (result) {
break;
}
}
} else {
@ -3627,10 +3648,10 @@ ServerResource {
physicalDisk = secondaryStorage.getPhysicalDisk(volName);
} else if (volume.getType() != Volume.Type.ISO) {
PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore();
pool = _storagePoolMgr.getStoragePool(
store.getPoolType(),
store.getUuid());
physicalDisk = pool.getPhysicalDisk(data.getPath());
physicalDisk = _storagePoolMgr.getPhysicalDisk( store.getPoolType(),
store.getUuid(),
data.getPath());
pool = physicalDisk.getPool();
}
String volPath = null;
@ -3703,10 +3724,9 @@ ServerResource {
if (volume.getType() == Volume.Type.ROOT) {
DataTO data = volume.getData();
PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore();
KVMStoragePool pool = _storagePoolMgr.getStoragePool(
store.getPoolType(),
store.getUuid());
KVMPhysicalDisk physicalDisk = pool.getPhysicalDisk(data.getPath());
KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk( store.getPoolType(),
store.getUuid(),
data.getPath());
FilesystemDef rootFs = new FilesystemDef(physicalDisk.getPath(), "/");
vm.getDevices().addDevice(rootFs);
break;
@ -3748,6 +3768,10 @@ ServerResource {
// need to umount secondary storage
String path = disk.getDiskPath();
String poolUuid = null;
if (path.endsWith("systemvm.iso")) {
//Don't need to clean up system vm iso, as it's stored in local
return true;
}
if (path != null) {
String[] token = path.split("/");
if (token.length > 3) {

View File

@ -31,11 +31,40 @@ import com.cloud.hypervisor.kvm.resource.KVMHAMonitor;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;
public class KVMStoragePoolManager {
private static final Logger s_logger = Logger
.getLogger(KVMStoragePoolManager.class);
private class StoragePoolInformation {
String name;
String host;
int port;
String path;
String userInfo;
boolean type;
StoragePoolType poolType;
public StoragePoolInformation(String name,
String host,
int port,
String path,
String userInfo,
StoragePoolType poolType,
boolean type) {
this.name = name;
this.host = host;
this.port = port;
this.path = path;
this.userInfo = userInfo;
this.type = type;
this.poolType = poolType;
}
}
private StorageAdaptor _storageAdaptor;
private KVMHAMonitor _haMonitor;
private final Map<String, Object> _storagePools = new ConcurrentHashMap<String, Object>();
private final Map<String, StoragePoolInformation> _storagePools = new ConcurrentHashMap<String, StoragePoolInformation>();
private final Map<String, StorageAdaptor> _storageMapper = new HashMap<String, StorageAdaptor>();
private StorageAdaptor getStorageAdaptor(StoragePoolType type) {
@ -51,10 +80,10 @@ public class KVMStoragePoolManager {
return adaptor;
}
private void addStoragePool(String uuid) {
private void addStoragePool(String uuid, StoragePoolInformation pool) {
synchronized (_storagePools) {
if (!_storagePools.containsKey(uuid)) {
_storagePools.put(uuid, new Object());
_storagePools.put(uuid, pool);
}
}
}
@ -68,8 +97,18 @@ public class KVMStoragePoolManager {
}
public KVMStoragePool getStoragePool(StoragePoolType type, String uuid) {
StorageAdaptor adaptor = getStorageAdaptor(type);
return adaptor.getStoragePool(uuid);
KVMStoragePool pool = null;
try {
pool = adaptor.getStoragePool(uuid);
} catch(Exception e) {
StoragePoolInformation info = _storagePools.get(uuid);
if (info != null) {
pool = createStoragePool(info.name, info.host, info.port, info.path, info.userInfo, info.poolType, info.type);
}
}
return pool;
}
public KVMStoragePool getStoragePoolByURI(String uri) {
@ -98,6 +137,39 @@ public class KVMStoragePoolManager {
return createStoragePool(uuid, sourceHost, 0, sourcePath, "", protocol, false);
}
public KVMPhysicalDisk getPhysicalDisk(StoragePoolType type, String poolUuid, String volName) {
int cnt = 0;
int retries = 10;
KVMPhysicalDisk vol = null;
//harden get volume, try cnt times to get volume, in case volume is created on other host
String errMsg = "";
while (cnt < retries) {
try {
KVMStoragePool pool = getStoragePool(type, poolUuid);
vol = pool.getPhysicalDisk(volName);
if (vol != null) {
break;
}
} catch (Exception e) {
s_logger.debug("Failed to find volume:" + volName + " due to" + e.toString() + ", retry:" + cnt);
errMsg = e.toString();
}
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
}
cnt++;
}
if (vol == null) {
throw new CloudRuntimeException(errMsg);
} else {
return vol;
}
}
public KVMStoragePool createStoragePool( String name, String host, int port,
String path, String userInfo,
StoragePoolType type) {
@ -105,7 +177,8 @@ public class KVMStoragePoolManager {
return createStoragePool(name, host, port, path, userInfo, type, true);
}
private KVMStoragePool createStoragePool( String name, String host, int port,
//Note: due to bug CLOUDSTACK-4459, createStoragepool can be called in parallel, so need to be synced.
private synchronized KVMStoragePool createStoragePool( String name, String host, int port,
String path, String userInfo,
StoragePoolType type, boolean primaryStorage) {
StorageAdaptor adaptor = getStorageAdaptor(type);
@ -119,7 +192,8 @@ public class KVMStoragePoolManager {
PoolType.PrimaryStorage);
_haMonitor.addStoragePool(nfspool);
}
addStoragePool(pool.getUuid());
StoragePoolInformation info = new StoragePoolInformation(name, host, port, path, userInfo, type, primaryStorage);
addStoragePool(pool.getUuid(), info);
return pool;
}
@ -132,25 +206,25 @@ public class KVMStoragePoolManager {
}
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name,
KVMStoragePool destPool) {
KVMStoragePool destPool, int timeout) {
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
// LibvirtStorageAdaptor-specific statement
if (destPool.getType() == StoragePoolType.RBD) {
return adaptor.createDiskFromTemplate(template, name,
PhysicalDiskFormat.RAW, template.getSize(), destPool);
PhysicalDiskFormat.RAW, template.getSize(), destPool, timeout);
} else if (destPool.getType() == StoragePoolType.CLVM) {
return adaptor.createDiskFromTemplate(template, name,
PhysicalDiskFormat.RAW, template.getSize(),
destPool);
destPool, timeout);
} else if (template.getFormat() == PhysicalDiskFormat.DIR) {
return adaptor.createDiskFromTemplate(template, name,
PhysicalDiskFormat.DIR,
template.getSize(), destPool);
template.getSize(), destPool, timeout);
} else {
return adaptor.createDiskFromTemplate(template, name,
PhysicalDiskFormat.QCOW2,
template.getSize(), destPool);
template.getSize(), destPool, timeout);
}
}
@ -163,9 +237,9 @@ public class KVMStoragePoolManager {
}
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name,
KVMStoragePool destPool) {
KVMStoragePool destPool, int timeout) {
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
return adaptor.copyPhysicalDisk(disk, name, destPool);
return adaptor.copyPhysicalDisk(disk, name, destPool, timeout);
}
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,

View File

@ -147,8 +147,7 @@ public class KVMStorageProcessor implements StorageProcessor {
DataTO destData = cmd.getDestTO();
TemplateObjectTO template = (TemplateObjectTO) srcData;
DataStoreTO imageStore = template.getDataStore();
TemplateObjectTO volume = (TemplateObjectTO) destData;
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) volume.getDataStore();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) destData.getDataStore();
if (!(imageStore instanceof NfsTO)) {
return new CopyCmdAnswer("unsupported protocol");
@ -195,21 +194,34 @@ public class KVMStorageProcessor implements StorageProcessor {
primaryStore.getUuid());
KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(),
primaryPool);
primaryPool, cmd.getWaitInMillSeconds());
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(primaryVol.getName());
DataTO data = null;
/**
* Force the ImageFormat for RBD templates to RAW
*
*/
if (primaryPool.getType() == StoragePoolType.RBD) {
newTemplate.setFormat(ImageFormat.RAW);
} else {
newTemplate.setFormat(ImageFormat.QCOW2);
if (destData.getObjectType() == DataObjectType.TEMPLATE) {
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(primaryVol.getName());
if (primaryPool.getType() == StoragePoolType.RBD) {
newTemplate.setFormat(ImageFormat.RAW);
} else {
newTemplate.setFormat(ImageFormat.QCOW2);
}
data = newTemplate;
} else if (destData.getObjectType() == DataObjectType.VOLUME) {
VolumeObjectTO volumeObjectTO = new VolumeObjectTO();
volumeObjectTO.setPath(primaryVol.getName());
if (primaryVol.getFormat() == PhysicalDiskFormat.RAW)
volumeObjectTO.setFormat(ImageFormat.RAW);
else if (primaryVol.getFormat() == PhysicalDiskFormat.QCOW2) {
volumeObjectTO.setFormat(ImageFormat.QCOW2);
}
data = volumeObjectTO;
}
return new CopyCmdAnswer(newTemplate);
return new CopyCmdAnswer(data);
} catch (CloudRuntimeException e) {
return new CopyCmdAnswer(e.toString());
} finally {
@ -220,7 +232,7 @@ public class KVMStorageProcessor implements StorageProcessor {
}
// this is much like PrimaryStorageDownloadCommand, but keeping it separate
private KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool) {
private KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool, int timeout) {
int index = templateUrl.lastIndexOf("/");
String mountpoint = templateUrl.substring(0, index);
String templateName = null;
@ -257,7 +269,7 @@ public class KVMStorageProcessor implements StorageProcessor {
/* Copy volume to primary storage */
KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(),
primaryPool);
primaryPool, timeout);
return primaryVol;
} catch (CloudRuntimeException e) {
s_logger.error("Failed to download template to primary storage", e);
@ -287,10 +299,15 @@ public class KVMStorageProcessor implements StorageProcessor {
String templatePath = template.getPath();
if (primaryPool.getType() == StoragePoolType.CLVM) {
vol = templateToPrimaryDownload(templatePath, primaryPool);
templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
vol = templateToPrimaryDownload(templatePath, primaryPool, cmd.getWaitInMillSeconds());
} else {
BaseVol = primaryPool.getPhysicalDisk(templatePath);
vol = storagePoolMgr.createDiskFromTemplate(BaseVol, UUID.randomUUID().toString(), primaryPool);
if (templatePath.contains("/mnt")) {
//upgrade issue, if the path contains path, need to extract the volume uuid from path
templatePath = templatePath.substring(templatePath.lastIndexOf(File.separator) + 1);
}
BaseVol = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath);
vol = storagePoolMgr.createDiskFromTemplate(BaseVol, UUID.randomUUID().toString(), BaseVol.getPool(), cmd.getWaitInMillSeconds());
}
if (vol == null) {
return new CopyCmdAnswer(" Can't create storage volume on storage pool");
@ -361,7 +378,7 @@ public class KVMStorageProcessor implements StorageProcessor {
.getPhysicalDisk(srcVolumeName);
volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
KVMPhysicalDisk newDisk = storagePoolMgr.copyPhysicalDisk(volume, volumeName,
primaryPool);
primaryPool, cmd.getWaitInMillSeconds());
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setFormat(ImageFormat.valueOf(newDisk.getFormat().toString().toUpperCase()));
newVol.setPath(volumeName);
@ -394,28 +411,14 @@ public class KVMStorageProcessor implements StorageProcessor {
String destVolumePath = destData.getPath();
String secondaryStorageUrl = nfsStore.getUrl();
KVMStoragePool secondaryStoragePool = null;
KVMStoragePool primaryPool = null;
try {
try {
primaryPool = storagePoolMgr.getStoragePool(
primaryStore.getPoolType(),
primaryStore.getUuid());
} catch (CloudRuntimeException e) {
if (e.getMessage().contains("not found")) {
primaryPool = storagePoolMgr.createStoragePool(primaryStore.getUuid(),
primaryStore.getHost(), primaryStore.getPort(),
primaryStore.getPath(), null,
primaryStore.getPoolType());
} else {
return new CopyCmdAnswer(e.getMessage());
}
}
try {
String volumeName = UUID.randomUUID().toString();
String destVolumeName = volumeName + "." + destFormat.getFileExtension();
KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(srcVolumePath);
KVMPhysicalDisk volume = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), srcVolumePath);
volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(
secondaryStorageUrl);
secondaryStoragePool.createFolder(destVolumePath);
@ -423,7 +426,7 @@ public class KVMStorageProcessor implements StorageProcessor {
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(
secondaryStorageUrl + File.separator + destVolumePath);
storagePoolMgr.copyPhysicalDisk(volume,
destVolumeName,secondaryStoragePool);
destVolumeName,secondaryStoragePool, cmd.getWaitInMillSeconds());
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(destVolumePath + File.separator + destVolumeName);
newVol.setFormat(destFormat);
@ -441,7 +444,7 @@ public class KVMStorageProcessor implements StorageProcessor {
public Answer createTemplateFromVolume(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
DataTO destData = cmd.getDestTO();
int wait = cmd.getWait();
int wait = cmd.getWaitInMillSeconds();
TemplateObjectTO template = (TemplateObjectTO) destData;
DataStoreTO imageStore = template.getDataStore();
VolumeObjectTO volume = (VolumeObjectTO) srcData;
@ -459,24 +462,15 @@ public class KVMStorageProcessor implements StorageProcessor {
secondaryStorage = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl());
try {
primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
} catch (CloudRuntimeException e) {
if (e.getMessage().contains("not found")) {
primary = storagePoolMgr.createStoragePool(primaryStore.getUuid(), primaryStore.getHost(),
primaryStore.getPort(), primaryStore.getPath(), null, primaryStore.getPoolType());
} else {
return new CopyCmdAnswer(e.getMessage());
}
}
primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
KVMPhysicalDisk disk = primary.getPhysicalDisk(volume.getPath());
KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volume.getPath());
String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateFolder;
this.storageLayer.mkdirs(tmpltPath);
String templateName = UUID.randomUUID().toString();
if (primary.getType() != StoragePoolType.RBD) {
Script command = new Script(_createTmplPath, wait * 1000, s_logger);
Script command = new Script(_createTmplPath, wait, s_logger);
command.add("-f", disk.getPath());
command.add("-t", tmpltPath);
command.add("-n", templateName + ".qcow2");
@ -497,7 +491,7 @@ public class KVMStorageProcessor implements StorageProcessor {
QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + templateName + ".qcow2");
destFile.setFormat(PhysicalDiskFormat.QCOW2);
QemuImg q = new QemuImg();
QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
try {
q.convert(srcFile, destFile);
} catch (QemuImgException e) {
@ -625,7 +619,7 @@ public class KVMStorageProcessor implements StorageProcessor {
SnapshotObjectTO snapshotOnCacheStore = (SnapshotObjectTO)answer.getNewData();
snapshotOnCacheStore.setDataStore(cacheStore);
((SnapshotObjectTO) destData).setDataStore(imageStore);
CopyCommand newCpyCmd = new CopyCommand(snapshotOnCacheStore, destData, cmd.getWait(), cmd.executeInSequence());
CopyCommand newCpyCmd = new CopyCommand(snapshotOnCacheStore, destData, cmd.getWaitInMillSeconds(), cmd.executeInSequence());
return copyToObjectStore(newCpyCmd);
}
@Override
@ -661,9 +655,9 @@ public class KVMStorageProcessor implements StorageProcessor {
snapshotRelPath = destSnapshot.getPath();
snapshotDestPath = ssPmountPath + File.separator + snapshotRelPath;
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(),
primaryStore.getUuid());
KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(volumePath);
KVMPhysicalDisk snapshotDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(),
primaryStore.getUuid(), volumePath);
KVMStoragePool primaryPool = snapshotDisk.getPool();
/**
* RBD snapshots can't be copied using qemu-img, so we have to use
@ -729,7 +723,7 @@ public class KVMStorageProcessor implements StorageProcessor {
return new CopyCmdAnswer(e.toString());
}
} else {
Script command = new Script(_manageSnapshotPath, cmd.getWait() * 1000, s_logger);
Script command = new Script(_manageSnapshotPath, cmd.getWaitInMillSeconds(), s_logger);
command.add("-b", snapshotDisk.getPath());
command.add("-n", snapshotName);
command.add("-p", snapshotDestPath);
@ -798,6 +792,7 @@ public class KVMStorageProcessor implements StorageProcessor {
}
}
protected synchronized String attachOrDetachISO(Connect conn, String vmName, String isoPath, boolean isAttach)
throws LibvirtException, URISyntaxException, InternalErrorException {
String isoXml = null;
@ -967,9 +962,8 @@ public class KVMStorageProcessor implements StorageProcessor {
String vmName = cmd.getVmName();
try {
Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
KVMStoragePool primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
KVMPhysicalDisk phyDisk = primary.getPhysicalDisk(vol.getPath());
attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue());
return new AttachAnswer(disk);
@ -990,9 +984,8 @@ public class KVMStorageProcessor implements StorageProcessor {
String vmName = cmd.getVmName();
try {
Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
KVMStoragePool primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
KVMPhysicalDisk phyDisk = primary.getPhysicalDisk(vol.getPath());
attachOrDetachDisk(conn, false, vmName, phyDisk, disk.getDiskSeq().intValue());
return new DettachAnswer(disk);
@ -1064,7 +1057,8 @@ public class KVMStorageProcessor implements StorageProcessor {
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(),
primaryStore.getUuid());
KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(volume.getPath());
KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(),
primaryStore.getUuid(), volume.getPath());
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) {
String vmUuid = vm.getUUIDString();
Object[] args = new Object[] { snapshotName, vmUuid };
@ -1191,7 +1185,7 @@ public class KVMStorageProcessor implements StorageProcessor {
String primaryUuid = pool.getUuid();
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getPoolType(), primaryUuid);
String volUuid = UUID.randomUUID().toString();
KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, volUuid, primaryPool);
KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, volUuid, primaryPool, cmd.getWaitInMillSeconds());
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(disk.getName());
newVol.setSize(disk.getVirtualSize());

View File

@ -101,10 +101,15 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
try {
vol = pool.storageVolLookupByName(volName);
} catch (LibvirtException e) {
s_logger.debug("Can't find volume: " + e.toString());
}
if (vol == null) {
storagePoolRefresh(pool);
try {
refreshPool(pool);
} catch (LibvirtException e) {
s_logger.debug("failed to refresh pool: " + e.toString());
}
try {
vol = pool.storageVolLookupByName(volName);
} catch (LibvirtException e) {
@ -119,6 +124,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(UUID
.randomUUID().toString(), size, format, null, null);
s_logger.debug(volDef.toString());
return pool.storageVolCreateXML(volDef.toString(), 0);
}
@ -128,7 +134,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
refreshPool(pool);
}
} catch (LibvirtException e) {
s_logger.debug("refresh storage pool failed: " + e.toString());
}
}
@ -397,7 +403,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
return pool;
} catch (LibvirtException e) {
throw new CloudRuntimeException(e.toString());
s_logger.debug("can't get storage pool",e);
throw new CloudRuntimeException(e.toString(), e);
}
}
@ -437,6 +444,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
}
return disk;
} catch (LibvirtException e) {
s_logger.debug("Failed to get physical disk:", e);
throw new CloudRuntimeException(e.toString());
}
@ -758,7 +766,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
*/
@Override
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool, int timeout) {
String newUuid = UUID.randomUUID().toString();
KVMStoragePool srcPool = template.getPool();
@ -775,20 +783,20 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
if (destPool.getType() != StoragePoolType.RBD) {
disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize());
if (template.getFormat() == PhysicalDiskFormat.TAR) {
Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath());
Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath(), timeout);
} else if (template.getFormat() == PhysicalDiskFormat.DIR) {
Script.runSimpleBashScript("mkdir -p " + disk.getPath());
Script.runSimpleBashScript("chmod 755 " + disk.getPath());
Script.runSimpleBashScript("cp -p -r " + template.getPath() + "/* " + disk.getPath());
Script.runSimpleBashScript("cp -p -r " + template.getPath() + "/* " + disk.getPath(), timeout);
} else if (format == PhysicalDiskFormat.QCOW2) {
QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
QemuImgFile destFile = new QemuImgFile(disk.getPath());
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(timeout);
qemu.create(destFile, backingFile);
} else if (format == PhysicalDiskFormat.RAW) {
QemuImgFile sourceFile = new QemuImgFile(template.getPath(), template.getFormat());
QemuImgFile destFile = new QemuImgFile(disk.getPath(), PhysicalDiskFormat.RAW);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(timeout);
qemu.convert(sourceFile, destFile);
}
} else {
@ -798,7 +806,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
disk.setSize(template.getVirtualSize());
disk.setVirtualSize(disk.getSize());
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(timeout);
QemuImgFile srcFile;
QemuImgFile destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
destPool.getSourcePort(),
@ -952,7 +960,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
*/
@Override
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name,
KVMStoragePool destPool) {
KVMStoragePool destPool, int timeout) {
/**
With RBD you can't run qemu-img convert with an existing RBD image as destination
@ -991,24 +999,27 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
String destPath = newDisk.getPath();
PhysicalDiskFormat destFormat = newDisk.getFormat();
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(timeout);
QemuImgFile srcFile = null;
QemuImgFile destFile = null;
if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
if (sourceFormat == PhysicalDiskFormat.TAR) {
Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath);
Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath, timeout);
} else if (sourceFormat == PhysicalDiskFormat.DIR) {
Script.runSimpleBashScript("mkdir -p " + destPath);
Script.runSimpleBashScript("chmod 755 " + destPath);
Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath);
Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath, timeout);
} else {
srcFile = new QemuImgFile(sourcePath, sourceFormat);
try {
Map<String, String> info = qemu.info(srcFile);
String backingFile = info.get(new String("backing_file"));
if (sourceFormat.equals(destFormat) && backingFile == null) {
Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath);
String result = Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath, timeout);
if (result != null) {
throw new CloudRuntimeException("Failed to create disk: " + result);
}
} else {
destFile = new QemuImgFile(destPath, destFormat);
try {
@ -1169,45 +1180,12 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
// However, we also need to fix the issues in CloudStack source code.
// A file lock is used to prevent deleting a volume from a KVM storage pool when refresh it.
private void refreshPool(StoragePool pool) throws LibvirtException {
Connect conn = LibvirtConnection.getConnection();
LibvirtStoragePoolDef spd = getStoragePoolDef(conn, pool);
if ((! spd.getPoolType().equals(LibvirtStoragePoolDef.poolType.NETFS))
&& (! spd.getPoolType().equals(LibvirtStoragePoolDef.poolType.DIR))) {
pool.refresh(0);
return;
}
String lockFile = spd.getTargetPath() + File.separator + _lockfile;
s_logger.debug("Attempting to lock pool " + pool.getName() + " with file " + lockFile);
if (lock(lockFile, ACQUIRE_GLOBAL_FILELOCK_TIMEOUT_FOR_KVM)) {
try {
pool.refresh(0);
} finally {
s_logger.debug("Releasing the lock on pool " + pool.getName() + " with file " + lockFile);
unlock(lockFile);
}
} else {
throw new CloudRuntimeException("Can not get file lock to refresh the pool " + pool.getName());
}
pool.refresh(0);
return;
}
private void deleteVol(LibvirtStoragePool pool, StorageVol vol) throws LibvirtException {
if ((! pool.getType().equals(StoragePoolType.NetworkFilesystem))
&& (! pool.getType().equals(StoragePoolType.Filesystem))) {
vol.delete(0);
return;
}
String lockFile = pool.getLocalPath() + File.separator + _lockfile;
s_logger.debug("Attempting to lock pool " + pool.getName() + " with file " + lockFile);
if (lock(lockFile, ACQUIRE_GLOBAL_FILELOCK_TIMEOUT_FOR_KVM)) {
try {
vol.delete(0);
} finally {
s_logger.debug("Releasing the lock on pool " + pool.getName() + " with file " + lockFile);
unlock(lockFile);
}
} else {
throw new CloudRuntimeException("Can not get file lock to delete the volume " + vol.getName());
}
vol.delete(0);
}
private boolean lock(String path, int wait) {

View File

@ -16,14 +16,19 @@
// under the License.
package com.cloud.hypervisor.kvm.storage;
import java.io.File;
import java.util.List;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.log4j.Logger;
import org.libvirt.StoragePool;
import com.cloud.storage.Storage.StoragePoolType;
public class LibvirtStoragePool implements KVMStoragePool {
private static final Logger s_logger = Logger
.getLogger(LibvirtStoragePool.class);
protected String uuid;
protected String uri;
protected long capacity;
@ -120,7 +125,32 @@ public class LibvirtStoragePool implements KVMStoragePool {
@Override
public KVMPhysicalDisk getPhysicalDisk(String volumeUuid) {
return this._storageAdaptor.getPhysicalDisk(volumeUuid, this);
KVMPhysicalDisk disk = null;
try {
disk = this._storageAdaptor.getPhysicalDisk(volumeUuid, this);
} catch (CloudRuntimeException e) {
if ((this.getStoragePoolType() != StoragePoolType.NetworkFilesystem) &&
(this.getStoragePoolType() != StoragePoolType.Filesystem)) {
throw e;
}
}
if (disk != null) {
return disk;
}
s_logger.debug("find volume bypass libvirt");
//For network file system or file system, try to use java file to find the volume, instead of through libvirt. BUG:CLOUDSTACK-4459
String localPoolPath = this.getLocalPath();
File f = new File(localPoolPath + File.separator + volumeUuid);
if (!f.exists()) {
s_logger.debug("volume: " + volumeUuid + " not exist on storage pool");
throw new CloudRuntimeException("Can't find volume:" + volumeUuid);
}
disk = new KVMPhysicalDisk(f.getPath(), volumeUuid, this);
disk.setFormat(PhysicalDiskFormat.QCOW2);
disk.setSize(f.length());
disk.setVirtualSize(f.length());
return disk;
}
@Override

View File

@ -40,7 +40,7 @@ public interface StorageAdaptor {
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
String name, PhysicalDiskFormat format, long size,
KVMStoragePool destPool);
KVMStoragePool destPool, int timeout);
public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk,
String name, PhysicalDiskFormat format, long size,
@ -50,7 +50,7 @@ public interface StorageAdaptor {
KVMStoragePool pool);
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name,
KVMStoragePool destPools);
KVMStoragePool destPools, int timeout);
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,
String snapshotName, String name, KVMStoragePool destPool);

View File

@ -31,6 +31,7 @@ public class QemuImg {
/* The qemu-img binary. We expect this to be in $PATH */
public String _qemuImgPath = "qemu-img";
private int timeout;
/* Shouldn't we have KVMPhysicalDisk and LibvirtVMDef read this? */
public static enum PhysicalDiskFormat {
@ -46,8 +47,12 @@ public class QemuImg {
}
}
public QemuImg() {
public QemuImg(int timeout) {
this.timeout = timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
/**
@ -84,7 +89,7 @@ public class QemuImg {
* @return void
*/
public void create(QemuImgFile file, QemuImgFile backingFile, Map<String, String> options) throws QemuImgException {
Script s = new Script(_qemuImgPath);
Script s = new Script(_qemuImgPath, timeout);
s.add("create");
if (options != null && !options.isEmpty()) {
@ -181,7 +186,7 @@ public class QemuImg {
* @return void
*/
public void convert(QemuImgFile srcFile, QemuImgFile destFile, Map<String, String> options) throws QemuImgException {
Script s = new Script(_qemuImgPath);
Script s = new Script(_qemuImgPath, timeout);
s.add("convert");
s.add("-f");
s.add(srcFile.getFormat().toString());

View File

@ -24,11 +24,13 @@ import com.cloud.template.VirtualMachineTemplate.BootloaderType;
import com.cloud.utils.Pair;
import com.cloud.vm.VirtualMachine;
import junit.framework.Assert;
import org.apache.commons.lang.SystemUtils;
import org.junit.Assume;
import org.junit.Test;
import java.util.Random;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@ -195,4 +197,17 @@ public class LibvirtComputingResourceTest {
Pair<Double, Double> stats = LibvirtComputingResource.getNicStats("lo");
assertNotNull(stats);
}
@Test
public void testUUID() {
String uuid = "1";
LibvirtComputingResource lcr = new LibvirtComputingResource();
uuid =lcr.getUuid(uuid);
Assert.assertTrue(!uuid.equals("1"));
String oldUuid = UUID.randomUUID().toString();
uuid = oldUuid;
uuid = lcr.getUuid(uuid);
Assert.assertTrue(uuid.equals(oldUuid));
}
}

View File

@ -38,7 +38,7 @@ public class QemuImgTest {
long size = 10995116277760l;
QemuImgFile file = new QemuImgFile(filename, size, PhysicalDiskFormat.QCOW2);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
Map<String, String> info = qemu.info(file);
@ -69,7 +69,7 @@ public class QemuImgTest {
options.put("cluster_size", clusterSize);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file, options);
Map<String, String> info = qemu.info(file);
@ -96,7 +96,7 @@ public class QemuImgTest {
QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.QCOW2);
try {
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
qemu.resize(file, endSize);
Map<String, String> info = qemu.info(file);
@ -125,7 +125,7 @@ public class QemuImgTest {
QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.RAW);
try {
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
qemu.resize(file, increment, true);
Map<String, String> info = qemu.info(file);
@ -153,7 +153,7 @@ public class QemuImgTest {
QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.RAW);
try {
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
qemu.resize(file, increment, true);
Map<String, String> info = qemu.info(file);
@ -182,7 +182,7 @@ public class QemuImgTest {
long endSize = -1;
QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.QCOW2);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
try {
qemu.create(file);
qemu.resize(file, endSize);
@ -199,7 +199,7 @@ public class QemuImgTest {
long startSize = 20480;
QemuImgFile file = new QemuImgFile(filename, 20480, PhysicalDiskFormat.QCOW2);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
qemu.resize(file, 0);
@ -216,7 +216,7 @@ public class QemuImgTest {
QemuImgFile firstFile = new QemuImgFile(firstFileName, 20480, PhysicalDiskFormat.QCOW2);
QemuImgFile secondFile = new QemuImgFile(secondFileName, PhysicalDiskFormat.QCOW2);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(firstFile);
qemu.create(secondFile, firstFile);
@ -240,7 +240,7 @@ public class QemuImgTest {
QemuImgFile srcFile = new QemuImgFile(srcFileName, srcSize);
QemuImgFile destFile = new QemuImgFile(destFileName);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(srcFile);
qemu.convert(srcFile, destFile);
Map<String, String> info = qemu.info(destFile);
@ -267,7 +267,7 @@ public class QemuImgTest {
QemuImgFile srcFile = new QemuImgFile(srcFileName, srcSize, srcFormat);
QemuImgFile destFile = new QemuImgFile(destFileName, destFormat);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(srcFile);
qemu.convert(srcFile, destFile);

View File

@ -0,0 +1,29 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-network-vxlan</artifactId>
<name>Apache CloudStack Plugin - Network VXLAN</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.3.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -0,0 +1,179 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.guru;
import javax.ejb.Local;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
import com.cloud.network.Network;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.State;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.dao.NetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
@Component
@Local(value=NetworkGuru.class)
public class VxlanGuestNetworkGuru extends GuestNetworkGuru {
private static final Logger s_logger = Logger.getLogger(VxlanGuestNetworkGuru.class);
public VxlanGuestNetworkGuru() {
super();
_isolationMethods = new IsolationMethod[] { IsolationMethod.VXLAN };
}
@Override
protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
// This guru handles only Guest Isolated network that supports Source nat service
if (networkType == NetworkType.Advanced
&& isMyTrafficType(offering.getTrafficType())
&& offering.getGuestType() == Network.GuestType.Isolated
&& isMyIsolationMethod(physicalNetwork)) {
return true;
} else {
s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
return false;
}
}
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
NetworkVO network = (NetworkVO) super.design(offering, plan, userSpecified, owner);
if (network == null) {
return null;
}
network.setBroadcastDomainType(BroadcastDomainType.Vxlan);
return network;
}
protected void allocateVnet(Network network, NetworkVO implemented, long dcId,
long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException {
if (network.getBroadcastUri() == null) {
String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId,
UseSystemGuestVlans.valueIn(network.getAccountId()));
if (vnet == null) {
throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " +
"part of network " + network + " implement ", DataCenter.class, dcId);
}
implemented.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(vnet));
allocateVnetComplete(network, implemented, dcId, physicalNetworkId, reservationId, vnet);
} else {
implemented.setBroadcastUri(network.getBroadcastUri());
}
}
// For Test: Mockit cannot mock static method, wrap it
protected void allocateVnetComplete(Network network, NetworkVO implemented, long dcId,
long physicalNetworkId, String reservationId, String vnet) {
//TODO(VXLAN): Add new event type for vxlan?
ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(),
EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone vNet: " + vnet + " Network Id: " + network.getId(), 0);
}
@Override
public Network implement(Network network, NetworkOffering offering,
DeployDestination dest, ReservationContext context)
throws InsufficientVirtualNetworkCapcityException {
assert (network.getState() == State.Implementing) : "Why are we implementing " + network;
long dcId = dest.getDataCenter().getId();
//get physical network id
Long physicalNetworkId = network.getPhysicalNetworkId();
// physical network id can be null in Guest Network in Basic zone, so locate the physical network
if (physicalNetworkId == null) {
physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
}
NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
network.getDataCenterId(), physicalNetworkId);
allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId());
if (network.getGateway() != null) {
implemented.setGateway(network.getGateway());
}
if (network.getCidr() != null) {
implemented.setCidr(network.getCidr());
}
return implemented;
}
@Override
public void reserve(NicProfile nic, Network network,
VirtualMachineProfile vm,
DeployDestination dest, ReservationContext context)
throws InsufficientVirtualNetworkCapcityException,
InsufficientAddressCapacityException {
super.reserve(nic, network, vm, dest, context);
}
@Override
public boolean release(NicProfile nic,
VirtualMachineProfile vm,
String reservationId) {
return super.release(nic, vm, reservationId);
}
@Override
public void shutdown(NetworkProfile profile, NetworkOffering offering) {
NetworkVO networkObject = _networkDao.findById(profile.getId());
if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vxlan ||
networkObject.getBroadcastUri() == null) {
s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
return;
}
super.shutdown(profile, offering);
}
@Override
public boolean trash(Network network, NetworkOffering offering) {
return super.trash(network, offering);
}
}

View File

@ -0,0 +1,274 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.guru;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Command;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.domain.Domain;
import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.Service;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.server.ConfigurationServer;
import com.cloud.user.Account;
import com.cloud.vm.ReservationContext;
import java.util.Arrays;
public class VxlanGuestNetworkGuruTest {
PhysicalNetworkDao physnetdao = mock (PhysicalNetworkDao.class);
DataCenterDao dcdao = mock(DataCenterDao.class);
AgentManager agentmgr = mock (AgentManager.class);
NetworkOrchestrationService netmgr = mock (NetworkOrchestrationService.class);
NetworkModel netmodel = mock (NetworkModel.class);
ConfigurationServer confsvr = mock(ConfigurationServer.class);
NetworkDao netdao = mock(NetworkDao.class);
VxlanGuestNetworkGuru guru;
@Before
public void setUp() {
guru = spy( new VxlanGuestNetworkGuru() );
((GuestNetworkGuru) guru)._physicalNetworkDao = physnetdao;
guru._physicalNetworkDao = physnetdao;
guru._dcDao = dcdao;
guru._networkModel = netmodel;
guru._networkDao = netdao;
((GuestNetworkGuru) guru)._configServer = confsvr;
DataCenterVO dc = mock(DataCenterVO.class);
when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24");
when(dcdao.findById(anyLong())).thenReturn((DataCenterVO) dc);
}
@Test
public void testCanHandle() {
NetworkOffering offering = mock(NetworkOffering.class);
when(offering.getId()).thenReturn(42L);
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
when(physnet.getId()).thenReturn(42L);
assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
// Not supported TrafficType != Guest
when(offering.getTrafficType()).thenReturn(TrafficType.Management);
assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
// Not supported: GuestType Shared
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
when(offering.getGuestType()).thenReturn(GuestType.Shared);
assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
// Not supported: Basic networking
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
assertFalse(guru.canHandle(offering, NetworkType.Basic, physnet) == true);
// Not supported: IsolationMethod != VXLAN
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VLAN" }));
assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
}
@Test
public void testDesign() {
PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
when(physnetdao.findById(anyLong())).thenReturn(physnet);
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
when(physnet.getId()).thenReturn(42L);
NetworkOffering offering = mock(NetworkOffering.class);
when(offering.getId()).thenReturn(42L);
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
DeploymentPlan plan = mock(DeploymentPlan.class);
Network network = mock(Network.class);
Account account = mock(Account.class);
Network designednetwork = guru.design(offering, plan, network, account);
assertTrue(designednetwork != null);
assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Vxlan);
}
@Test
public void testImplement() throws InsufficientVirtualNetworkCapcityException {
PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
when(physnetdao.findById(anyLong())).thenReturn(physnet);
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
when(physnet.getId()).thenReturn(42L);
NetworkOffering offering = mock(NetworkOffering.class);
when(offering.getId()).thenReturn(42L);
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
NetworkVO network = mock(NetworkVO.class);
when(network.getName()).thenReturn("testnetwork");
when(network.getState()).thenReturn(State.Implementing);
when(network.getPhysicalNetworkId()).thenReturn(42L);
DeployDestination dest = mock(DeployDestination.class);
DataCenter dc = mock(DataCenter.class);
when(dest.getDataCenter()).thenReturn(dc);
when(netmodel.findPhysicalNetworkId(anyLong(), (String) any(), (TrafficType) any())).thenReturn(42L);
//TODO(VXLAN): doesn't support VNI specified
//when(confsvr.getConfigValue((String) any(), (String) any(), anyLong())).thenReturn("true");
when(dcdao.allocateVnet(anyLong(), anyLong(), anyLong(), (String) any(), eq(true))).thenReturn("42");
doNothing().when(guru).allocateVnetComplete((Network) any(), (NetworkVO) any(), anyLong(), anyLong(), (String) any(), eq("42"));
Domain dom = mock(Domain.class);
when(dom.getName()).thenReturn("domain");
Account acc = mock(Account.class);
when(acc.getAccountName()).thenReturn("accountname");
ReservationContext res = mock(ReservationContext.class);
when(res.getDomain()).thenReturn(dom);
when(res.getAccount()).thenReturn(acc);
Network implementednetwork = guru.implement(network, offering, dest, res);
assertTrue(implementednetwork != null);
}
@Test
public void testImplementWithCidr() throws InsufficientVirtualNetworkCapcityException {
PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
when(physnetdao.findById(anyLong())).thenReturn(physnet);
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
when(physnet.getId()).thenReturn(42L);
NetworkOffering offering = mock(NetworkOffering.class);
when(offering.getId()).thenReturn(42L);
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
NetworkVO network = mock(NetworkVO.class);
when(network.getName()).thenReturn("testnetwork");
when(network.getState()).thenReturn(State.Implementing);
when(network.getGateway()).thenReturn("10.1.1.1");
when(network.getCidr()).thenReturn("10.1.1.0/24");
when(network.getPhysicalNetworkId()).thenReturn(42L);
DeployDestination dest = mock(DeployDestination.class);
DataCenter dc = mock(DataCenter.class);
when(dest.getDataCenter()).thenReturn(dc);
when(netmodel.findPhysicalNetworkId(anyLong(), (String) any(), (TrafficType) any())).thenReturn(42L);
//TODO(VXLAN): doesn't support VNI specified
//when(confsvr.getConfigValue((String) any(), (String) any(), anyLong())).thenReturn("true");
when(dcdao.allocateVnet(anyLong(), anyLong(), anyLong(), (String) any(), eq(true))).thenReturn("42");
doNothing().when(guru).allocateVnetComplete((Network) any(), (NetworkVO) any(), anyLong(), anyLong(), (String) any(), eq("42"));
Domain dom = mock(Domain.class);
when(dom.getName()).thenReturn("domain");
Account acc = mock(Account.class);
when(acc.getAccountName()).thenReturn("accountname");
ReservationContext res = mock(ReservationContext.class);
when(res.getDomain()).thenReturn(dom);
when(res.getAccount()).thenReturn(acc);
Network implementednetwork = guru.implement(network, offering, dest, res);
assertTrue(implementednetwork != null);
assertTrue(implementednetwork.getCidr().equals("10.1.1.0/24"));
assertTrue(implementednetwork.getGateway().equals("10.1.1.1"));
}
@Test
public void testShutdown() throws InsufficientVirtualNetworkCapcityException, URISyntaxException {
PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
when(physnetdao.findById(anyLong())).thenReturn(physnet);
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
when(physnet.getId()).thenReturn(42L);
NetworkOffering offering = mock(NetworkOffering.class);
when(offering.getId()).thenReturn(42L);
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
NetworkVO network = mock(NetworkVO.class);
when(network.getName()).thenReturn("testnetwork");
when(network.getState()).thenReturn(State.Implementing);
when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vxlan);
when(network.getBroadcastUri()).thenReturn(new URI("vxlan:12345"));
when(network.getPhysicalNetworkId()).thenReturn(42L);
when(netdao.findById(42L)).thenReturn(network);
DeployDestination dest = mock(DeployDestination.class);
DataCenter dc = mock(DataCenter.class);
when(dest.getDataCenter()).thenReturn(dc);
when(netmodel.findPhysicalNetworkId(anyLong(), (String) any(), (TrafficType) any())).thenReturn(42L);
Domain dom = mock(Domain.class);
when(dom.getName()).thenReturn("domain");
Account acc = mock(Account.class);
when(acc.getAccountName()).thenReturn("accountname");
ReservationContext res = mock(ReservationContext.class);
when(res.getDomain()).thenReturn(dom);
when(res.getAccount()).thenReturn(acc);
NetworkProfile implementednetwork = mock(NetworkProfile.class);
when(implementednetwork.getId()).thenReturn(42L);
when(implementednetwork.getBroadcastUri()).thenReturn(new URI("vxlan:12345"));
when(offering.getSpecifyVlan()).thenReturn(false);
guru.shutdown(implementednetwork, offering);
verify(implementednetwork, times(1)).setBroadcastUri(null);
}
}

View File

@ -62,6 +62,7 @@
<module>alert-handlers/snmp-alerts</module>
<module>alert-handlers/syslog-alerts</module>
<module>network-elements/internal-loadbalancer</module>
<module>network-elements/vxlan</module>
</modules>
<dependencies>

View File

@ -25,9 +25,12 @@ import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.configuration.Config;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.dao.HostDao;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ResizeVolumePayload;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
import com.cloud.storage.dao.DiskOfferingDao;
@ -35,20 +38,28 @@ import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.template.TemplateManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.engine.subsystem.api.storage.*;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.command.CreateObjectCommand;
import org.apache.cloudstack.storage.command.DeleteCommand;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.cloudstack.storage.volume.VolumeObject;
import org.apache.log4j.Logger;
import javax.inject.Inject;
import java.util.UUID;
public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreDriverImpl.class);
@ -74,7 +85,12 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
SnapshotManager snapshotMgr;
@Inject
EndPointSelector epSelector;
@Inject
ConfigurationDao configDao;
@Inject
TemplateManager templateManager;
@Inject
TemplateDataFactory templateDataFactory;
@Override
public DataTO getTO(DataObject data) {
return null;
@ -165,10 +181,49 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
@Override
public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
DataStore store = destData.getDataStore();
if (store.getRole() == DataStoreRole.Primary) {
if ((srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.TEMPLATE)) {
//For CLVM, we need to copy template to primary storage at all, just fake the copy result.
TemplateObjectTO templateObjectTO = new TemplateObjectTO();
templateObjectTO.setPath(UUID.randomUUID().toString());
templateObjectTO.setSize(srcdata.getSize());
templateObjectTO.setPhysicalSize(srcdata.getSize());
templateObjectTO.setFormat(Storage.ImageFormat.RAW);
CopyCmdAnswer answer = new CopyCmdAnswer(templateObjectTO);
CopyCommandResult result = new CopyCommandResult("", answer);
callback.complete(result);
} else if (srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) {
//For CLVM, we need to pass template on secondary storage to hypervisor
String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
int _primaryStorageDownloadWait = NumbersUtil.parseInt(value,
Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
DataStore imageStore = templateManager.getImageStore(storagePoolVO.getDataCenterId(), srcdata.getId());
DataObject srcData = templateDataFactory.getTemplate(srcdata.getId(), imageStore);
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait, true);
EndPoint ep = epSelector.select(srcData, destData);
Answer answer = ep.sendMessage(cmd);
CopyCommandResult result = new CopyCommandResult("", answer);
callback.complete(result);
}
}
}
@Override
public boolean canCopy(DataObject srcData, DataObject destData) {
//BUG fix for CLOUDSTACK-4618
DataStore store = destData.getDataStore();
if (store.getRole() == DataStoreRole.Primary) {
if ((srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.TEMPLATE) ||
(srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME)) {
StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
if (storagePoolVO != null && storagePoolVO.getPoolType() == Storage.StoragePoolType.CLVM) {
return true;
}
}
}
return false;
}

View File

@ -81,7 +81,7 @@
<cs.reflections.version>0.9.8</cs.reflections.version>
<cs.java-ipv6.version>0.10</cs.java-ipv6.version>
<cs.replace.properties>build/replace.properties</cs.replace.properties>
<cs.libvirt-java.version>0.5.0</cs.libvirt-java.version>
<cs.libvirt-java.version>0.5.1</cs.libvirt-java.version>
<cs.rados-java.version>0.1.3</cs.rados-java.version>
<cs.target.dir>target</cs.target.dir>
<cs.daemon.version>1.0.10</cs.daemon.version>

View File

@ -388,7 +388,8 @@ class nfsConfig(serviceCfgBase):
return True
cfo = configFileOps("/etc/nfsmount.conf")
cfo.addEntry("AC", "False")
cfo.addEntry("Ac", "False")
cfo.addEntry("actimeo", "0")
cfo.save()
self.syscfg.svo.enableService("rpcbind")

View File

@ -42,11 +42,11 @@ fi
is_lv() {
# Must be a block device
if [ -b "${1}" ]; then
if [ -b "${1}" -o -L "{1}" ]; then
# But not a volume group or physical volume
lvm vgs "${1}" > /dev/null 2>&1 && return 1
# And a logical volume
lvm lvs "${1}" > /dev/null 2>&1 && return 0
lvm lvs "${1}" > /dev/null 2>&1 && return 1
fi
return 0
}

View File

@ -372,8 +372,16 @@ def unmountSnapshotsDir(session, args):
return "1"
def getPrimarySRPath(primaryStorageSRUuid, isISCSI):
if isISCSI:
def getPrimarySRPath(session, primaryStorageSRUuid, isISCSI):
sr = session.xenapi.SR.get_by_uuid(primaryStorageSRUuid)
srrec = session.xenapi.SR.get_record(sr)
srtype = srrec["type"]
if srtype == "file":
pbd = session.xenapi.SR.get_PBDs(sr)[0]
pbdrec = session.xenapi.PBD.get_record(pbd)
primarySRPath = pbdrec["device_config"]["location"]
return primarySRPath
elif isISCSI:
primarySRDir = lvhdutil.VG_PREFIX + primaryStorageSRUuid
return os.path.join(lvhdutil.VG_LOCATION, primarySRDir)
else:
@ -472,7 +480,7 @@ def getVhdParent(session, args):
snapshotUuid = args['snapshotUuid']
isISCSI = getIsTrueString(args['isISCSI'])
primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
primarySRPath = getPrimarySRPath(session, primaryStorageSRUuid, isISCSI)
util.SMlog("primarySRPath: " + primarySRPath)
baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI)
@ -490,7 +498,7 @@ def backupSnapshot(session, args):
isISCSI = getIsTrueString(args['isISCSI'])
path = args['path']
localMountPoint = args['localMountPoint']
primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
primarySRPath = getPrimarySRPath(session, primaryStorageSRUuid, isISCSI)
util.SMlog("primarySRPath: " + primarySRPath)
baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI)

View File

@ -0,0 +1,230 @@
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# modifyvnet.sh -- adds and deletes VXLANs from a Routing Server
# set -x
## TODO(VXLAN): MTU, IPv6 underlying
usage() {
printf "Usage: %s: -o <op>(add | delete) -v <vxlan id> -p <pif> -b <bridge name>\n"
}
addVxlan() {
local vxlanId=$1
local pif=$2
local vxlanDev=vxlan$vxlanId
local vxlanBr=$3
local mcastGrp="239.$(( $vxlanId >> 16 % 256 )).$(( $vxlanId >> 8 % 256 )).$(( $vxlanId % 256 ))"
## TODO(VXLAN): $brif (trafficlabel) should be passed from caller because we cannot assume 1:1 mapping between pif and brif.
# lookup bridge interface
local sysfs_dir=/sys/devices/virtual/net/
local brif=`find ${sysfs_dir}*/brif/ -name $pif | sed -e "s,$sysfs_dir,," | sed -e 's,/brif/.*$,,'`
if [ "$brif " == " " ]
then
printf "Failed to lookup bridge interface which includes pif: $pif."
return 1
fi
# confirm ip address of $brif
ip addr show $brif | grep -w inet
if [ $? -gt 0 ]
then
printf "Failed to find vxlan multicast source ip address on brif: $brif."
return 1
fi
# mcast route
## TODO(VXLAN): Can we assume there're only one IP address which can be multicast src IP on the IF?
ip route get $mcastGrp | grep -w "dev $brif"
if [ $? -gt 0 ]
then
ip route add $mcastGrp/32 dev $brif
if [ $? -gt 0 ]
then
printf "Failed to add vxlan multicast route on brif: $brif."
return 1
fi
fi
if [ ! -d /sys/class/net/$vxlanDev ]
then
ip link add $vxlanDev type vxlan id $vxlanId group $mcastGrp ttl 10 dev $brif
if [ $? -gt 0 ]
then
# race condition that someone already creates the vxlan
if [ ! -d /sys/class/net/$vxlanDev ]
then
printf "Failed to create vxlan $vxlanId on brif: $brif."
return 1
fi
fi
fi
# is up?
ip link show $vxlanDev | grep -w UP > /dev/null
if [ $? -gt 0 ]
then
ip link set $vxlanDev up > /dev/null
fi
if [ ! -d /sys/class/net/$vxlanBr ]
then
brctl addbr $vxlanBr > /dev/null
if [ $? -gt 0 ]
then
if [ ! -d /sys/class/net/$vxlanBr ]
then
printf "Failed to create br: $vxlanBr"
return 2
fi
fi
brctl setfd $vxlanBr 0
fi
#pif is eslaved into vxlanBr?
ls /sys/class/net/$vxlanBr/brif/ | grep -w "$vxlanDev" > /dev/null
if [ $? -gt 0 ]
then
brctl addif $vxlanBr $vxlanDev > /dev/null
if [ $? -gt 0 ]
then
ls /sys/class/net/$vxlanBr/brif/ | grep -w "$vxlanDev" > /dev/null
if [ $? -gt 0 ]
then
printf "Failed to add vxlan: $vxlanDev to $vxlanBr"
return 3
fi
fi
fi
# is vxlanBr up?
ip link show $vxlanBr | grep -w UP > /dev/null
if [ $? -gt 0 ]
then
ip link set $vxlanBr up
fi
return 0
}
deleteVxlan() {
local vxlanId=$1
local pif=$2
local vxlanDev=vxlan$vxlanId
local vxlanBr=$3
local mcastGrp="239.$(( $vxlanId >> 16 % 256 )).$(( $vxlanId >> 8 % 256 )).$(( $vxlanId % 256 ))"
ip route del $mcastGrp/32 dev $brif
ip link delete $vxlanDev
if [ $? -gt 0 ]
then
printf "Failed to del vxlan: $vxlanId"
printf "Continue..."
fi
ip link set $vxlanBr down
if [ $? -gt 0 ]
then
return 1
fi
brctl delbr $vxlanBr
if [ $? -gt 0 ]
then
printf "Failed to del bridge $vxlanBr"
return 1
fi
return 0
}
op=
vxlanId=
option=$@
while getopts 'o:v:p:b:' OPTION
do
case $OPTION in
o) oflag=1
op="$OPTARG"
;;
v) vflag=1
vxlanId="$OPTARG"
;;
p) pflag=1
pif="$OPTARG"
;;
b) bflag=1
brName="$OPTARG"
;;
?) usage
exit 2
;;
esac
done
# Check that all arguments were passed in
if [ "$oflag$vflag$pflag$bflag" != "1111" ]
then
usage
exit 2
fi
# Do we support Vxlan?
lsmod|grep ^vxlan >& /dev/null
if [ $? -gt 0 ]
then
modprobe=`modprobe vxlan 2>&1`
if [ $? -gt 0 ]
then
printf "Failed to load vxlan kernel module: $modprobe"
exit 1
fi
fi
if [ "$op" == "add" ]
then
# Add the vxlan
addVxlan $vxlanId $pif $brName
# If the add fails then return failure
if [ $? -gt 0 ]
then
exit 1
fi
else
if [ "$op" == "delete" ]
then
# Delete the vxlan
deleteVxlan $vxlanId $pif $brName
# Always exit with success
exit 0
fi
fi

View File

@ -3770,7 +3770,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
validateLoadBalancerServiceCapabilities(lbServiceCapabilityMap);
if (!serviceProviderMap.containsKey(Service.Lb) && lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
if (lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
maxconn = cmd.getMaxconnections();
if (maxconn == null) {
maxconn=Integer.parseInt(_configDao.getValue(Config.NetworkLBHaproxyMaxConn.key()));
@ -3924,42 +3924,27 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
void validateStaticNatServiceCapablities(Map<Capability, String> staticNatServiceCapabilityMap) {
if (staticNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) {
if (staticNatServiceCapabilityMap.keySet().size() > 2) {
throw new InvalidParameterValueException("Only " + Capability.ElasticIp.getName() + " and "
+ Capability.AssociatePublicIP.getName()
+ " capabilitiy can be sepcified for static nat service");
}
boolean eipEnabled = false;
boolean eipDisabled = false;
boolean associatePublicIP = true;
for (Capability capability : staticNatServiceCapabilityMap.keySet()) {
String value = staticNatServiceCapabilityMap.get(capability);
String value = staticNatServiceCapabilityMap.get(capability).toLowerCase();
if (! (value.contains("true") ^ value.contains("false"))) {
throw new InvalidParameterValueException("Unknown specified value (" + value + ") for "
+ capability);
}
if (capability == Capability.ElasticIp) {
eipEnabled = value.contains("true");
eipDisabled = value.contains("false");
if (!eipEnabled && !eipDisabled) {
throw new InvalidParameterValueException("Unknown specified value for "
+ Capability.ElasticIp.getName());
}
} else if (capability == Capability.AssociatePublicIP) {
if (value.contains("true")) {
associatePublicIP = true;
} else if (value.contains("false")) {
associatePublicIP = false;
} else {
throw new InvalidParameterValueException("Unknown specified value for "
+ Capability.AssociatePublicIP.getName());
}
associatePublicIP = value.contains("true");
} else {
throw new InvalidParameterValueException("Only " + Capability.ElasticIp.getName() + " and "
+ Capability.AssociatePublicIP.getName()
+ " capabilitiy can be sepcified for static nat service");
}
if (eipDisabled && associatePublicIP) {
throw new InvalidParameterValueException("Capability " + Capability.AssociatePublicIP.getName()
+ " can only be set when capability " + Capability.ElasticIp.getName() + " is true");
}
}
if ((! eipEnabled) && associatePublicIP) {
throw new InvalidParameterValueException("Capability " + Capability.AssociatePublicIP.getName()
+ " can only be set when capability " + Capability.ElasticIp.getName() + " is true");
}
}
}

View File

@ -190,6 +190,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
private static final long MAX_VLAN_ID = 4095L; // 2^12 - 1
private static final long MIN_GRE_KEY = 0L;
private static final long MAX_GRE_KEY = 4294967295L; // 2^32 -1
private static final long MIN_VXLAN_VNI = 0L;
private static final long MAX_VXLAN_VNI = 16777215L; // 2^24 -1
@Inject
DataCenterDao _dcDao = null;
@ -2648,6 +2650,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (network.getIsolationMethods().contains("GRE")) {
minVnet = MIN_GRE_KEY;
maxVnet = MAX_GRE_KEY;
} else if (network.getIsolationMethods().contains("VXLAN")) {
minVnet = MIN_VXLAN_VNI;
maxVnet = MAX_VXLAN_VNI;
}
String rangeMessage = " between " + minVnet + " and " + maxVnet;
if (VnetRange.length == 1 && VnetRange[0].equals("")) {

View File

@ -1042,6 +1042,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error);
for (SnapshotVO snapshotVO : snapshots) {
try {
List<SnapshotDataStoreVO> storeRefs = _snapshotStoreDao.findBySnapshotId(snapshotVO.getId());
for(SnapshotDataStoreVO ref : storeRefs) {
_snapshotStoreDao.expunge(ref.getId());
}
_snapshotDao.expunge(snapshotVO.getId());
} catch (Exception e) {
s_logger.warn("Unable to destroy " + snapshotVO.getId(), e);

View File

@ -757,7 +757,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
}
if (diskOffering.getTags() != null) {
if (!newDiskOffering.getTags().equals(diskOffering.getTags())) {
if (newDiskOffering.getTags() == null || !newDiskOffering.getTags().equals(diskOffering.getTags())) {
throw new InvalidParameterValueException("Tags on new and old disk offerings must match");
}
} else if (newDiskOffering.getTags() != null) {

View File

@ -140,8 +140,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
@Inject
protected VMTemplateDao _templateDao;
@Inject
protected HostDao _hostDao;
@Inject
protected UserVmDao _vmDao;
@Inject
protected VolumeDao _volsDao;
@ -158,8 +156,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
@Inject
protected PrimaryDataStoreDao _storagePoolDao;
@Inject
protected EventDao _eventDao;
@Inject
protected SnapshotPolicyDao _snapshotPolicyDao = null;
@Inject
protected SnapshotScheduleDao _snapshotScheduleDao;
@ -463,7 +459,9 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
while (snaps.size() > maxSnaps && snaps.size() > 1) {
SnapshotVO oldestSnapshot = snaps.get(0);
long oldSnapId = oldestSnapshot.getId();
s_logger.debug("Max snaps: " + policy.getMaxSnaps() + " exceeded for snapshot policy with Id: " + policyId + ". Deleting oldest snapshot: " + oldSnapId);
if (policy != null) {
s_logger.debug("Max snaps: " + policy.getMaxSnaps() + " exceeded for snapshot policy with Id: " + policyId + ". Deleting oldest snapshot: " + oldSnapId);
}
if(deleteSnapshot(oldSnapId)){
//log Snapshot delete event
ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, oldestSnapshot.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_SNAPSHOT_DELETE, "Successfully deleted oldest snapshot: " + oldSnapId, 0);
@ -1001,6 +999,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
return true;
}
@Override
@DB
public SnapshotInfo takeSnapshot(VolumeInfo volume) throws ResourceAllocationException {
CreateSnapshotPayload payload = (CreateSnapshotPayload)volume.getpayload();
Long snapshotId = payload.getSnapshotId();
@ -1019,15 +1018,17 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
if (!processed) {
throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId);
}
postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId());
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(),
snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null,
volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
_resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
try {
postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId());
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(),
snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null,
volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
_resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
} catch (Exception e) {
s_logger.debug("post process snapshot failed", e);
}
} catch(Exception e) {
s_logger.debug("Failed to create snapshot", e);
if (backup) {

View File

@ -770,29 +770,42 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
}
@Override
@DB
public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
StoragePool pool = (StoragePool) _dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Evicting " + templatePoolVO);
//Need to hold the lock, otherwise, another thread may create a volume from the template at the same time.
//Assumption here is that, we will hold the same lock during create volume from template
VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolVO.getId());
if (templatePoolRef == null) {
s_logger.debug("can't aquire the lock for template pool ref:" + templatePoolVO.getId());
return;
}
DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
try {
Answer answer = _storageMgr.sendToPool(pool, cmd);
StoragePool pool = (StoragePool) this._dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
if (answer != null && answer.getResult()) {
// Remove the templatePoolVO
if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName());
}
} else {
s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Evicting " + templatePoolVO);
}
} catch (StorageUnavailableException e) {
s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: "
+ pool.getName());
DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
try {
Answer answer = _storageMgr.sendToPool(pool, cmd);
if (answer != null && answer.getResult()) {
// Remove the templatePoolVO
if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName());
}
} else {
s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName());
}
} catch (StorageUnavailableException e) {
s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: "
+ pool.getName());
}
} finally {
_tmpltPoolDao.releaseFromLockTable(templatePoolRef.getId());
}
}
@ -1376,16 +1389,23 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
//getting the prent volume
long parentVolumeId=_snapshotDao.findById(snapshotId).getVolumeId();
VolumeVO parentVolume = _volumeDao.findById(parentVolumeId);
if (parentVolume.getIsoId() != null) {
if (parentVolume != null && parentVolume.getIsoId() != null && parentVolume.getIsoId() != 0) {
privateTemplate.setSourceTemplateId(parentVolume.getIsoId());
_tmpltDao.update(privateTemplate.getId(), privateTemplate);
} else if (parentVolume != null && parentVolume.getTemplateId() != null) {
privateTemplate.setSourceTemplateId(parentVolume.getTemplateId());
_tmpltDao.update(privateTemplate.getId(), privateTemplate);
}
}
else if (volumeId != null) {
VolumeVO parentVolume = _volumeDao.findById(volumeId);
if (parentVolume.getIsoId() != null) {
if (parentVolume.getIsoId() != null && parentVolume.getIsoId() != 0) {
privateTemplate.setSourceTemplateId(parentVolume.getIsoId());
_tmpltDao.update(privateTemplate.getId(), privateTemplate);
} else if (parentVolume.getTemplateId() != null) {
privateTemplate.setSourceTemplateId(parentVolume.getTemplateId());
_tmpltDao.update(privateTemplate.getId(), privateTemplate);
}
}
TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);

View File

@ -857,7 +857,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
@DB
@ActionEvents({
@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User"),
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
})
public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType,
Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID) {

View File

@ -27,7 +27,9 @@ import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import junit.framework.Assert;
@ -53,7 +55,9 @@ import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Network.Capability;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
@ -415,6 +419,70 @@ public class ConfigurationManagerTest {
}
}
@Test
public void validateEmptyStaticNatServiceCapablitiesTest() {
Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<Capability, String>();
configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
}
@Test
public void validateInvalidStaticNatServiceCapablitiesTest() {
Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<Capability, String>();
staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "Frue and Talse");
boolean caught = false;
try {
configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
}
catch (InvalidParameterValueException e) {
Assert.assertTrue(e.getMessage(),e.getMessage().contains("(frue and talse)"));
caught = true;
}
Assert.assertTrue("should not be accepted",caught);
}
@Test
public void validateTTStaticNatServiceCapablitiesTest() {
Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<Capability, String>();
staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "true and Talse");
staticNatServiceCapabilityMap.put(Capability.ElasticIp, "True");
configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
}
@Test
public void validateFTStaticNatServiceCapablitiesTest() {
Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<Capability, String>();
staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "false");
staticNatServiceCapabilityMap.put(Capability.ElasticIp, "True");
configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
}
@Test
public void validateTFStaticNatServiceCapablitiesTest() {
Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<Capability, String>();
staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "true and Talse");
staticNatServiceCapabilityMap.put(Capability.ElasticIp, "false");
boolean caught = false;
try {
configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
}
catch (InvalidParameterValueException e) {
Assert.assertTrue(e.getMessage(),e.getMessage().contains("Capability " + Capability.AssociatePublicIP.getName()
+ " can only be set when capability " + Capability.ElasticIp.getName() + " is true"));
caught = true;
}
Assert.assertTrue("should not be accepted",caught);
}
@Test
public void validateFFStaticNatServiceCapablitiesTest() {
Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<Capability, String>();
staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "false");
staticNatServiceCapabilityMap.put(Capability.ElasticIp, "False");
configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
}
public class DedicatePublicIpRangeCmdExtn extends DedicatePublicIpRangeCmd {
@Override

View File

@ -2371,3 +2371,7 @@ CREATE VIEW `cloud`.`data_center_view` AS
`cloud`.`dedicated_resources` ON data_center.id = dedicated_resources.data_center_id
left join
`cloud`.`affinity_group` ON dedicated_resources.affinity_group_id = affinity_group.id;
UPDATE `cloud`.`ntwk_offering_service_map` SET Provider='VpcVirtualRouter' WHERE network_offering_id IN (SELECT id from `cloud`.`network_offerings` WHERE name IN ('DefaultIsolatedNetworkOfferingForVpcNetworks', 'DefaultIsolatedNetworkOfferingForVpcNetworksNoLB'));

View File

@ -17,6 +17,7 @@
import deployDataCenter
import TestCaseExecuteEngine
import sys
from argparse import ArgumentParser
if __name__ == "__main__":
@ -37,6 +38,8 @@ if __name__ == "__main__":
parser.add_argument("-l", "--load", dest="load", action="store_true",
help="only load config, do not deploy,\
it will only run testcase")
parser.add_argument("-n", "--num", dest="number",
help="how many times you want run the test case")
options = parser.parse_args()
@ -52,23 +55,38 @@ if __name__ == "__main__":
deploy.loadCfg()
else:
deploy.deploy()
iterates = 1
if options.number is not None:
if options.number == "loop":
iterates = sys.maxint
else:
try:
iterates = int(options.number)
except:
iterates = 1
if options.testCaseFolder is None:
if options.module is None:
parser.print_usage()
exit(1)
else:
engine = \
TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient,
n = 0
while(n < iterates):
engine = \
TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient,
deploy.getCfg(),
testCaseLogFile,
testResultLogFile)
engine.loadTestsFromFile(options.module)
engine.run()
engine.loadTestsFromFile(options.module)
engine.run()
n = n + 1
else:
engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient,
n = 0
while(n<iterates):
engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient,
deploy.getCfg(),
testCaseLogFile,
testResultLogFile)
engine.loadTestsFromDir(options.testCaseFolder)
engine.run()
engine.loadTestsFromDir(options.testCaseFolder)
engine.run()
n = n + 1

View File

@ -332,6 +332,7 @@ dictionary = {
'label.add.to.group': '<fmt:message key="label.add.to.group" />',
'label.add.user': '<fmt:message key="label.add.user" />',
'label.add.vlan': '<fmt:message key="label.add.vlan" />',
'label.add.vxlan': '<fmt:message key="label.add.vxlan" />',
'label.add.vm': '<fmt:message key="label.add.vm" />',
'label.add.vms': '<fmt:message key="label.add.vms" />',
'label.add.vms.to.lb': '<fmt:message key="label.add.vms.to.lb" />',
@ -549,6 +550,7 @@ dictionary = {
'label.end.port': '<fmt:message key="label.end.port" />',
'label.end.reserved.system.IP': '<fmt:message key="label.end.reserved.system.IP" />',
'label.end.vlan': '<fmt:message key="label.end.vlan" />',
'label.end.vxlan': '<fmt:message key="label.end.vxlan" />',
'label.enter.token': '<fmt:message key="label.enter.token" />',
'label.error.code': '<fmt:message key="label.error.code" />',
'label.error': '<fmt:message key="label.error" />',
@ -904,6 +906,10 @@ dictionary = {
'label.Pxe.server.type': '<fmt:message key="label.Pxe.server.type" />',
'label.quickview': '<fmt:message key="label.quickview" />',
'label.rbd': '<fmt:message key="label.rbd" />',
'label.rbd.monitor': '<fmt:message key="label.rbd.monitor" />',
'label.rbd.pool': '<fmt:message key="label.rbd.pool" />',
'label.rbd.id': '<fmt:message key="label.rbd.id" />',
'label.rbd.secret': '<fmt:message key="label.rbd.secret" />',
'label.reboot': '<fmt:message key="label.reboot" />',
'label.recent.errors': '<fmt:message key="label.recent.errors" />',
'label.redundant.router.capability': '<fmt:message key="label.redundant.router.capability" />',
@ -1011,12 +1017,14 @@ dictionary = {
'label.source.nat': '<fmt:message key="label.source.nat" />',
'label.specify.IP.ranges': '<fmt:message key="label.specify.IP.ranges" />',
'label.specify.vlan': '<fmt:message key="label.specify.vlan" />',
'label.specify.vxlan': '<fmt:message key="label.specify.vxlan" />',
'label.SR.name ': '<fmt:message key="label.SR.name " />',
'label.srx': '<fmt:message key="label.srx" />',
'label.start.IP': '<fmt:message key="label.start.IP" />',
'label.start.port': '<fmt:message key="label.start.port" />',
'label.start.reserved.system.IP': '<fmt:message key="label.start.reserved.system.IP" />',
'label.start.vlan': '<fmt:message key="label.start.vlan" />',
'label.start.vxlan': '<fmt:message key="label.start.vxlan" />',
'label.state': '<fmt:message key="label.state" />',
'label.static.nat': '<fmt:message key="label.static.nat" />',
'label.static.nat.to': '<fmt:message key="label.static.nat.to" />',
@ -1135,6 +1143,9 @@ dictionary = {
'label.vlan': '<fmt:message key="label.vlan" />',
'label.vlan.id': '<fmt:message key="label.vlan.id" />',
'label.vlan.range': '<fmt:message key="label.vlan.range" />',
'label.vxlan': '<fmt:message key="label.vxlan" />',
'label.vxlan.id': '<fmt:message key="label.vxlan.id" />',
'label.vxlan.range': '<fmt:message key="label.vxlan.range" />',
'label.vm.add': '<fmt:message key="label.vm.add" />',
'label.vm.destroy': '<fmt:message key="label.vm.destroy" />',
'label.vm.display.name': '<fmt:message key="label.vm.display.name" />',

View File

@ -643,6 +643,22 @@ cloudStack.docs = {
desc: 'In iSCSI, this is the LUN number. For example, 3.',
externalLink: ''
},
helpPrimaryStorageRBDMonitor: {
desc: 'The address of a Ceph monitor. Can also be a Round Robin DNS record',
externalLink: ''
},
helpPrimaryStorageRBDPool: {
desc: 'The pool to use on the Ceph cluster. This pool should already exist',
externalLink: ''
},
helpPrimaryStorageRBDId: {
desc: 'The cephx user to use without the client. prefix. For example: admin',
externalLink: ''
},
helpPrimaryStorageRBDSecret: {
desc: 'The base64 encoded secret of the cephx user.',
externalLink: ''
},
helpPrimaryStorageTags: {
desc: 'Comma-separated list of tags for this storage device. Must be the same set or a superset of the tags on your disk offerings.',
externalLink: ''

View File

@ -1168,9 +1168,12 @@ var addExtraPropertiesToGuestNetworkObject = function(jsonObj) {
jsonObj.scope = "Account (" + jsonObj.domain + ", " + jsonObj.account + ")";
}
if (jsonObj.vlan == null && jsonObj.broadcasturi != null) {
if (jsonObj.vlan == null && jsonObj.broadcasturi != null && jsonObj.broadcasturi.substring(0,7) == "vlan://") {
jsonObj.vlan = jsonObj.broadcasturi.replace("vlan://", "");
}
if(jsonObj.vxlan == null && jsonObj.broadcasturi != null && jsonObj.broadcasturi.substring(0,8) == "vxlan://") {
jsonObj.vxlan = jsonObj.broadcasturi.replace("vxlan://", "");
}
}
//used by infrastructure page

View File

@ -12803,10 +12803,6 @@
id: "SharedMountPoint",
description: "SharedMountPoint"
});
items.push({
id: "rbd",
description: "RBD"
});
args.response.success({
data: items
});
@ -13117,6 +13113,7 @@
// RBD
rbdmonitor: {
label: 'label.rbd.monitor',
docID: 'helpPrimaryStorageRBDMonitor',
validation: {
required: true
},
@ -13124,6 +13121,7 @@
},
rbdpool: {
label: 'label.rbd.pool',
docID: 'helpPrimaryStorageRBDPool',
validation: {
required: true
},
@ -13131,6 +13129,7 @@
},
rbdid: {
label: 'label.rbd.id',
docID: 'helpPrimaryStorageRBDId',
validation: {
required: false
},
@ -13138,6 +13137,7 @@
},
rbdsecret: {
label: 'label.rbd.secret',
docID: 'helpPrimaryStorageRBDSecret',
validation: {
required: false
},

View File

@ -715,10 +715,12 @@
$('<option>').attr({
value: 'VNS'
}).html('VNS'),
$('<option>').attr({
value: 'SSP'
}).html('SSP')
}).html('SSP'),
$('<option>').attr({
value: 'VXLAN'
}).html('VXLAN')
)
)
);