mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch 'master' into javelin
This commit is contained in:
commit
2fb346ab62
@ -25,6 +25,9 @@
|
|||||||
<artifactId>cloudstack</artifactId>
|
<artifactId>cloudstack</artifactId>
|
||||||
<version>4.1.0-SNAPSHOT</version>
|
<version>4.1.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
<properties>
|
||||||
|
<mkisofs>mkisofs</mkisofs>
|
||||||
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
@ -167,6 +170,19 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<profiles>
|
<profiles>
|
||||||
|
<!-- Debian will never distribute mkisofs due to licensing issues.
|
||||||
|
Fortunately genisoimage is a work-alike -->
|
||||||
|
<profile>
|
||||||
|
<id>genisoimage</id>
|
||||||
|
<activation>
|
||||||
|
<file>
|
||||||
|
<exists>/usr/bin/genisoimage</exists>
|
||||||
|
</file>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<mkisofs>genisoimage</mkisofs>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>vmware</id>
|
<id>vmware</id>
|
||||||
<activation>
|
<activation>
|
||||||
@ -209,7 +225,7 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<executable>mkisofs</executable>
|
<executable>${mkisofs}</executable>
|
||||||
<workingDirectory>dist</workingDirectory>
|
<workingDirectory>dist</workingDirectory>
|
||||||
<arguments>
|
<arguments>
|
||||||
<argument>-quiet</argument>
|
<argument>-quiet</argument>
|
||||||
|
|||||||
@ -1,25 +1,22 @@
|
|||||||
<?xml version='1.0' encoding='utf-8' ?>
|
<?xml version='1.0' encoding='utf-8' ?>
|
||||||
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||||
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
|
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
|
||||||
%BOOK_ENTITIES;
|
%BOOK_ENTITIES;
|
||||||
]>
|
]>
|
||||||
|
|
||||||
<!-- Licensed to the Apache Software Foundation (ASF) under one
|
<!-- Licensed to the Apache Software Foundation (ASF) under one
|
||||||
or more contributor license agreements. See the NOTICE file
|
or more contributor license agreements. See the NOTICE file
|
||||||
distributed with this work for additional information
|
distributed with this work for additional information
|
||||||
regarding copyright ownership. The ASF licenses this file
|
regarding copyright ownership. The ASF licenses this file
|
||||||
to you under the Apache License, Version 2.0 (the
|
to you under the Apache License, Version 2.0 (the
|
||||||
"License"); you may not use this file except in compliance
|
"License"); you may not use this file except in compliance
|
||||||
with the License. You may obtain a copy of the License at
|
with the License. You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
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
|
||||||
Unless required by applicable law or agreed to in writing,
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
software distributed under the License is distributed on an
|
KIND, either express or implied. See the License for the
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
specific language governing permissions and limitations
|
||||||
KIND, either express or implied. See the License for the
|
under the License.
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="offerings">
|
<chapter id="offerings">
|
||||||
@ -28,4 +25,5 @@
|
|||||||
are discussed in the section on setting up networking for users.</para>
|
are discussed in the section on setting up networking for users.</para>
|
||||||
<xi:include href="compute-disk-service-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
<xi:include href="compute-disk-service-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||||
<xi:include href="system-service-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
<xi:include href="system-service-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||||
|
<xi:include href="sys-offering-sysvm.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|||||||
75
docs/en-US/sys-offering-sysvm.xml
Normal file
75
docs/en-US/sys-offering-sysvm.xml
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8' ?>
|
||||||
|
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||||
|
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
|
||||||
|
%BOOK_ENTITIES;
|
||||||
|
]>
|
||||||
|
<!-- 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.
|
||||||
|
-->
|
||||||
|
<section id="sys-offering-sysvm">
|
||||||
|
<title>Changing the Default System Offering for System VMs</title>
|
||||||
|
<para>You can manually change the system offering for a particular System VM. Additionally, as a
|
||||||
|
&PRODUCT; administrator, you can also change the default system offering used for System
|
||||||
|
VMs.</para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Create a new system offering.</para>
|
||||||
|
<para>For more information, see <phrase condition="install"><xref
|
||||||
|
linkend="creating-system-service-offerings"/></phrase>
|
||||||
|
<phrase condition="admin">Creating a New System Service Offering</phrase>. </para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Back up the database:</para>
|
||||||
|
<programlisting>mysqldump -u root -p cloud | bzip2 > cloud_backup.sql.bz2</programlisting>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Open an MySQL prompt:</para>
|
||||||
|
<programlisting>mysql -u cloud -p cloud</programlisting>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Run the following queries on the cloud database.</para>
|
||||||
|
<orderedlist numeration="loweralpha">
|
||||||
|
<listitem>
|
||||||
|
<para>In the disk_offering table, identify the original default offering and the new
|
||||||
|
offering you want to use by default. </para>
|
||||||
|
<para>Take a note of the ID of the new offering.</para>
|
||||||
|
<programlisting>select id,name,unique_name,type from disk_offering;</programlisting>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>For the original default offering, set the value of unique_name to NULL.</para>
|
||||||
|
<programlisting># update disk_offering set unique_name = NULL where id = 10;</programlisting>
|
||||||
|
<para>Ensure that you use the correct value for the ID.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>For the new offering that you want to use by default, set the value of unique_name
|
||||||
|
as follows:</para>
|
||||||
|
<para>For the default Console Proxy VM (CPVM) offering,set unique_name to
|
||||||
|
'Cloud.com-ConsoleProxy'. For the default Secondary Storage VM (SSVM) offering, set
|
||||||
|
unique_name to 'Cloud.com-SecondaryStorage'. For example:</para>
|
||||||
|
<programlisting>update disk_offering set unique_name = 'Cloud.com-ConsoleProxy' where id = 16;</programlisting>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Restart &PRODUCT; Management Server. Restarting is required because the default
|
||||||
|
offerings are loaded into the memory at startup.</para>
|
||||||
|
<programlisting>service cloud-management restart</programlisting>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Destroy the existing CPVM or SSVM offerings and wait for them to be recreated. The new
|
||||||
|
CPVM or SSVM are configured with the new offering. </para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</section>
|
||||||
@ -1371,6 +1371,7 @@ CREATE TABLE `cloud`.`alert` (
|
|||||||
`last_sent` DATETIME NULL COMMENT 'Last time the alert was sent',
|
`last_sent` DATETIME NULL COMMENT 'Last time the alert was sent',
|
||||||
`resolved` DATETIME NULL COMMENT 'when the alert status was resolved (available memory no longer at critical level, etc.)',
|
`resolved` DATETIME NULL COMMENT 'when the alert status was resolved (available memory no longer at critical level, etc.)',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
|
INDEX `last_sent` (`last_sent` DESC),
|
||||||
CONSTRAINT `uc_alert__uuid` UNIQUE (`uuid`)
|
CONSTRAINT `uc_alert__uuid` UNIQUE (`uuid`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,8 @@ ALTER TABLE `cloud`.`inline_load_balancer_nic_map` DROP COLUMN load_balancer_id;
|
|||||||
ALTER TABLE upload ADD uuid VARCHAR(40);
|
ALTER TABLE upload ADD uuid VARCHAR(40);
|
||||||
ALTER TABLE async_job modify job_cmd VARCHAR(255);
|
ALTER TABLE async_job modify job_cmd VARCHAR(255);
|
||||||
|
|
||||||
|
ALTER TABLE `cloud`.`alert` ADD INDEX `last_sent` (`last_sent` DESC) ;
|
||||||
|
|
||||||
-- populate uuid column with db id if uuid is null
|
-- populate uuid column with db id if uuid is null
|
||||||
UPDATE `cloud`.`account` set uuid=id WHERE uuid is NULL;
|
UPDATE `cloud`.`account` set uuid=id WHERE uuid is NULL;
|
||||||
UPDATE `cloud`.`alert` set uuid=id WHERE uuid is NULL;
|
UPDATE `cloud`.`alert` set uuid=id WHERE uuid is NULL;
|
||||||
|
|||||||
@ -16,11 +16,13 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from common import grammar
|
import re
|
||||||
from marvin.cloudstackAPI import *
|
from marvin.cloudstackAPI import *
|
||||||
from marvin import cloudstackAPI
|
from marvin import cloudstackAPI
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
pass
|
import sys
|
||||||
|
print "ImportError", e
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
completions = cloudstackAPI.__all__
|
completions = cloudstackAPI.__all__
|
||||||
|
|
||||||
@ -43,9 +45,12 @@ def main():
|
|||||||
completing commands and help docs. This reduces the overall search and
|
completing commands and help docs. This reduces the overall search and
|
||||||
cache_miss (computation) complexity from O(n) to O(1) for any valid cmd.
|
cache_miss (computation) complexity from O(n) to O(1) for any valid cmd.
|
||||||
"""
|
"""
|
||||||
|
pattern = re.compile("[A-Z]")
|
||||||
|
verbs = list(set([x[:pattern.search(x).start()] for x in completions
|
||||||
|
if pattern.search(x) is not None]).difference(['cloudstack']))
|
||||||
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
|
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
|
||||||
cache_verbs = {}
|
cache_verbs = {}
|
||||||
for verb in grammar:
|
for verb in verbs:
|
||||||
completions_found = filter(lambda x: x.startswith(verb), completions)
|
completions_found = filter(lambda x: x.startswith(verb), completions)
|
||||||
cache_verbs[verb] = {}
|
cache_verbs[verb] = {}
|
||||||
for api_name in completions_found:
|
for api_name in completions_found:
|
||||||
|
|||||||
@ -26,6 +26,7 @@ try:
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import pdb
|
import pdb
|
||||||
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
@ -38,7 +39,7 @@ try:
|
|||||||
|
|
||||||
from prettytable import PrettyTable
|
from prettytable import PrettyTable
|
||||||
from common import __version__, config_file, config_fields
|
from common import __version__, config_file, config_fields
|
||||||
from common import grammar, precached_verbs
|
from common import precached_verbs
|
||||||
from marvin.cloudstackConnection import cloudConnection
|
from marvin.cloudstackConnection import cloudConnection
|
||||||
from marvin.cloudstackException import cloudstackAPIException
|
from marvin.cloudstackException import cloudstackAPIException
|
||||||
from marvin.cloudstackAPI import *
|
from marvin.cloudstackAPI import *
|
||||||
@ -71,12 +72,12 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||||||
ruler = "="
|
ruler = "="
|
||||||
config_file = config_file
|
config_file = config_file
|
||||||
config_fields = config_fields
|
config_fields = config_fields
|
||||||
grammar = grammar
|
|
||||||
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
|
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
|
||||||
cache_verbs = precached_verbs
|
cache_verbs = precached_verbs
|
||||||
|
|
||||||
def __init__(self, pname):
|
def __init__(self, pname, verbs):
|
||||||
self.program_name = pname
|
self.program_name = pname
|
||||||
|
self.verbs = verbs
|
||||||
if os.path.exists(self.config_file):
|
if os.path.exists(self.config_file):
|
||||||
config = self.read_config()
|
config = self.read_config()
|
||||||
else:
|
else:
|
||||||
@ -102,11 +103,9 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||||||
logger.debug("Loaded config fields:\n%s" % self.config_fields)
|
logger.debug("Loaded config fields:\n%s" % self.config_fields)
|
||||||
|
|
||||||
cmd.Cmd.__init__(self)
|
cmd.Cmd.__init__(self)
|
||||||
# Update config if config_file does not exist
|
|
||||||
if not os.path.exists(self.config_file):
|
if not os.path.exists(self.config_file):
|
||||||
config = self.write_config()
|
config = self.write_config()
|
||||||
|
|
||||||
# Enable history support
|
|
||||||
try:
|
try:
|
||||||
if os.path.exists(self.history_file):
|
if os.path.exists(self.history_file):
|
||||||
readline.read_history_file(self.history_file)
|
readline.read_history_file(self.history_file)
|
||||||
@ -381,13 +380,13 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||||||
|
|
||||||
def completedefault(self, text, line, begidx, endidx):
|
def completedefault(self, text, line, begidx, endidx):
|
||||||
partitions = line.partition(" ")
|
partitions = line.partition(" ")
|
||||||
verb = partitions[0]
|
verb = partitions[0].strip()
|
||||||
rline = partitions[2].partition(" ")
|
rline = partitions[2].lstrip().partition(" ")
|
||||||
subject = rline[0]
|
subject = rline[0]
|
||||||
separator = rline[1]
|
separator = rline[1]
|
||||||
params = rline[2]
|
params = rline[2].lstrip()
|
||||||
|
|
||||||
if verb not in self.grammar:
|
if verb not in self.verbs:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
autocompletions = []
|
autocompletions = []
|
||||||
@ -436,7 +435,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||||||
args = args.strip().partition(" ")
|
args = args.strip().partition(" ")
|
||||||
key, value = (args[0], args[2])
|
key, value = (args[0], args[2])
|
||||||
setattr(self, key, value) # keys and attributes should have same names
|
setattr(self, key, value) # keys and attributes should have same names
|
||||||
self.prompt = self.prompt.strip() + " " # prompt fix
|
self.prompt = self.prompt.strip() + " " # prompt fix
|
||||||
self.write_config()
|
self.write_config()
|
||||||
|
|
||||||
def complete_set(self, text, line, begidx, endidx):
|
def complete_set(self, text, line, begidx, endidx):
|
||||||
@ -513,22 +512,22 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# Create handlers on the fly using closures
|
pattern = re.compile("[A-Z]")
|
||||||
self = CloudMonkeyShell
|
verbs = list(set([x[:pattern.search(x).start()] for x in completions
|
||||||
global grammar
|
if pattern.search(x) is not None]).difference(['cloudstack']))
|
||||||
for rule in grammar:
|
for verb in verbs:
|
||||||
def add_grammar(rule):
|
def add_grammar(verb):
|
||||||
def grammar_closure(self, args):
|
def grammar_closure(self, args):
|
||||||
if self.pipe_runner("%s %s" % (rule, args)):
|
if self.pipe_runner("%s %s" % (verb, args)):
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
args_partition = args.partition(" ")
|
args_partition = args.partition(" ")
|
||||||
res = self.cache_verbs[rule][args_partition[0]]
|
res = self.cache_verbs[verb][args_partition[0]]
|
||||||
cmd = res[0]
|
cmd = res[0]
|
||||||
helpdoc = res[2]
|
helpdoc = res[2]
|
||||||
args = args_partition[2]
|
args = args_partition[2]
|
||||||
except KeyError, e:
|
except KeyError, e:
|
||||||
self.print_shell("Error: invalid %s api arg" % rule, e)
|
self.print_shell("Error: invalid %s api arg" % verb, e)
|
||||||
return
|
return
|
||||||
if ' --help' in args or ' -h' in args:
|
if ' --help' in args or ' -h' in args:
|
||||||
self.print_shell(helpdoc)
|
self.print_shell(helpdoc)
|
||||||
@ -536,12 +535,12 @@ def main():
|
|||||||
self.default("%s %s" % (cmd, args))
|
self.default("%s %s" % (cmd, args))
|
||||||
return grammar_closure
|
return grammar_closure
|
||||||
|
|
||||||
grammar_handler = add_grammar(rule)
|
grammar_handler = add_grammar(verb)
|
||||||
grammar_handler.__doc__ = "%ss resources" % rule.capitalize()
|
grammar_handler.__doc__ = "%ss resources" % verb.capitalize()
|
||||||
grammar_handler.__name__ = 'do_' + rule
|
grammar_handler.__name__ = 'do_' + verb
|
||||||
setattr(self, grammar_handler.__name__, grammar_handler)
|
setattr(CloudMonkeyShell, grammar_handler.__name__, grammar_handler)
|
||||||
|
|
||||||
shell = CloudMonkeyShell(sys.argv[0])
|
shell = CloudMonkeyShell(sys.argv[0], verbs)
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
shell.onecmd(' '.join(sys.argv[1:]))
|
shell.onecmd(' '.join(sys.argv[1:]))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -39,12 +39,3 @@ config_fields = {'host': 'localhost', 'port': '8080',
|
|||||||
'history_file':
|
'history_file':
|
||||||
os.path.expanduser('~/.cloudmonkey_history')}
|
os.path.expanduser('~/.cloudmonkey_history')}
|
||||||
|
|
||||||
# Add verbs in grammar
|
|
||||||
grammar = ['create', 'list', 'delete', 'update', 'lock',
|
|
||||||
'enable', 'activate', 'disable', 'add', 'remove',
|
|
||||||
'attach', 'detach', 'associate', 'disassociate', 'generate', 'ldap',
|
|
||||||
'assign', 'authorize', 'change', 'register', 'configure',
|
|
||||||
'start', 'restart', 'reboot', 'stop', 'reconnect',
|
|
||||||
'cancel', 'destroy', 'revoke', 'mark', 'reset',
|
|
||||||
'copy', 'extract', 'migrate', 'restore', 'suspend',
|
|
||||||
'get', 'query', 'prepare', 'deploy', 'upload']
|
|
||||||
|
|||||||
@ -642,12 +642,16 @@
|
|||||||
},
|
},
|
||||||
vmLimit: {
|
vmLimit: {
|
||||||
label: 'label.instance.limits',
|
label: 'label.instance.limits',
|
||||||
isEditable: function(context) {
|
isEditable: function(context) {
|
||||||
|
|
||||||
|
if(context.accounts == undefined)
|
||||||
|
return false;
|
||||||
|
else {
|
||||||
if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin
|
if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
} }
|
||||||
},
|
},
|
||||||
ipLimit: {
|
ipLimit: {
|
||||||
label: 'label.ip.limits',
|
label: 'label.ip.limits',
|
||||||
|
|||||||
@ -1322,6 +1322,13 @@
|
|||||||
networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
|
networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
|
||||||
if (networkOfferingObjs != null && networkOfferingObjs.length > 0) {
|
if (networkOfferingObjs != null && networkOfferingObjs.length > 0) {
|
||||||
for (var i = 0; i < networkOfferingObjs.length; i++) {
|
for (var i = 0; i < networkOfferingObjs.length; i++) {
|
||||||
|
|
||||||
|
if(args.scope=="account-specific" && args.context.zones[0].securitygroupsenabled == true) { //BUG - CLOUDSTACK-1063
|
||||||
|
var serviceObjArray = networkOfferingObjs[i].name;
|
||||||
|
if(serviceObjArray == "DefaultSharedNetworkOfferingWithSGService"){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//comment out the following 12 lines because of CS-16718
|
//comment out the following 12 lines because of CS-16718
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -860,8 +860,19 @@
|
|||||||
|
|
||||||
// Previous button
|
// Previous button
|
||||||
if ($target.closest('div.button.previous').size()) {
|
if ($target.closest('div.button.previous').size()) {
|
||||||
var index = $steps.filter(':visible').index();
|
var $step = $steps.filter(':visible');
|
||||||
if (index) showStep(index);
|
var $networkStep = $steps.filter('.network');
|
||||||
|
var index = $step.index();
|
||||||
|
|
||||||
|
$networkStep.removeClass('next-use-security-groups');
|
||||||
|
|
||||||
|
if (index) {
|
||||||
|
if (index == $steps.size() - 1 && $networkStep.hasClass('next-use-security-groups')) {
|
||||||
|
showStep(5);
|
||||||
|
} else {
|
||||||
|
showStep(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,22 +57,80 @@
|
|||||||
var fields = $.map(args.form.fields, function(value, key) {
|
var fields = $.map(args.form.fields, function(value, key) {
|
||||||
return key;
|
return key;
|
||||||
})
|
})
|
||||||
|
|
||||||
$(fields).each(function() {
|
var ret = function() {
|
||||||
|
return $formContainer.dialog({
|
||||||
|
dialogClass: 'create-form',
|
||||||
|
closeOnEscape: false,
|
||||||
|
draggable: false,
|
||||||
|
width: 400,
|
||||||
|
title: _l(args.form.title),
|
||||||
|
open: function() {
|
||||||
|
if (args.form.preFilter) {
|
||||||
|
args.form.preFilter({ $form: $form, context: args.context });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: createLabel ? createLabel : _l('label.ok'),
|
||||||
|
'class': 'ok',
|
||||||
|
click: function() {
|
||||||
|
if (!complete($formContainer)) { return false; }
|
||||||
|
|
||||||
|
$('div.overlay').remove();
|
||||||
|
$('.tooltip-box').remove();
|
||||||
|
$formContainer.remove();
|
||||||
|
$(this).dialog('destroy');
|
||||||
|
|
||||||
|
$('.hovered-elem').hide();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: _l('label.cancel'),
|
||||||
|
'class': 'cancel',
|
||||||
|
click: function() {
|
||||||
|
$('div.overlay').remove();
|
||||||
|
$('.tooltip-box').remove();
|
||||||
|
$formContainer.remove();
|
||||||
|
$(this).dialog('destroy');
|
||||||
|
|
||||||
|
$('.hovered-elem').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).closest('.ui-dialog').overlay();
|
||||||
|
};
|
||||||
|
|
||||||
|
var isLastAsync = function(idx) {
|
||||||
|
for(var i = idx+1; i < $(fields).length ; i++) {
|
||||||
|
var f = args.form.fields[$(fields).get(i)];
|
||||||
|
if(f.select || f.dynamic){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var isAsync = false;
|
||||||
|
var isNoDialog = args.noDialog ? args.noDialog : false;
|
||||||
|
|
||||||
|
$(fields).each(function(idx, element) {
|
||||||
var key = this;
|
var key = this;
|
||||||
var field = args.form.fields[key];
|
var field = args.form.fields[key];
|
||||||
|
|
||||||
var $formItem = $('<div>')
|
var $formItem = $('<div>')
|
||||||
.addClass('form-item')
|
.addClass('form-item')
|
||||||
.attr({ rel: key });
|
.attr({ rel: key });
|
||||||
|
|
||||||
if(field.isHidden != null) {
|
if(field.isHidden != null) {
|
||||||
if (typeof(field.isHidden) == 'boolean' && field.isHidden == true)
|
if (typeof(field.isHidden) == 'boolean' && field.isHidden == true)
|
||||||
$formItem.hide();
|
$formItem.hide();
|
||||||
else if (typeof(field.isHidden) == 'function' && field.isHidden() == true)
|
else if (typeof(field.isHidden) == 'function' && field.isHidden() == true)
|
||||||
$formItem.hide();
|
$formItem.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
$formItem.appendTo($form);
|
$formItem.appendTo($form);
|
||||||
|
|
||||||
//Handling Escape KeyPress events
|
//Handling Escape KeyPress events
|
||||||
@ -96,7 +154,7 @@
|
|||||||
closeOnEscape: false
|
closeOnEscape: false
|
||||||
}); */
|
}); */
|
||||||
// Label field
|
// Label field
|
||||||
|
|
||||||
var $name = $('<div>').addClass('name')
|
var $name = $('<div>').addClass('name')
|
||||||
.appendTo($formItem)
|
.appendTo($formItem)
|
||||||
.append(
|
.append(
|
||||||
@ -104,9 +162,10 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
// red asterisk
|
// red asterisk
|
||||||
var $astersikSpan = $('<span>').addClass('field-required').html('*');
|
var $astersikSpan = $('<span>').addClass('field-required').html('*');
|
||||||
$name.find('label').prepend($astersikSpan);
|
$name.find('label').prepend($astersikSpan);
|
||||||
if (field.validation == null || field.validation.required == false) {
|
|
||||||
|
if (field.validation == null || field.validation.required == false) {
|
||||||
$astersikSpan.hide();
|
$astersikSpan.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +228,7 @@
|
|||||||
|
|
||||||
// Determine field type of input
|
// Determine field type of input
|
||||||
if (field.select) {
|
if (field.select) {
|
||||||
|
isAsync = true;
|
||||||
selectArgs = {
|
selectArgs = {
|
||||||
context: args.context,
|
context: args.context,
|
||||||
response: {
|
response: {
|
||||||
@ -193,6 +253,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$input.trigger('change');
|
$input.trigger('change');
|
||||||
|
|
||||||
|
if((!isNoDialog) && isLastAsync(idx)) {
|
||||||
|
ret();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -200,7 +264,7 @@
|
|||||||
selectFn = field.select;
|
selectFn = field.select;
|
||||||
$input = $('<select>')
|
$input = $('<select>')
|
||||||
.attr({ name: key })
|
.attr({ name: key })
|
||||||
.data('dialog-select-fn', function(args) {
|
.data('dialog-select-fn', function(args) {
|
||||||
selectFn(args ? $.extend(true, {}, selectArgs, args) : selectArgs);
|
selectFn(args ? $.extend(true, {}, selectArgs, args) : selectArgs);
|
||||||
})
|
})
|
||||||
.appendTo($value);
|
.appendTo($value);
|
||||||
@ -221,21 +285,21 @@
|
|||||||
var dependsOnArgs = {};
|
var dependsOnArgs = {};
|
||||||
|
|
||||||
$input.find('option').remove();
|
$input.find('option').remove();
|
||||||
|
|
||||||
if (!$target.children().size()) return true;
|
if (!$target.children().size()) return true;
|
||||||
|
|
||||||
dependsOnArgs[dependsOn] = $target.val();
|
dependsOnArgs[dependsOn] = $target.val();
|
||||||
|
|
||||||
selectFn($.extend(selectArgs, dependsOnArgs));
|
selectFn($.extend(selectArgs, dependsOnArgs));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!$dependsOn.is('select')) {
|
if (!$dependsOn.is('select')) {
|
||||||
selectFn(selectArgs);
|
selectFn(selectArgs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectFn(selectArgs);
|
selectFn(selectArgs);
|
||||||
}
|
}
|
||||||
} else if (field.isBoolean) {
|
} else if (field.isBoolean) {
|
||||||
if (field.multiArray) {
|
if (field.multiArray) {
|
||||||
@ -263,7 +327,7 @@
|
|||||||
} else {
|
} else {
|
||||||
// This is mainly for IE compatibility
|
// This is mainly for IE compatibility
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$input.attr('checked', false);
|
$input.attr('checked', false);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,6 +341,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (field.dynamic) {
|
} else if (field.dynamic) {
|
||||||
|
isAsync = true;
|
||||||
// Generate a 'sub-create-form' -- append resulting fields
|
// Generate a 'sub-create-form' -- append resulting fields
|
||||||
$input = $('<div>').addClass('dynamic-input').appendTo($value);
|
$input = $('<div>').addClass('dynamic-input').appendTo($value);
|
||||||
$form.hide();
|
$form.hide();
|
||||||
@ -297,6 +362,9 @@
|
|||||||
|
|
||||||
// Form should be slightly wider
|
// Form should be slightly wider
|
||||||
$form.closest(':ui-dialog').dialog('option', { position: 'center',closeOnEscape: false });
|
$form.closest(':ui-dialog').dialog('option', { position: 'center',closeOnEscape: false });
|
||||||
|
if((!isNoDialog) && isLastAsync(idx)) {
|
||||||
|
ret();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -308,63 +376,64 @@
|
|||||||
if (field.defaultValue) {
|
if (field.defaultValue) {
|
||||||
$input.val(field.defaultValue);
|
$input.val(field.defaultValue);
|
||||||
}
|
}
|
||||||
} else if (field.isDatepicker) { //jQuery datepicker
|
} else if (field.isDatepicker) { //jQuery datepicker
|
||||||
$input = $('<input>').attr({
|
$input = $('<input>').attr({
|
||||||
name: key,
|
name: key,
|
||||||
type: 'text'
|
type: 'text'
|
||||||
}).appendTo($value);
|
}).appendTo($value);
|
||||||
|
|
||||||
if (field.defaultValue) {
|
if (field.defaultValue) {
|
||||||
$input.val(field.defaultValue);
|
$input.val(field.defaultValue);
|
||||||
}
|
}
|
||||||
if (field.id) {
|
if (field.id) {
|
||||||
$input.attr('id', field.id);
|
$input.attr('id', field.id);
|
||||||
}
|
}
|
||||||
$input.addClass("disallowSpecialCharacters");
|
$input.addClass("disallowSpecialCharacters");
|
||||||
$input.datepicker({dateFormat: 'yy-mm-dd'});
|
$input.datepicker({dateFormat: 'yy-mm-dd'});
|
||||||
|
|
||||||
} else if(field.range) { //2 text fields on the same line (e.g. port range: startPort - endPort)
|
|
||||||
$input = $.merge(
|
|
||||||
// Range start
|
|
||||||
$('<input>').attr({
|
|
||||||
type: 'text',
|
|
||||||
name: field.range[0]
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Range end
|
} else if(field.range) {//2 text fields on the same line (e.g. port range: startPort - endPort)
|
||||||
$('<input>').attr({
|
$input = $.merge(
|
||||||
type: 'text',
|
// Range start
|
||||||
name: field.range[1]
|
$('<input>').attr({
|
||||||
})
|
type: 'text',
|
||||||
).appendTo(
|
name: field.range[0]
|
||||||
$('<div>').addClass('range-edit').appendTo($value)
|
}),
|
||||||
);
|
|
||||||
$input.wrap($('<div>').addClass('range-item'));
|
|
||||||
$input.addClass("disallowSpecialCharacters");
|
|
||||||
|
|
||||||
} else { //text field
|
|
||||||
$input = $('<input>').attr({
|
|
||||||
name: key,
|
|
||||||
type: field.password || field.isPassword ? 'password' : 'text'
|
|
||||||
}).appendTo($value);
|
|
||||||
|
|
||||||
if (field.defaultValue) {
|
// Range end
|
||||||
$input.val(field.defaultValue);
|
$('<input>').attr({
|
||||||
}
|
type: 'text',
|
||||||
if (field.id) {
|
name: field.range[1]
|
||||||
$input.attr('id', field.id);
|
})
|
||||||
}
|
).appendTo(
|
||||||
|
$('<div>').addClass('range-edit').appendTo($value)
|
||||||
|
);
|
||||||
|
$input.wrap($('<div>').addClass('range-item'));
|
||||||
|
$input.addClass("disallowSpecialCharacters");
|
||||||
|
|
||||||
|
} else { //text field
|
||||||
|
$input = $('<input>').attr({
|
||||||
|
name: key,
|
||||||
|
type: field.password || field.isPassword ? 'password' : 'text'
|
||||||
|
}).appendTo($value);
|
||||||
|
|
||||||
|
if (field.defaultValue) {
|
||||||
|
$input.val(field.defaultValue);
|
||||||
|
}
|
||||||
|
if (field.id) {
|
||||||
|
$input.attr('id', field.id);
|
||||||
|
}
|
||||||
$input.addClass("disallowSpecialCharacters");
|
$input.addClass("disallowSpecialCharacters");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(field.validation != null)
|
if(field.validation != null)
|
||||||
$input.data('validation-rules', field.validation);
|
$input.data('validation-rules', field.validation);
|
||||||
else
|
else
|
||||||
$input.data('validation-rules', {});
|
$input.data('validation-rules', {});
|
||||||
|
|
||||||
var fieldLabel = field.label;
|
var fieldLabel = field.label;
|
||||||
|
|
||||||
var inputId = $input.attr('id') ? $input.attr('id') : fieldLabel.replace(/\./g,'_');
|
var inputId = $input.attr('id') ? $input.attr('id') : fieldLabel.replace(/\./g,'_');
|
||||||
|
|
||||||
$input.attr('id', inputId);
|
$input.attr('id', inputId);
|
||||||
$name.find('label').attr('for', inputId);
|
$name.find('label').attr('for', inputId);
|
||||||
|
|
||||||
@ -380,29 +449,32 @@
|
|||||||
attachTo: '.form-item'
|
attachTo: '.form-item'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* $input.blur(function() {
|
/* $input.blur(function() {
|
||||||
console.log('tooltip remove->' + $input.attr('name'));
|
console.log('tooltip remove->' + $input.attr('name'));
|
||||||
});*/
|
});*/
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var getFormValues = function() {
|
var getFormValues = function() {
|
||||||
var formValues = {};
|
var formValues = {};
|
||||||
$.each(args.form.fields, function(key) {});
|
$.each(args.form.fields, function(key) {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup form validation
|
// Setup form validation
|
||||||
$formContainer.find('form').validate();
|
$formContainer.find('form').validate();
|
||||||
$formContainer.find('input, select').each(function() {
|
$formContainer.find('input, select').each(function() {
|
||||||
if ($(this).data('validation-rules')) {
|
if ($(this).data('validation-rules')) {
|
||||||
$(this).rules('add', $(this).data('validation-rules'));
|
$(this).rules('add', $(this).data('validation-rules'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$(this).rules('add', {});
|
$(this).rules('add', {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$form.find('select').trigger('change');
|
$form.find('select').trigger('change');
|
||||||
|
|
||||||
|
|
||||||
var complete = function($formContainer) {
|
var complete = function($formContainer) {
|
||||||
var $form = $formContainer.find('form');
|
var $form = $formContainer.find('form');
|
||||||
var data = cloudStack.serializeForm($form);
|
var data = cloudStack.serializeForm($form);
|
||||||
@ -429,93 +501,48 @@
|
|||||||
$formContainer: $formContainer,
|
$formContainer: $formContainer,
|
||||||
completeAction: complete
|
completeAction: complete
|
||||||
};
|
};
|
||||||
|
} else if (!isAsync) {
|
||||||
|
return ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $formContainer.dialog({
|
|
||||||
dialogClass: 'create-form',
|
|
||||||
closeOnEscape: false,
|
|
||||||
draggable: false,
|
|
||||||
width: 400,
|
|
||||||
title: _l(args.form.title),
|
|
||||||
open: function() {
|
|
||||||
if (args.form.preFilter) {
|
|
||||||
args.form.preFilter({ $form: $form, context: args.context });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: createLabel ? createLabel : _l('label.ok'),
|
|
||||||
'class': 'ok',
|
|
||||||
click: function() {
|
|
||||||
if (!complete($formContainer)) { return false; }
|
|
||||||
|
|
||||||
$('div.overlay').remove();
|
|
||||||
$('.tooltip-box').remove();
|
|
||||||
$formContainer.remove();
|
|
||||||
$(this).dialog('destroy');
|
|
||||||
|
|
||||||
$('.hovered-elem').hide();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: _l('label.cancel'),
|
|
||||||
'class': 'cancel',
|
|
||||||
click: function() {
|
|
||||||
$('div.overlay').remove();
|
|
||||||
$('.tooltip-box').remove();
|
|
||||||
$formContainer.remove();
|
|
||||||
$(this).dialog('destroy');
|
|
||||||
|
|
||||||
$('.hovered-elem').hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}).closest('.ui-dialog').overlay();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* to change a property(e.g. validation) of a createForm field after a createForm is rendered
|
* to change a property(e.g. validation) of a createForm field after a createForm is rendered
|
||||||
*/
|
*/
|
||||||
createFormField: {
|
createFormField: {
|
||||||
validation: {
|
validation: {
|
||||||
required: {
|
required: {
|
||||||
add: function($formField) {
|
add: function($formField) {
|
||||||
var $input = $formField.find('input, select');
|
|
||||||
var validationRules = $input.data('validation-rules');
|
|
||||||
|
|
||||||
if(validationRules == null || validationRules.required == null || validationRules.required == false) {
|
|
||||||
$formField.find('.name').find('label').find('span.field-required').css('display', 'inline'); //show red asterisk
|
|
||||||
|
|
||||||
if(validationRules == null)
|
|
||||||
validationRules = {};
|
|
||||||
validationRules.required = true;
|
|
||||||
$input.data('validation-rules', validationRules);
|
|
||||||
|
|
||||||
$input.rules('add', { required: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
remove: function($formField) {
|
|
||||||
var $input = $formField.find('input, select');
|
var $input = $formField.find('input, select');
|
||||||
var validationRules = $input.data('validation-rules');
|
var validationRules = $input.data('validation-rules');
|
||||||
|
|
||||||
if(validationRules != null && validationRules.required != null && validationRules.required == true) {
|
if(validationRules == null || validationRules.required == null || validationRules.required == false) {
|
||||||
$formField.find('.name').find('label').find('span.field-required').hide(); //hide red asterisk
|
$formField.find('.name').find('label').find('span.field-required').css('display', 'inline'); //show red asterisk
|
||||||
|
|
||||||
delete validationRules.required;
|
if(validationRules == null)
|
||||||
$input.data('validation-rules', validationRules);
|
validationRules = {};
|
||||||
|
validationRules.required = true;
|
||||||
|
$input.data('validation-rules', validationRules);
|
||||||
|
$input.rules('add', { required: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove: function($formField) {
|
||||||
|
var $input = $formField.find('input, select');
|
||||||
|
var validationRules = $input.data('validation-rules');
|
||||||
|
|
||||||
|
if(validationRules != null && validationRules.required != null && validationRules.required == true) {
|
||||||
|
$formField.find('.name').find('label').find('span.field-required').hide(); //hide red asterisk
|
||||||
|
delete validationRules.required;
|
||||||
|
$input.data('validation-rules', validationRules);
|
||||||
|
|
||||||
|
$input.rules('remove', 'required');
|
||||||
|
$formField.find('.value').find('label.error').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
$input.rules('remove', 'required');
|
|
||||||
|
|
||||||
$formField.find('.value').find('label.error').hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirmation dialog
|
* Confirmation dialog
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user