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>
|
||||
<version>4.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<properties>
|
||||
<mkisofs>mkisofs</mkisofs>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
@ -167,6 +170,19 @@
|
||||
</plugins>
|
||||
</build>
|
||||
<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>
|
||||
<id>vmware</id>
|
||||
<activation>
|
||||
@ -209,7 +225,7 @@
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<executable>mkisofs</executable>
|
||||
<executable>${mkisofs}</executable>
|
||||
<workingDirectory>dist</workingDirectory>
|
||||
<arguments>
|
||||
<argument>-quiet</argument>
|
||||
|
||||
@ -1,25 +1,22 @@
|
||||
<?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">
|
||||
%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.
|
||||
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.
|
||||
-->
|
||||
|
||||
<chapter id="offerings">
|
||||
@ -28,4 +25,5 @@
|
||||
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="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>
|
||||
|
||||
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',
|
||||
`resolved` DATETIME NULL COMMENT 'when the alert status was resolved (available memory no longer at critical level, etc.)',
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `last_sent` (`last_sent` DESC),
|
||||
CONSTRAINT `uc_alert__uuid` UNIQUE (`uuid`)
|
||||
) 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 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
|
||||
UPDATE `cloud`.`account` set uuid=id WHERE uuid is NULL;
|
||||
UPDATE `cloud`.`alert` set uuid=id WHERE uuid is NULL;
|
||||
|
||||
@ -16,11 +16,13 @@
|
||||
# under the License.
|
||||
|
||||
try:
|
||||
from common import grammar
|
||||
import re
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin import cloudstackAPI
|
||||
except ImportError, e:
|
||||
pass
|
||||
import sys
|
||||
print "ImportError", e
|
||||
sys.exit(1)
|
||||
|
||||
completions = cloudstackAPI.__all__
|
||||
|
||||
@ -43,9 +45,12 @@ def main():
|
||||
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.
|
||||
"""
|
||||
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=[]]}}
|
||||
cache_verbs = {}
|
||||
for verb in grammar:
|
||||
for verb in verbs:
|
||||
completions_found = filter(lambda x: x.startswith(verb), completions)
|
||||
cache_verbs[verb] = {}
|
||||
for api_name in completions_found:
|
||||
|
||||
@ -26,6 +26,7 @@ try:
|
||||
import logging
|
||||
import os
|
||||
import pdb
|
||||
import re
|
||||
import shlex
|
||||
import sys
|
||||
import time
|
||||
@ -38,7 +39,7 @@ try:
|
||||
|
||||
from prettytable import PrettyTable
|
||||
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.cloudstackException import cloudstackAPIException
|
||||
from marvin.cloudstackAPI import *
|
||||
@ -71,12 +72,12 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
ruler = "="
|
||||
config_file = config_file
|
||||
config_fields = config_fields
|
||||
grammar = grammar
|
||||
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
|
||||
cache_verbs = precached_verbs
|
||||
|
||||
def __init__(self, pname):
|
||||
def __init__(self, pname, verbs):
|
||||
self.program_name = pname
|
||||
self.verbs = verbs
|
||||
if os.path.exists(self.config_file):
|
||||
config = self.read_config()
|
||||
else:
|
||||
@ -102,11 +103,9 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
logger.debug("Loaded config fields:\n%s" % self.config_fields)
|
||||
|
||||
cmd.Cmd.__init__(self)
|
||||
# Update config if config_file does not exist
|
||||
if not os.path.exists(self.config_file):
|
||||
config = self.write_config()
|
||||
|
||||
# Enable history support
|
||||
try:
|
||||
if os.path.exists(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):
|
||||
partitions = line.partition(" ")
|
||||
verb = partitions[0]
|
||||
rline = partitions[2].partition(" ")
|
||||
verb = partitions[0].strip()
|
||||
rline = partitions[2].lstrip().partition(" ")
|
||||
subject = rline[0]
|
||||
separator = rline[1]
|
||||
params = rline[2]
|
||||
params = rline[2].lstrip()
|
||||
|
||||
if verb not in self.grammar:
|
||||
if verb not in self.verbs:
|
||||
return []
|
||||
|
||||
autocompletions = []
|
||||
@ -436,7 +435,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
args = args.strip().partition(" ")
|
||||
key, value = (args[0], args[2])
|
||||
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()
|
||||
|
||||
def complete_set(self, text, line, begidx, endidx):
|
||||
@ -513,22 +512,22 @@ class CloudMonkeyShell(cmd.Cmd, object):
|
||||
|
||||
|
||||
def main():
|
||||
# Create handlers on the fly using closures
|
||||
self = CloudMonkeyShell
|
||||
global grammar
|
||||
for rule in grammar:
|
||||
def add_grammar(rule):
|
||||
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']))
|
||||
for verb in verbs:
|
||||
def add_grammar(verb):
|
||||
def grammar_closure(self, args):
|
||||
if self.pipe_runner("%s %s" % (rule, args)):
|
||||
if self.pipe_runner("%s %s" % (verb, args)):
|
||||
return
|
||||
try:
|
||||
args_partition = args.partition(" ")
|
||||
res = self.cache_verbs[rule][args_partition[0]]
|
||||
res = self.cache_verbs[verb][args_partition[0]]
|
||||
cmd = res[0]
|
||||
helpdoc = res[2]
|
||||
args = args_partition[2]
|
||||
except KeyError, e:
|
||||
self.print_shell("Error: invalid %s api arg" % rule, e)
|
||||
self.print_shell("Error: invalid %s api arg" % verb, e)
|
||||
return
|
||||
if ' --help' in args or ' -h' in args:
|
||||
self.print_shell(helpdoc)
|
||||
@ -536,12 +535,12 @@ def main():
|
||||
self.default("%s %s" % (cmd, args))
|
||||
return grammar_closure
|
||||
|
||||
grammar_handler = add_grammar(rule)
|
||||
grammar_handler.__doc__ = "%ss resources" % rule.capitalize()
|
||||
grammar_handler.__name__ = 'do_' + rule
|
||||
setattr(self, grammar_handler.__name__, grammar_handler)
|
||||
grammar_handler = add_grammar(verb)
|
||||
grammar_handler.__doc__ = "%ss resources" % verb.capitalize()
|
||||
grammar_handler.__name__ = 'do_' + verb
|
||||
setattr(CloudMonkeyShell, grammar_handler.__name__, grammar_handler)
|
||||
|
||||
shell = CloudMonkeyShell(sys.argv[0])
|
||||
shell = CloudMonkeyShell(sys.argv[0], verbs)
|
||||
if len(sys.argv) > 1:
|
||||
shell.onecmd(' '.join(sys.argv[1:]))
|
||||
else:
|
||||
|
||||
@ -39,12 +39,3 @@ config_fields = {'host': 'localhost', 'port': '8080',
|
||||
'history_file':
|
||||
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: {
|
||||
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
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
} }
|
||||
},
|
||||
ipLimit: {
|
||||
label: 'label.ip.limits',
|
||||
|
||||
@ -1322,6 +1322,13 @@
|
||||
networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
|
||||
if (networkOfferingObjs != null && networkOfferingObjs.length > 0) {
|
||||
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
|
||||
/*
|
||||
|
||||
@ -860,8 +860,19 @@
|
||||
|
||||
// Previous button
|
||||
if ($target.closest('div.button.previous').size()) {
|
||||
var index = $steps.filter(':visible').index();
|
||||
if (index) showStep(index);
|
||||
var $step = $steps.filter(':visible');
|
||||
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;
|
||||
}
|
||||
|
||||
@ -57,22 +57,80 @@
|
||||
var fields = $.map(args.form.fields, function(value, 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 field = args.form.fields[key];
|
||||
|
||||
var $formItem = $('<div>')
|
||||
.addClass('form-item')
|
||||
.attr({ rel: key });
|
||||
|
||||
|
||||
if(field.isHidden != null) {
|
||||
if (typeof(field.isHidden) == 'boolean' && field.isHidden == true)
|
||||
$formItem.hide();
|
||||
else if (typeof(field.isHidden) == 'function' && field.isHidden() == true)
|
||||
$formItem.hide();
|
||||
if (typeof(field.isHidden) == 'boolean' && field.isHidden == true)
|
||||
$formItem.hide();
|
||||
else if (typeof(field.isHidden) == 'function' && field.isHidden() == true)
|
||||
$formItem.hide();
|
||||
}
|
||||
|
||||
|
||||
$formItem.appendTo($form);
|
||||
|
||||
//Handling Escape KeyPress events
|
||||
@ -96,7 +154,7 @@
|
||||
closeOnEscape: false
|
||||
}); */
|
||||
// Label field
|
||||
|
||||
|
||||
var $name = $('<div>').addClass('name')
|
||||
.appendTo($formItem)
|
||||
.append(
|
||||
@ -104,9 +162,10 @@
|
||||
);
|
||||
|
||||
// red asterisk
|
||||
var $astersikSpan = $('<span>').addClass('field-required').html('*');
|
||||
$name.find('label').prepend($astersikSpan);
|
||||
if (field.validation == null || field.validation.required == false) {
|
||||
var $astersikSpan = $('<span>').addClass('field-required').html('*');
|
||||
$name.find('label').prepend($astersikSpan);
|
||||
|
||||
if (field.validation == null || field.validation.required == false) {
|
||||
$astersikSpan.hide();
|
||||
}
|
||||
|
||||
@ -169,6 +228,7 @@
|
||||
|
||||
// Determine field type of input
|
||||
if (field.select) {
|
||||
isAsync = true;
|
||||
selectArgs = {
|
||||
context: args.context,
|
||||
response: {
|
||||
@ -193,6 +253,10 @@
|
||||
}
|
||||
|
||||
$input.trigger('change');
|
||||
|
||||
if((!isNoDialog) && isLastAsync(idx)) {
|
||||
ret();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -200,7 +264,7 @@
|
||||
selectFn = field.select;
|
||||
$input = $('<select>')
|
||||
.attr({ name: key })
|
||||
.data('dialog-select-fn', function(args) {
|
||||
.data('dialog-select-fn', function(args) {
|
||||
selectFn(args ? $.extend(true, {}, selectArgs, args) : selectArgs);
|
||||
})
|
||||
.appendTo($value);
|
||||
@ -221,21 +285,21 @@
|
||||
var dependsOnArgs = {};
|
||||
|
||||
$input.find('option').remove();
|
||||
|
||||
|
||||
if (!$target.children().size()) return true;
|
||||
|
||||
dependsOnArgs[dependsOn] = $target.val();
|
||||
|
||||
selectFn($.extend(selectArgs, dependsOnArgs));
|
||||
|
||||
selectFn($.extend(selectArgs, dependsOnArgs));
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!$dependsOn.is('select')) {
|
||||
selectFn(selectArgs);
|
||||
selectFn(selectArgs);
|
||||
}
|
||||
} else {
|
||||
selectFn(selectArgs);
|
||||
selectFn(selectArgs);
|
||||
}
|
||||
} else if (field.isBoolean) {
|
||||
if (field.multiArray) {
|
||||
@ -263,7 +327,7 @@
|
||||
} else {
|
||||
// This is mainly for IE compatibility
|
||||
setTimeout(function() {
|
||||
$input.attr('checked', false);
|
||||
$input.attr('checked', false);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
@ -277,6 +341,7 @@
|
||||
});
|
||||
}
|
||||
} else if (field.dynamic) {
|
||||
isAsync = true;
|
||||
// Generate a 'sub-create-form' -- append resulting fields
|
||||
$input = $('<div>').addClass('dynamic-input').appendTo($value);
|
||||
$form.hide();
|
||||
@ -297,6 +362,9 @@
|
||||
|
||||
// Form should be slightly wider
|
||||
$form.closest(':ui-dialog').dialog('option', { position: 'center',closeOnEscape: false });
|
||||
if((!isNoDialog) && isLastAsync(idx)) {
|
||||
ret();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -308,63 +376,64 @@
|
||||
if (field.defaultValue) {
|
||||
$input.val(field.defaultValue);
|
||||
}
|
||||
} else if (field.isDatepicker) { //jQuery datepicker
|
||||
$input = $('<input>').attr({
|
||||
name: key,
|
||||
type: 'text'
|
||||
}).appendTo($value);
|
||||
} else if (field.isDatepicker) { //jQuery datepicker
|
||||
$input = $('<input>').attr({
|
||||
name: key,
|
||||
type: 'text'
|
||||
}).appendTo($value);
|
||||
|
||||
if (field.defaultValue) {
|
||||
$input.val(field.defaultValue);
|
||||
}
|
||||
if (field.id) {
|
||||
$input.attr('id', field.id);
|
||||
}
|
||||
$input.addClass("disallowSpecialCharacters");
|
||||
$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]
|
||||
}),
|
||||
if (field.defaultValue) {
|
||||
$input.val(field.defaultValue);
|
||||
}
|
||||
if (field.id) {
|
||||
$input.attr('id', field.id);
|
||||
}
|
||||
$input.addClass("disallowSpecialCharacters");
|
||||
$input.datepicker({dateFormat: 'yy-mm-dd'});
|
||||
|
||||
// Range end
|
||||
$('<input>').attr({
|
||||
type: 'text',
|
||||
name: field.range[1]
|
||||
})
|
||||
).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);
|
||||
} 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]
|
||||
}),
|
||||
|
||||
if (field.defaultValue) {
|
||||
$input.val(field.defaultValue);
|
||||
}
|
||||
if (field.id) {
|
||||
$input.attr('id', field.id);
|
||||
}
|
||||
// Range end
|
||||
$('<input>').attr({
|
||||
type: 'text',
|
||||
name: field.range[1]
|
||||
})
|
||||
).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");
|
||||
}
|
||||
|
||||
if(field.validation != null)
|
||||
if(field.validation != null)
|
||||
$input.data('validation-rules', field.validation);
|
||||
else
|
||||
else
|
||||
$input.data('validation-rules', {});
|
||||
|
||||
var fieldLabel = field.label;
|
||||
|
||||
var inputId = $input.attr('id') ? $input.attr('id') : fieldLabel.replace(/\./g,'_');
|
||||
|
||||
|
||||
$input.attr('id', inputId);
|
||||
$name.find('label').attr('for', inputId);
|
||||
|
||||
@ -380,29 +449,32 @@
|
||||
attachTo: '.form-item'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* $input.blur(function() {
|
||||
console.log('tooltip remove->' + $input.attr('name'));
|
||||
});*/
|
||||
});
|
||||
|
||||
|
||||
|
||||
var getFormValues = function() {
|
||||
var formValues = {};
|
||||
$.each(args.form.fields, function(key) {});
|
||||
};
|
||||
|
||||
// Setup form validation
|
||||
// Setup form validation
|
||||
$formContainer.find('form').validate();
|
||||
$formContainer.find('input, select').each(function() {
|
||||
$formContainer.find('input, select').each(function() {
|
||||
if ($(this).data('validation-rules')) {
|
||||
$(this).rules('add', $(this).data('validation-rules'));
|
||||
}
|
||||
else {
|
||||
$(this).rules('add', {});
|
||||
}
|
||||
});
|
||||
$form.find('select').trigger('change');
|
||||
|
||||
|
||||
else {
|
||||
$(this).rules('add', {});
|
||||
}
|
||||
});
|
||||
$form.find('select').trigger('change');
|
||||
|
||||
|
||||
var complete = function($formContainer) {
|
||||
var $form = $formContainer.find('form');
|
||||
var data = cloudStack.serializeForm($form);
|
||||
@ -429,93 +501,48 @@
|
||||
$formContainer: $formContainer,
|
||||
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
|
||||
*/
|
||||
createFormField: {
|
||||
validation: {
|
||||
required: {
|
||||
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) {
|
||||
createFormField: {
|
||||
validation: {
|
||||
required: {
|
||||
add: 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);
|
||||
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 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
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user