diff --git a/include/AuthManager.h b/include/AuthManager.h index e456f02fee..0042d5d8a8 100644 --- a/include/AuthManager.h +++ b/include/AuthManager.h @@ -457,13 +457,6 @@ private: */ void do_action(const string &name, void *args){}; - /** - * Base 64 encoding - * @param in the string to encoded - * @return a pointer to the encoded string (must be freed) or 0 in case of - * error - */ - static string * base64_encode(const string& in); }; diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 2709d66a49..5fedef7216 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -104,6 +104,14 @@ public: pthread_mutex_unlock(&mutex); }; + /** + * Function to print the object into a string in XML format + * base64 encoded + * @param xml the resulting XML string + * @return a reference to the generated string + */ + virtual string& to_xml64(string &xml64); + /** * Function to print the object into a string in XML format * @param xml the resulting XML string diff --git a/include/SSLTools.h b/include/SSLTools.h new file mode 100644 index 0000000000..8edef40653 --- /dev/null +++ b/include/SSLTools.h @@ -0,0 +1,51 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed 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. */ +/* -------------------------------------------------------------------------*/ + +#ifndef SSL_TOOLS_H_ +#define SSL_TOOLS_H_ + +#include + +using namespace std; + +/** + * The SSLTools class provides a simple interface to common SSL utils used + * in OpenNebula + */ +class SSLTools +{ +public: + /** + * sha1 digest + * @param in the string to be hashed + * @return sha1 hash of str + */ + static string sha1_digest(const string& in); + + /** + * Base 64 encoding + * @param in the string to encoded + * @return a pointer to the encoded string (must be freed) or 0 in case of + * error + */ + static string * base64_encode(const string& in); + +private: + SSLTools(){}; + ~SSLTools(){}; +}; + +#endif /*SSL_TOOLS_H_*/ diff --git a/include/User.h b/include/User.h index be2acaecae..437dd28f87 100644 --- a/include/User.h +++ b/include/User.h @@ -94,13 +94,6 @@ public: **/ static int split_secret(const string secret, string& user, string& pass); - /** - * "Encrypts" the password with SHA1 digest - * @param password - * @return sha1 encrypted password - */ - static string sha1_digest(const string& pass); - private: // ------------------------------------------------------------------------- // Friends diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 0c8e7dba48..7b441c77ae 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -323,11 +323,9 @@ IMAGE_MAD = [ # command : path can be absolute or relative to $ONE_LOCATION/share/hooks # case of self-contained installation or relative to # /usr/share/one/hooks in case of system-wide installation -# arguments : for the hook. You can access to VM template variables with $ -# - $ATTR, the value of an attribute e.g. $NAME or $VMID -# - $ATTR[VAR], the value of a vector e.g. $NIC[MAC] -# - $ATTR[VAR, COND], same of previous but COND select between -# multiple ATTRs e.g. $NIC[MAC, NETWORK="Public"] +# arguments : for the hook. You can access to VM information with $ +# - $VMID, the ID of the virtual machine +# - $TEMPLATE, the VM template in xml and base64 encoded # remote : values, # - YES, The hook is executed in the host where the VM was # allocated @@ -343,8 +341,9 @@ IMAGE_MAD = [ # command : path can be absolute or relative to $ONE_LOCATION/share/hooks # case of self-contained installation or relative to # /usr/share/one/hooks in case of system-wide installation -# arguments : for the hook. You can use the Host ID with $HID to pass it as -# argument for the hook +# arguments : for the hook. You can use the following Host information: +# - $HID, the ID of the host +# - $TEMPLATE, the Host template in xml and base64 encoded # remote : values, # - YES, The hook is executed in the host # - NO, The hook is executed in the OpenNebula server (default) diff --git a/src/authm/AuthManager.cc b/src/authm/AuthManager.cc index cc88d57de5..c162abcc49 100644 --- a/src/authm/AuthManager.cc +++ b/src/authm/AuthManager.cc @@ -16,15 +16,10 @@ #include "AuthManager.h" #include "NebulaLog.h" +#include "SSLTools.h" #include "Nebula.h" -#include -#include -#include -#include -#include - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -35,40 +30,6 @@ const char * AuthManager::auth_driver_name = "auth_exe"; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -string * AuthRequest::base64_encode(const string& in) -{ - BIO * bio_mem; - BIO * bio_64; - - char * encoded_c; - long int size; - - bio_64 = BIO_new(BIO_f_base64()); - bio_mem = BIO_new(BIO_s_mem()); - - BIO_push(bio_64, bio_mem); - - BIO_set_flags(bio_64,BIO_FLAGS_BASE64_NO_NL); - - BIO_write(bio_64, in.c_str(), in.length()); - - if (BIO_flush(bio_64) != 1) - { - return 0; - } - - size = BIO_get_mem_data(bio_mem,&encoded_c); - - string * encoded = new string(encoded_c,size); - - BIO_free_all(bio_64); - - return encoded; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - void AuthRequest::add_auth(Object ob, const string& ob_id, Operation op, @@ -91,7 +52,7 @@ void AuthRequest::add_auth(Object ob, if (op == CREATE || op == INSTANTIATE) //encode the ob_id, it is a template { - string * encoded_id = base64_encode(ob_id); + string * encoded_id = SSLTools::base64_encode(ob_id); if (encoded_id != 0) { diff --git a/src/authm/test/SConstruct b/src/authm/test/SConstruct index fedafed5e5..d3f9fcded1 100644 --- a/src/authm/test/SConstruct +++ b/src/authm/test/SConstruct @@ -17,10 +17,10 @@ Import('env') env.Prepend(LIBS=[ 'nebula_template', + 'nebula_authm', 'nebula_common', 'nebula_core', 'nebula_mad', - 'nebula_authm', 'nebula_sql', 'nebula_log', 'crypto' diff --git a/src/common/Attribute.cc b/src/common/Attribute.cc index 8f92b513f9..9df5bb078d 100644 --- a/src/common/Attribute.cc +++ b/src/common/Attribute.cc @@ -75,8 +75,20 @@ string * VectorAttribute::to_xml() const for (it=attribute_value.begin();it!=attribute_value.end();it++) { - oss << "<" << it->first << ">second - << "]]>first << ">"; + if ( it->first.empty() ) + { + continue; + } + + if ( it->second.empty() ) + { + oss << "<" << it->first << "/>"; + } + else + { + oss << "<" << it->first << ">second + << "]]>first << ">"; + } } oss << ""; @@ -133,9 +145,16 @@ void VectorAttribute::unmarshall(const string& sattr, const char * _sep) { continue; } - - attribute_value.insert(make_pair(tmp.substr(0,mpos), - tmp.substr(mpos+1))); + + if ( mpos + 1 == tmp.size() ) + { + attribute_value.insert(make_pair(tmp.substr(0,mpos),"")); + } + else + { + attribute_value.insert(make_pair(tmp.substr(0,mpos), + tmp.substr(mpos+1))); + } } } /* -------------------------------------------------------------------------- */ diff --git a/src/common/SConstruct b/src/common/SConstruct index 21aa3320e6..d491470b01 100644 --- a/src/common/SConstruct +++ b/src/common/SConstruct @@ -24,7 +24,8 @@ lib_name='nebula_common' source_files=[ 'ActionManager.cc', 'Attribute.cc', - 'mem_collector.c' + 'mem_collector.c', + 'SSLTools.cc' ] # Build library diff --git a/src/common/SSLTools.cc b/src/common/SSLTools.cc new file mode 100644 index 0000000000..dfc0c8e135 --- /dev/null +++ b/src/common/SSLTools.cc @@ -0,0 +1,98 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed 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. */ +/* -------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include + +#include "SSLTools.h" +#include +#include +#include + + +//#include + + +//#include +//#include +//#include + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string * SSLTools::base64_encode(const string& in) +{ + BIO * bio_mem; + BIO * bio_64; + + char * encoded_c; + long int size; + + bio_64 = BIO_new(BIO_f_base64()); + bio_mem = BIO_new(BIO_s_mem()); + + BIO_push(bio_64, bio_mem); + + BIO_set_flags(bio_64,BIO_FLAGS_BASE64_NO_NL); + + BIO_write(bio_64, in.c_str(), in.length()); + + if (BIO_flush(bio_64) != 1) + { + return 0; + } + + size = BIO_get_mem_data(bio_mem,&encoded_c); + + string * encoded = new string(encoded_c,size); + + BIO_free_all(bio_64); + + return encoded; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string SSLTools::sha1_digest(const string& in) +{ + EVP_MD_CTX mdctx; + unsigned char md_value[EVP_MAX_MD_SIZE]; + unsigned int md_len; + ostringstream oss; + + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL); + + EVP_DigestUpdate(&mdctx, in.c_str(), in.length()); + + EVP_DigestFinal_ex(&mdctx,md_value,&md_len); + EVP_MD_CTX_cleanup(&mdctx); + + for(unsigned int i = 0; iget_oid(); + + parsed.replace(found,4,oss.str()); + } + + found = parsed.find("$TEMPLATE"); + + if ( found != string::npos ) + { + string templ; + parsed.replace(found,9,host->to_xml64(templ)); + } +} // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- @@ -26,7 +50,6 @@ void HostAllocateHook::do_hook(void *arg) Host * host; string parsed_args = args; - size_t found; host = static_cast(arg); @@ -34,16 +57,8 @@ void HostAllocateHook::do_hook(void *arg) { return; } - - found = args.find("$HID"); - - if ( found !=string::npos ) - { - ostringstream oss; - oss << host->get_oid(); - - parsed_args.replace(found,4,oss.str()); - } + + parse_host_arguments(host,parsed_args); Nebula& ne = Nebula::instance(); HookManager * hm = ne.get_hm(); @@ -156,17 +171,8 @@ void HostStateHook::do_hook(void *arg) if ( cur_state == this->state ) { string parsed_args = args; - size_t found; - found = args.find("$HID"); - - if ( found !=string::npos ) - { - ostringstream oss; - oss << host->get_oid(); - - parsed_args.replace(found,4,oss.str()); - } + parse_host_arguments(host,parsed_args); Nebula& ne = Nebula::instance(); HookManager * hm = ne.get_hm(); diff --git a/src/pool/PoolObjectSQL.cc b/src/pool/PoolObjectSQL.cc index 5de6f9f99b..3d87a55280 100644 --- a/src/pool/PoolObjectSQL.cc +++ b/src/pool/PoolObjectSQL.cc @@ -15,6 +15,25 @@ /* -------------------------------------------------------------------------- */ #include "PoolObjectSQL.h" +#include "SSLTools.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string& PoolObjectSQL::to_xml64(string &xml64) +{ + string *str64; + + to_xml(xml64); + + str64 = SSLTools::base64_encode(xml64); + + xml64 = *str64; + + delete str64; + + return xml64; +} /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/scheduler/include/Client.h b/src/scheduler/include/Client.h index 9d28551635..e82c10c9d8 100644 --- a/src/scheduler/include/Client.h +++ b/src/scheduler/include/Client.h @@ -82,6 +82,11 @@ public: private: + /** + * Default message size for XML data off the network + */ + static const int MESSAGE_SIZE; + string one_auth; string one_endpoint; @@ -92,13 +97,6 @@ private: int read_oneauth(string &secret); int split_secret(const string secret, string& user, string& pass); - - string sha1_digest(const string& pass); - - /** - * Default message size for XML data off the network - */ - static const int MESSAGE_SIZE; }; #endif /*ONECLIENT_H_*/ diff --git a/src/scheduler/src/client/Client.cc b/src/scheduler/src/client/Client.cc index 91e3cc3eb1..b2bc97bc7a 100644 --- a/src/scheduler/src/client/Client.cc +++ b/src/scheduler/src/client/Client.cc @@ -15,6 +15,7 @@ /* -------------------------------------------------------------------------- */ #include "Client.h" +#include "SSLTools.h" #include #include @@ -25,12 +26,8 @@ #include #include -#include #include -#include -#include - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -57,7 +54,7 @@ void Client::set_one_auth(string secret) if( rc == 0 ) { - string sha1_pass = sha1_digest(pass); + string sha1_pass = SSLTools::sha1_digest(pass); one_auth = user + ":" + sha1_pass; } @@ -157,33 +154,6 @@ int Client::split_secret(const string secret, string& user, string& pass) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -string Client::sha1_digest(const string& pass) -{ - EVP_MD_CTX mdctx; - unsigned char md_value[EVP_MAX_MD_SIZE]; - unsigned int md_len; - ostringstream oss; - - EVP_MD_CTX_init(&mdctx); - EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL); - - EVP_DigestUpdate(&mdctx, pass.c_str(), pass.length()); - - EVP_DigestFinal_ex(&mdctx,md_value,&md_len); - EVP_MD_CTX_cleanup(&mdctx); - - for(unsigned int i = 0; i #include - -#include #include #include "User.h" @@ -206,29 +204,3 @@ int User::split_secret(const string secret, string& user, string& pass) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -string User::sha1_digest(const string& pass) -{ - EVP_MD_CTX mdctx; - unsigned char md_value[EVP_MAX_MD_SIZE]; - unsigned int md_len; - ostringstream oss; - - EVP_MD_CTX_init(&mdctx); - EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL); - - EVP_DigestUpdate(&mdctx, pass.c_str(), pass.length()); - - EVP_DigestFinal_ex(&mdctx,md_value,&md_len); - EVP_MD_CTX_cleanup(&mdctx); - - for(unsigned int i = 0; i #include @@ -85,7 +86,7 @@ UserPool::UserPool(SqlDB * db):PoolSQL(db,User::table) if (User::split_secret(one_token,one_name,one_pass) == 0) { string error_str; - string sha1_pass = User::sha1_digest(one_pass); + string sha1_pass = SSLTools::sha1_digest(one_pass); allocate(&one_uid, one_name, sha1_pass, true, error_str); } diff --git a/src/um/test/UserPoolTest.cc b/src/um/test/UserPoolTest.cc index 9815c3d111..238a557e4d 100644 --- a/src/um/test/UserPoolTest.cc +++ b/src/um/test/UserPoolTest.cc @@ -20,6 +20,7 @@ #include "UserPool.h" #include "PoolTest.h" +#include "SSLTools.h" using namespace std; @@ -119,7 +120,7 @@ public: string st = "top_secret_string"; string sha1 = "773260f433f7fd6f89c1f1bfc32e080fc0748478"; - CPPUNIT_ASSERT( sha1 == User::sha1_digest(st) ); + CPPUNIT_ASSERT( sha1 == SSLTools::sha1_digest(st) ); } void split_secret() @@ -151,7 +152,7 @@ public: CPPUNIT_ASSERT( user->get_oid() == 0 ); CPPUNIT_ASSERT( user->get_name() == "one_user_test" ); - CPPUNIT_ASSERT( user->get_password() == User::sha1_digest("password") ); + CPPUNIT_ASSERT( user->get_password() == SSLTools::sha1_digest("password") ); } void authenticate() diff --git a/src/vm/VirtualMachineHook.cc b/src/vm/VirtualMachineHook.cc index 6283408b39..8d98e970e6 100644 --- a/src/vm/VirtualMachineHook.cc +++ b/src/vm/VirtualMachineHook.cc @@ -21,11 +21,36 @@ // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- +static void parse_vm_arguments(VirtualMachine *vm, string& parsed) +{ + size_t found; + + found = parsed.find("$VMID"); + + if ( found !=string::npos ) + { + ostringstream oss; + oss << vm->get_oid(); + + parsed.replace(found,5,oss.str()); + } + + found = parsed.find("$TEMPLATE"); + + if ( found != string::npos ) + { + string templ; + parsed.replace(found,9,vm->to_xml64(templ)); + } +} + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + void VirtualMachineAllocateHook::do_hook(void *arg) { VirtualMachine * vm; - int rc; - string parsed_args; + string parsed_args = args; vm = static_cast(arg); @@ -34,18 +59,15 @@ void VirtualMachineAllocateHook::do_hook(void *arg) return; } - rc = vm->parse_template_attribute(args, parsed_args); + parse_vm_arguments(vm, parsed_args); - if ( rc == 0) + Nebula& ne = Nebula::instance(); + HookManager * hm = ne.get_hm(); + const HookManagerDriver * hmd = hm->get(); + + if ( hmd != 0 ) { - Nebula& ne = Nebula::instance(); - HookManager * hm = ne.get_hm(); - const HookManagerDriver * hmd = hm->get(); - - if ( hmd != 0 ) - { - hmd->execute(vm->get_oid(),name,cmd,parsed_args); - } + hmd->execute(vm->get_oid(),name,cmd,parsed_args); } } @@ -143,29 +165,28 @@ void VirtualMachineStateHook::do_hook(void *arg) if ( cur_lcm == lcm && cur_vm == this->vm ) { - string parsed_args; + string parsed_args = args; - if ( vm->parse_template_attribute(args, parsed_args) == 0) + parse_vm_arguments(vm,parsed_args); + + Nebula& ne = Nebula::instance(); + HookManager * hm = ne.get_hm(); + + const HookManagerDriver * hmd = hm->get(); + + if ( hmd != 0 ) { - Nebula& ne = Nebula::instance(); - HookManager * hm = ne.get_hm(); - - const HookManagerDriver * hmd = hm->get(); - - if ( hmd != 0 ) + if ( ! remote ) { - if ( ! remote ) - { - hmd->execute(vm->get_oid(),name,cmd,parsed_args); - } - else if ( vm->hasHistory() ) - { - hmd->execute(vm->get_oid(), - name, - vm->get_hostname(), - cmd, - parsed_args); - } + hmd->execute(vm->get_oid(),name,cmd,parsed_args); + } + else if ( vm->hasHistory() ) + { + hmd->execute(vm->get_oid(), + name, + vm->get_hostname(), + cmd, + parsed_args); } } } diff --git a/src/vm/vm_var_parser.c b/src/vm/vm_var_parser.c index 62cc4142d7..b689e8673c 100644 --- a/src/vm/vm_var_parser.c +++ b/src/vm/vm_var_parser.c @@ -392,8 +392,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 11 -#define YY_END_OF_BUFFER 12 +#define YY_NUM_RULES 12 +#define YY_END_OF_BUFFER 13 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -401,11 +401,12 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[30] = +static yyconst flex_int16_t yy_accept[34] = { 0, - 0, 0, 0, 0, 12, 10, 1, 9, 9, 11, - 9, 8, 3, 6, 2, 4, 5, 10, 0, 3, - 2, 5, 0, 7, 3, 6, 2, 4, 0 + 0, 0, 0, 0, 0, 0, 13, 11, 1, 10, + 10, 12, 9, 3, 6, 2, 4, 5, 12, 8, + 11, 0, 3, 2, 5, 3, 6, 2, 4, 0, + 7, 8, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -419,7 +420,7 @@ static yyconst flex_int32_t yy_ec[256] = 8, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 9, 1, 10, 1, 7, 1, 7, 7, 7, 7, + 9, 1, 10, 1, 11, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -440,49 +441,52 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[11] = +static yyconst flex_int32_t yy_meta[12] = { 0, - 1, 1, 1, 1, 2, 1, 1, 1, 1, 1 + 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, + 3 } ; -static yyconst flex_int16_t yy_base[33] = +static yyconst flex_int16_t yy_base[39] = { 0, - 29, 28, 0, 0, 32, 0, 35, 35, 9, 35, - 27, 35, 28, 22, 26, 25, 35, 0, 0, 24, - 23, 35, 20, 35, 16, 9, 12, 11, 35, 19, - 11, 21 + 41, 40, 0, 0, 8, 12, 44, 0, 47, 47, + 18, 47, 47, 41, 0, 40, 39, 47, 32, 20, + 0, 0, 23, 21, 47, 20, 0, 19, 16, 13, + 47, 7, 47, 28, 31, 34, 10, 37 } ; -static yyconst flex_int16_t yy_def[33] = +static yyconst flex_int16_t yy_def[39] = { 0, - 30, 30, 29, 3, 29, 31, 29, 29, 29, 29, - 32, 29, 29, 29, 29, 29, 29, 31, 9, 29, - 29, 29, 32, 29, 29, 29, 29, 29, 0, 29, - 29, 29 + 34, 34, 33, 3, 35, 35, 33, 36, 33, 33, + 33, 33, 33, 33, 37, 33, 33, 33, 38, 33, + 36, 11, 33, 33, 33, 33, 37, 33, 33, 38, + 33, 33, 0, 33, 33, 33, 33, 33 } ; -static yyconst flex_int16_t yy_nxt[46] = +static yyconst flex_int16_t yy_nxt[59] = { 0, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 19, 18, 28, 27, 20, 26, 21, 25, 22, 6, - 6, 23, 23, 24, 27, 25, 28, 27, 26, 25, - 24, 29, 7, 7, 5, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29 + 10, 11, 12, 10, 13, 14, 15, 16, 17, 18, + 15, 19, 27, 32, 20, 19, 31, 29, 20, 22, + 28, 26, 28, 23, 26, 24, 32, 25, 8, 8, + 8, 12, 12, 12, 21, 31, 21, 30, 30, 30, + 29, 28, 26, 33, 9, 9, 7, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33 } ; -static yyconst flex_int16_t yy_chk[46] = +static yyconst flex_int16_t yy_chk[59] = { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 9, 31, 28, 27, 9, 26, 9, 25, 9, 30, - 30, 32, 32, 23, 21, 20, 16, 15, 14, 13, - 11, 5, 2, 1, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29 + 3, 5, 37, 32, 5, 6, 30, 29, 6, 11, + 28, 26, 24, 11, 23, 11, 20, 11, 34, 34, + 34, 35, 35, 35, 36, 19, 36, 38, 38, 38, + 17, 16, 14, 7, 2, 1, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[12] = +static yyconst flex_int32_t yy_rule_can_match_eol[13] = { 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, }; +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, }; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; @@ -532,10 +536,12 @@ char *vm_var_text; llocp->first_column = llocp->last_column; \ llocp->last_column += vm_var_leng; -#line 536 "vm_var_parser.c" + +#line 541 "vm_var_parser.c" #define INITIAL 0 #define VAR 1 +#define VALUE 2 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -713,7 +719,7 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 42 "vm_var_parser.l" +#line 43 "vm_var_parser.l" /* ------------------------------------------------------------------------- */ @@ -724,7 +730,7 @@ YY_DECL /* $NUM.CONTEXT_VARIABLE */ /* ------------------------------------------------------------------------- */ -#line 728 "vm_var_parser.c" +#line 734 "vm_var_parser.c" if ( !(yy_init) ) { @@ -777,13 +783,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 30 ) + if ( yy_current_state >= 34 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 35 ); + while ( yy_base[yy_current_state] != 47 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -819,60 +825,69 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 52 "vm_var_parser.l" +#line 53 "vm_var_parser.l" { BEGIN VAR;} YY_BREAK case 2: YY_RULE_SETUP -#line 54 "vm_var_parser.l" -{ return EQUAL;} +#line 55 "vm_var_parser.l" +{ BEGIN VALUE; return EQUAL; } YY_BREAK case 3: YY_RULE_SETUP -#line 55 "vm_var_parser.l" +#line 56 "vm_var_parser.l" { return COMMA;} YY_BREAK case 4: YY_RULE_SETUP -#line 56 "vm_var_parser.l" +#line 57 "vm_var_parser.l" { return OBRACKET;} YY_BREAK case 5: YY_RULE_SETUP -#line 57 "vm_var_parser.l" +#line 58 "vm_var_parser.l" { return CBRACKET;} YY_BREAK case 6: YY_RULE_SETUP -#line 59 "vm_var_parser.l" +#line 60 "vm_var_parser.l" { lvalp->val_str = - mem_collector_strdup(mc,vm_var_text); + mem_collector_strdup(mc,vm_var_text); return VARIABLE;} YY_BREAK case 7: /* rule 7 can match eol */ YY_RULE_SETUP -#line 63 "vm_var_parser.l" +#line 64 "vm_var_parser.l" { lvalp->val_str = - mem_collector_strdup(mc,vm_var_text+1); + mem_collector_strdup(mc,vm_var_text+1); lvalp->val_str[vm_var_leng-2] = '\0'; + BEGIN(VAR); return STRING;} YY_BREAK case 8: YY_RULE_SETUP -#line 68 "vm_var_parser.l" -{ lvalp->val_char = '\0'; - return EOA;} +#line 70 "vm_var_parser.l" +{ lvalp->val_str = + mem_collector_strdup(mc,vm_var_text); + BEGIN(VAR); + return STRING;} YY_BREAK case 9: YY_RULE_SETUP -#line 71 "vm_var_parser.l" +#line 75 "vm_var_parser.l" +{ lvalp->val_char = '\0'; + return EOA;} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 78 "vm_var_parser.l" { lvalp->val_char = *vm_var_text; BEGIN(INITIAL); return EOA;} YY_BREAK case YY_STATE_EOF(VAR): -#line 75 "vm_var_parser.l" +#line 82 "vm_var_parser.l" { lvalp->val_char = '\0'; BEGIN(INITIAL); return EOA;} @@ -880,19 +895,20 @@ case YY_STATE_EOF(VAR): /* ------------------------------------------------------------------------- */ /* Just copy the string verbatim till we find a variable (starts with $) */ /* ------------------------------------------------------------------------- */ -case 10: -/* rule 10 can match eol */ +case 11: +/* rule 11 can match eol */ YY_RULE_SETUP -#line 83 "vm_var_parser.l" +#line 90 "vm_var_parser.l" { lvalp->val_str = mem_collector_strdup(mc,vm_var_text); return RSTRING;} YY_BREAK -case 11: +case 12: YY_RULE_SETUP -#line 85 "vm_var_parser.l" +#line 92 "vm_var_parser.l" ECHO; YY_BREAK -#line 895 "vm_var_parser.c" +#line 910 "vm_var_parser.c" case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(VALUE): yyterminate(); case YY_END_OF_BUFFER: @@ -1183,7 +1199,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 30 ) + if ( yy_current_state >= 34 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1211,11 +1227,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 30 ) + if ( yy_current_state >= 34 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 29); + yy_is_jam = (yy_current_state == 33); return yy_is_jam ? 0 : yy_current_state; } @@ -1860,7 +1876,7 @@ void vm_var_free (void * ptr ) #define YYTABLES_NAME "yytables" -#line 85 "vm_var_parser.l" +#line 92 "vm_var_parser.l" diff --git a/src/vm/vm_var_parser.l b/src/vm/vm_var_parser.l index 48a39cf8b6..7a3b39007e 100644 --- a/src/vm/vm_var_parser.l +++ b/src/vm/vm_var_parser.l @@ -39,6 +39,7 @@ %option yylineno %x VAR +%x VALUE %% /* ------------------------------------------------------------------------- */ @@ -51,18 +52,24 @@ \$ { BEGIN VAR;} -[[:blank:]]*=[[:blank:]]* { return EQUAL;} +[[:blank:]]*=[[:blank:]]* { BEGIN VALUE; return EQUAL; } [[:blank:]]*,[[:blank:]]* { return COMMA;} \[[[:blank:]]* { return OBRACKET;} [[:blank:]]*\] { return CBRACKET;} [[:alnum:]_]+ { lvalp->val_str = - mem_collector_strdup(mc,yytext); + mem_collector_strdup(mc,yytext); return VARIABLE;} -\"[^\"]*\" { lvalp->val_str = - mem_collector_strdup(mc,yytext+1); +\"[^\"]*\" { lvalp->val_str = + mem_collector_strdup(mc,yytext+1); lvalp->val_str[yyleng-2] = '\0'; + BEGIN(VAR); + return STRING;} + +[[:alnum:]]+ { lvalp->val_str = + mem_collector_strdup(mc,yytext); + BEGIN(VAR); return STRING;} \$ { lvalp->val_char = '\0'; diff --git a/src/vm/vm_var_syntax.cc b/src/vm/vm_var_syntax.cc index a4f2f659cf..30866385ae 100644 --- a/src/vm/vm_var_syntax.cc +++ b/src/vm/vm_var_syntax.cc @@ -136,6 +136,92 @@ extern "C" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void get_image_attribute(VirtualMachine * vm, + const string& attr_name, + const string& img_name, + const string& img_value, + string& attr_value) +{ + Nebula& nd = Nebula::instance(); + + ImagePool * ipool = nd.get_ipool(); + Image * img; + int iid = -1; + string iid_str; + + int num; + vector attrs; + const VectorAttribute * disk; + + attr_value.clear(); + + if (img_name.empty() || img_name != "IMAGE_ID") + { + return; + } + + // ---------------------------------------------- + // Check that the image is in the template, so + // are sure that we can access the image template + // ---------------------------------------------- + num = vm->get_template_attribute("DISK",attrs); + + for (int i=0; i < num ;i++) + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + iid_str = disk->vector_value("IMAGE_ID"); + + if ( iid_str == img_value ) + { + istringstream iss(img_value); + + iss >> iid; + + if (iss.fail()) + { + iid = -1; + } + + break; + } + } + + if (iid == -1) + { + return; + } + + // ---------------------------------------------- + // Get the attribute template from the image + // ---------------------------------------------- + img = ipool->get(iid, true); + + if ( img == 0 ) + { + return; + } + + if (attr_name == "TEMPLATE") + { + attr_value = img->to_xml64(attr_value); + } + else + { + img->get_template_attribute(attr_name.c_str(),attr_value); + } + + img->unlock(); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void get_network_attribute(VirtualMachine * vm, const string& attr_name, const string& net_name, @@ -146,52 +232,112 @@ void get_network_attribute(VirtualMachine * vm, VirtualNetworkPool * vnpool = nd.get_vnpool(); VirtualNetwork * vn; + int vnet_id = -1; + string vnet_id_str; - string network = ""; + int num; + vector attrs; + const VectorAttribute * net; - attr_value = ""; + attr_value.clear(); - if (net_name.empty()) - { - vector nics; - const VectorAttribute * nic; - - if (vm->get_template_attribute("NIC",nics) == 0) - { - return; - } - - nic = dynamic_cast(nics[0]); - - if ( nic == 0 ) - { - return; - } - - network = nic->vector_value("NETWORK"); - } - else if (net_name == "NAME") - { - network = net_value; - } - - if ( network.empty() ) + if (net_name.empty() || net_name != "NETWORK_ID") { return; } - vn = vnpool->get(network, vm->get_uid(), true); + // ---------------------------------------------- + // Check that the network is in the template, so + // are sure that we can access its template + // ---------------------------------------------- + num = vm->get_template_attribute("NIC",attrs); + + for (int i=0; i < num ;i++) + { + net = dynamic_cast(attrs[i]); + + if ( net == 0 ) + { + continue; + } + + vnet_id_str = net->vector_value("NETWORK_ID"); + + if ( vnet_id_str == net_value ) + { + istringstream iss(net_value); + + iss >> vnet_id; + + if (iss.fail()) + { + vnet_id = -1; + } + + break; + } + } + + if (vnet_id == -1) + { + return; + } + + // ---------------------------------------------- + // Get the attribute template from the image + // ---------------------------------------------- + vn = vnpool->get(vnet_id, true); if ( vn == 0 ) { return; } - vn->get_template_attribute(attr_name.c_str(),attr_value); + if (attr_name == "TEMPLATE") + { + attr_value = vn->to_xml64(attr_value); + } + else + { + vn->get_template_attribute(attr_name.c_str(),attr_value); + } vn->unlock(); } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* +void get_user_attribute(VirtualMachine * vm, + const string& attr_name, + string& attr_value) +{ + Nebula& nd = Nebula::instance(); + + UserPool * upool = nd.get_upool(); + User * user; + + attr_value.clear(); + + user = upool->get(vm->get_uid(), true); + + if ( user == 0 ) + { + return; + } + + if (attr_name == "TEMPLATE") + { + attr_value = user->to_xml64(attr_value); + } + else + { + user->get_template_attribute(attr_name.c_str(),attr_value); + } + + user->unlock(); +} +*/ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -201,9 +347,23 @@ void insert_single(VirtualMachine * vm, { string value = ""; - vm->get_template_attribute(name.c_str(),value); + if (name == "TEMPLATE") + { + vm->to_xml64(value); + } + else if (name == "UID") + { + parsed << vm->get_uid(); + } + else + { + vm->get_template_attribute(name.c_str(),value); + } - parsed << value; + if (!value.empty()) + { + parsed << value; + } } /* -------------------------------------------------------------------------- */ @@ -222,7 +382,7 @@ void insert_vector(VirtualMachine * vm, int num; - if ( name == "NETWORK") + if (name == "NETWORK") { string value; @@ -235,35 +395,50 @@ void insert_vector(VirtualMachine * vm, return; } - - if ( ( num = vm->get_template_attribute(name.c_str(),values) ) <= 0 ) + else if (name == "IMAGE") { + string value; + + get_image_attribute(vm,vname,vvar,vval,value); + + if (!value.empty()) + { + parsed << value; + } + return; } - - if ( vvar.empty() ) - { - vattr = dynamic_cast(values[0]); - } else { - const VectorAttribute * tmp = 0; - - for (int i=0 ; i < num ; i++) + if ( ( num = vm->get_template_attribute(name.c_str(),values) ) <= 0 ) { - tmp = dynamic_cast(values[i]); + return; + } - if ( tmp && ( tmp->vector_value(vvar.c_str()) == vval )) + if ( vvar.empty() ) + { + vattr = dynamic_cast(values[0]); + } + else + { + const VectorAttribute * tmp = 0; + + for (int i=0 ; i < num ; i++) { - vattr = tmp; - break; + tmp = dynamic_cast(values[i]); + + if ( tmp && ( tmp->vector_value(vvar.c_str()) == vval )) + { + vattr = tmp; + break; + } } } - } - if ( vattr != 0 ) - { - parsed << vattr->vector_value(vname.c_str()); + if ( vattr != 0 ) + { + parsed << vattr->vector_value(vname.c_str()); + } } } @@ -273,7 +448,7 @@ void insert_vector(VirtualMachine * vm, /* Line 189 of yacc.c */ -#line 277 "vm_var_syntax.cc" +#line 452 "vm_var_syntax.cc" /* Enabling traces. */ #ifndef YYDEBUG @@ -319,7 +494,7 @@ typedef union YYSTYPE { /* Line 214 of yacc.c */ -#line 220 "vm_var_syntax.y" +#line 395 "vm_var_syntax.y" char * val_str; int val_int; @@ -328,7 +503,7 @@ typedef union YYSTYPE /* Line 214 of yacc.c */ -#line 332 "vm_var_syntax.cc" +#line 507 "vm_var_syntax.cc" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -353,7 +528,7 @@ typedef struct YYLTYPE /* Line 264 of yacc.c */ -#line 357 "vm_var_syntax.cc" +#line 532 "vm_var_syntax.cc" #ifdef short # undef short @@ -639,7 +814,7 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 244, 244, 245, 248, 252, 265, 280 + 0, 419, 419, 420, 423, 427, 440, 455 }; #endif @@ -1612,7 +1787,7 @@ yyreduce: case 4: /* Line 1464 of yacc.c */ -#line 249 "vm_var_syntax.y" +#line 424 "vm_var_syntax.y" { (*parsed) << (yyvsp[(1) - (1)].val_str); ;} @@ -1621,7 +1796,7 @@ yyreduce: case 5: /* Line 1464 of yacc.c */ -#line 253 "vm_var_syntax.y" +#line 428 "vm_var_syntax.y" { string name((yyvsp[(1) - (2)].val_str)); @@ -1639,7 +1814,7 @@ yyreduce: case 6: /* Line 1464 of yacc.c */ -#line 266 "vm_var_syntax.y" +#line 441 "vm_var_syntax.y" { string name((yyvsp[(1) - (5)].val_str)); string vname((yyvsp[(3) - (5)].val_str)); @@ -1659,7 +1834,7 @@ yyreduce: case 7: /* Line 1464 of yacc.c */ -#line 281 "vm_var_syntax.y" +#line 456 "vm_var_syntax.y" { string name((yyvsp[(1) - (9)].val_str)); string vname((yyvsp[(3) - (9)].val_str)); @@ -1682,7 +1857,7 @@ yyreduce: /* Line 1464 of yacc.c */ -#line 1686 "vm_var_syntax.cc" +#line 1861 "vm_var_syntax.cc" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1901,7 +2076,7 @@ yyreturn: /* Line 1684 of yacc.c */ -#line 299 "vm_var_syntax.y" +#line 474 "vm_var_syntax.y" extern "C" void vm_var__error( diff --git a/src/vm/vm_var_syntax.h b/src/vm/vm_var_syntax.h index f14220c3a3..8d099c1d0a 100644 --- a/src/vm/vm_var_syntax.h +++ b/src/vm/vm_var_syntax.h @@ -57,7 +57,7 @@ typedef union YYSTYPE { /* Line 1685 of yacc.c */ -#line 220 "vm_var_syntax.y" +#line 395 "vm_var_syntax.y" char * val_str; int val_int; diff --git a/src/vm/vm_var_syntax.y b/src/vm/vm_var_syntax.y index 8887bdd6fb..ae83471f07 100644 --- a/src/vm/vm_var_syntax.y +++ b/src/vm/vm_var_syntax.y @@ -74,6 +74,92 @@ extern "C" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void get_image_attribute(VirtualMachine * vm, + const string& attr_name, + const string& img_name, + const string& img_value, + string& attr_value) +{ + Nebula& nd = Nebula::instance(); + + ImagePool * ipool = nd.get_ipool(); + Image * img; + int iid = -1; + string iid_str; + + int num; + vector attrs; + const VectorAttribute * disk; + + attr_value.clear(); + + if (img_name.empty() || img_name != "IMAGE_ID") + { + return; + } + + // ---------------------------------------------- + // Check that the image is in the template, so + // are sure that we can access the image template + // ---------------------------------------------- + num = vm->get_template_attribute("DISK",attrs); + + for (int i=0; i < num ;i++) + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + iid_str = disk->vector_value("IMAGE_ID"); + + if ( iid_str == img_value ) + { + istringstream iss(img_value); + + iss >> iid; + + if (iss.fail()) + { + iid = -1; + } + + break; + } + } + + if (iid == -1) + { + return; + } + + // ---------------------------------------------- + // Get the attribute template from the image + // ---------------------------------------------- + img = ipool->get(iid, true); + + if ( img == 0 ) + { + return; + } + + if (attr_name == "TEMPLATE") + { + attr_value = img->to_xml64(attr_value); + } + else + { + img->get_template_attribute(attr_name.c_str(),attr_value); + } + + img->unlock(); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void get_network_attribute(VirtualMachine * vm, const string& attr_name, const string& net_name, @@ -84,52 +170,112 @@ void get_network_attribute(VirtualMachine * vm, VirtualNetworkPool * vnpool = nd.get_vnpool(); VirtualNetwork * vn; + int vnet_id = -1; + string vnet_id_str; - string network = ""; + int num; + vector attrs; + const VectorAttribute * net; - attr_value = ""; + attr_value.clear(); - if (net_name.empty()) - { - vector nics; - const VectorAttribute * nic; - - if (vm->get_template_attribute("NIC",nics) == 0) - { - return; - } - - nic = dynamic_cast(nics[0]); - - if ( nic == 0 ) - { - return; - } - - network = nic->vector_value("NETWORK"); - } - else if (net_name == "NAME") - { - network = net_value; - } - - if ( network.empty() ) + if (net_name.empty() || net_name != "NETWORK_ID") { return; } - vn = vnpool->get(network, vm->get_uid(), true); + // ---------------------------------------------- + // Check that the network is in the template, so + // are sure that we can access its template + // ---------------------------------------------- + num = vm->get_template_attribute("NIC",attrs); + + for (int i=0; i < num ;i++) + { + net = dynamic_cast(attrs[i]); + + if ( net == 0 ) + { + continue; + } + + vnet_id_str = net->vector_value("NETWORK_ID"); + + if ( vnet_id_str == net_value ) + { + istringstream iss(net_value); + + iss >> vnet_id; + + if (iss.fail()) + { + vnet_id = -1; + } + + break; + } + } + + if (vnet_id == -1) + { + return; + } + + // ---------------------------------------------- + // Get the attribute template from the image + // ---------------------------------------------- + vn = vnpool->get(vnet_id, true); if ( vn == 0 ) { return; } - vn->get_template_attribute(attr_name.c_str(),attr_value); + if (attr_name == "TEMPLATE") + { + attr_value = vn->to_xml64(attr_value); + } + else + { + vn->get_template_attribute(attr_name.c_str(),attr_value); + } vn->unlock(); } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* +void get_user_attribute(VirtualMachine * vm, + const string& attr_name, + string& attr_value) +{ + Nebula& nd = Nebula::instance(); + + UserPool * upool = nd.get_upool(); + User * user; + + attr_value.clear(); + + user = upool->get(vm->get_uid(), true); + + if ( user == 0 ) + { + return; + } + + if (attr_name == "TEMPLATE") + { + attr_value = user->to_xml64(attr_value); + } + else + { + user->get_template_attribute(attr_name.c_str(),attr_value); + } + + user->unlock(); +} +*/ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -139,9 +285,23 @@ void insert_single(VirtualMachine * vm, { string value = ""; - vm->get_template_attribute(name.c_str(),value); + if (name == "TEMPLATE") + { + vm->to_xml64(value); + } + else if (name == "UID") + { + parsed << vm->get_uid(); + } + else + { + vm->get_template_attribute(name.c_str(),value); + } - parsed << value; + if (!value.empty()) + { + parsed << value; + } } /* -------------------------------------------------------------------------- */ @@ -160,7 +320,7 @@ void insert_vector(VirtualMachine * vm, int num; - if ( name == "NETWORK") + if (name == "NETWORK") { string value; @@ -173,35 +333,50 @@ void insert_vector(VirtualMachine * vm, return; } - - if ( ( num = vm->get_template_attribute(name.c_str(),values) ) <= 0 ) + else if (name == "IMAGE") { + string value; + + get_image_attribute(vm,vname,vvar,vval,value); + + if (!value.empty()) + { + parsed << value; + } + return; } - - if ( vvar.empty() ) - { - vattr = dynamic_cast(values[0]); - } else { - const VectorAttribute * tmp = 0; - - for (int i=0 ; i < num ; i++) + if ( ( num = vm->get_template_attribute(name.c_str(),values) ) <= 0 ) { - tmp = dynamic_cast(values[i]); + return; + } - if ( tmp && ( tmp->vector_value(vvar.c_str()) == vval )) + if ( vvar.empty() ) + { + vattr = dynamic_cast(values[0]); + } + else + { + const VectorAttribute * tmp = 0; + + for (int i=0 ; i < num ; i++) { - vattr = tmp; - break; + tmp = dynamic_cast(values[i]); + + if ( tmp && ( tmp->vector_value(vvar.c_str()) == vval )) + { + vattr = tmp; + break; + } } } - } - if ( vattr != 0 ) - { - parsed << vattr->vector_value(vname.c_str()); + if ( vattr != 0 ) + { + parsed << vattr->vector_value(vname.c_str()); + } } }