Statistics
| Branch: | Tag: | Revision:

one / src / vm / vm_var_syntax.y @ 4b66f92b

History | View | Annotate | Download (12.3 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs        */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
%{
18
#include <iostream>
19
#include <sstream>
20
#include <string>
21
#include <map>
22
#include <algorithm>
23

    
24
#include <ctype.h>
25
#include <string.h>
26

    
27
#include "vm_var_syntax.h"
28
#include "VirtualMachinePool.h"
29
#include "VirtualMachine.h"
30
#include "Nebula.h"
31

    
32
#define vm_var__lex vm_var_lex
33

    
34
#define YYERROR_VERBOSE
35
#define VM_VAR_TO_UPPER(S) transform (S.begin(),S.end(),S.begin(), \
36
(int(*)(int))toupper)
37

    
38
extern "C"
39
{
40
    #include "mem_collector.h"
41

    
42
    void vm_var__error(
43
        YYLTYPE *        llocp,
44
        mem_collector *  mc,
45
        VirtualMachine * vm,
46
        ostringstream *  parsed,
47
        char **          errmsg,
48
        const char *     str);
49

    
50
    int vm_var__lex (YYSTYPE *lvalp, YYLTYPE *llocp, mem_collector * mc);
51

    
52
    int vm_var__parse (mem_collector *  mc,
53
                       VirtualMachine * vm,
54
                       ostringstream *  parsed,
55
                       char **          errmsg);
56

    
57
    int vm_var_parse (VirtualMachine * vm,
58
                      ostringstream *  parsed,
59
                      char **          errmsg)
60
    {
61
        mem_collector mc;
62
        int           rc;
63

    
64
        mem_collector_init(&mc);
65

    
66
        rc = vm_var__parse(&mc, vm, parsed, errmsg);
67

    
68
        mem_collector_cleanup(&mc);
69

    
70
        return rc;
71
    }
72
}
73

    
74
/* -------------------------------------------------------------------------- */
75
/* -------------------------------------------------------------------------- */
76

    
77
void get_image_attribute(VirtualMachine * vm,
78
                         const string&    attr_name,
79
                         const string&    img_name,
80
                         const string&    img_value,
81
                         string&          attr_value)
82
{
83
    Nebula& nd = Nebula::instance();
84

    
85
    ImagePool * ipool = nd.get_ipool();
86
    Image  *    img;
87
    int         iid = -1;
88

    
89
    int num;
90
    vector<const Attribute *> attrs;
91
    const VectorAttribute *   disk;
92

    
93
    attr_value.clear();
94

    
95
    if ( img_name.empty() || (img_name!="IMAGE" && img_name!="IMAGE_ID") )
96
    {
97
        return;
98
    }
99

    
100
    // ----------------------------------------------
101
    // Check that the image is in the template, so
102
    // are sure that we can access the image template
103
    // ----------------------------------------------
104
    num = vm->get_template_attribute("DISK",attrs);
105

    
106
    for (int i=0; i < num ;i++)
107
    {
108
        disk = dynamic_cast<const VectorAttribute *>(attrs[i]);
109

    
110
        if ( disk == 0 )
111
        {
112
            continue;
113
        }
114

    
115
        if ( disk->vector_value(img_name.c_str()) == img_value )
116
        {
117
            string        iid_str = disk->vector_value("IMAGE_ID");
118
            istringstream iss(iid_str);
119

    
120
            iss >> iid;
121

    
122
            if (iss.fail())
123
            {
124
                iid = -1;
125
            }
126

    
127
            break;
128
        }
129
    }
130

    
131
    if (iid == -1)
132
    {
133
        return;
134
    }
135

    
136
    // ----------------------------------------------
137
    // Get the attribute template from the image
138
    // ----------------------------------------------
139
    img = ipool->get(iid, true);
140

    
141
    if ( img == 0 )
142
    {
143
        return;
144
    }
145

    
146
    if (attr_name == "TEMPLATE")
147
    {
148
        attr_value = img->to_xml64(attr_value);
149
    }
150
    else
151
    {
152
        img->get_template_attribute(attr_name.c_str(),attr_value);
153
    }
154

    
155
    img->unlock();
156
}
157

    
158
/* -------------------------------------------------------------------------- */
159
/* -------------------------------------------------------------------------- */
160

    
161
void get_network_attribute(VirtualMachine * vm,
162
                           const string&    attr_name,
163
                           const string&    net_name,
164
                           const string&    net_value,
165
                           string&          attr_value)
166
{
167
    Nebula& nd = Nebula::instance();
168

    
169
    VirtualNetworkPool * vnpool = nd.get_vnpool();
170
    VirtualNetwork  *    vn;
171
    int                  ar_id, vnet_id = -1;
172

    
173
    int num;
174
    vector<const Attribute *> attrs;
175
    const VectorAttribute *   net;
176

    
177
    attr_value.clear();
178

    
179
    if ( net_name.empty() ||
180
        (net_name!="NETWORK" && net_name!="NETWORK_ID" && net_name!="NIC_ID"))
181
    {
182
        return;
183
    }
184

    
185
    // ----------------------------------------------
186
    // Check that the network is in the template, so
187
    // are sure that we can access its template
188
    // ----------------------------------------------
189
    num = vm->get_template_attribute("NIC",attrs);
190

    
191
    for (int i=0; i < num ;i++)
192
    {
193
        net = dynamic_cast<const VectorAttribute *>(attrs[i]);
194

    
195
        if ( net == 0 )
196
        {
197
            continue;
198
        }
199

    
200
        if ( net->vector_value(net_name.c_str()) == net_value )
201
        {
202
            if (net->vector_value("NETWORK_ID", vnet_id) != 0)
203
            {
204
                vnet_id = -1;
205
            }
206

    
207
            if (net->vector_value("AR_ID", ar_id) != 0)
208
            {
209
                vnet_id = -1;
210
            }
211

    
212
            break;
213
        }
214
    }
215

    
216
    if (vnet_id == -1)
217
    {
218
        return;
219
    }
220

    
221
    // ----------------------------------------------
222
    // Get the attribute template from the image
223
    // ----------------------------------------------
224
    vn = vnpool->get(vnet_id, true);
225

    
226
    if ( vn == 0 )
227
    {
228
        return;
229
    }
230

    
231
    if (attr_name == "TEMPLATE")
232
    {
233
        attr_value = vn->to_xml64(attr_value);
234
    }
235
    else
236
    {
237
        vn->get_template_attribute(attr_name.c_str(), attr_value, ar_id);
238
    }
239

    
240
    vn->unlock();
241
}
242

    
243
/* -------------------------------------------------------------------------- */
244
/* -------------------------------------------------------------------------- */
245

    
246
void get_user_attribute(VirtualMachine * vm,
247
                        const string&    attr_name,
248
                        string&          attr_value)
249
{
250
    Nebula& nd = Nebula::instance();
251

    
252
    UserPool * upool = nd.get_upool();
253
    User *     user;
254

    
255
    attr_value.clear();
256

    
257
    user = upool->get(vm->get_uid(), true);
258

    
259
    if ( user == 0 )
260
    {
261
        return;
262
    }
263

    
264
    if (attr_name == "TEMPLATE")
265
    {
266
        attr_value = user->to_xml64(attr_value);
267
    }
268
    else
269
    {
270
        user->get_template_attribute(attr_name.c_str(),attr_value);
271
    }
272

    
273
    user->unlock();
274
}
275

    
276
/* -------------------------------------------------------------------------- */
277
/* -------------------------------------------------------------------------- */
278

    
279
void insert_single(VirtualMachine * vm,
280
                   ostringstream&   parsed,
281
                   const string&    name)
282
{
283
    string value = "";
284

    
285
    if (name == "TEMPLATE")
286
    {
287
        vm->to_xml64(value);
288
    }
289
    else if (name == "UID")
290
    {
291
        parsed << vm->get_uid();
292
    }
293
    else if (name == "UNAME")
294
    {
295
        parsed << vm->get_uname();
296
    }
297
    else if (name == "GID")
298
    {
299
        parsed << vm->get_gid();
300
    }
301
    else if (name == "GNAME")
302
    {
303
        parsed << vm->get_gname();
304
    }
305
    else if (name == "NAME")
306
    {
307

    
308
        parsed << vm->get_name();
309
    }
310
    else
311
    {
312

    
313
        vm->get_template_attribute(name.c_str(),value);
314

    
315
        if (value.empty())
316
        {
317
            vm->get_user_template_attribute(name.c_str(),value);
318
        }
319
    }
320

    
321
    if (!value.empty())
322
    {
323
        parsed << value;
324
    }
325
}
326

    
327
/* -------------------------------------------------------------------------- */
328
/* -------------------------------------------------------------------------- */
329

    
330
void insert_vector(VirtualMachine * vm,
331
                   ostringstream&   parsed,
332
                   const string&    name,
333
                   const string&    vname,
334
                   const string&    vvar,
335
                   const string&    vval)
336

    
337
{
338
    vector<const Attribute*> values;
339
    const VectorAttribute *  vattr = 0;
340

    
341
    int    num;
342

    
343
    if (name == "NETWORK")
344
    {
345
        string value;
346

    
347
        get_network_attribute(vm,vname,vvar,vval,value);
348

    
349
        if (!value.empty())
350
        {
351
            parsed << value;
352
        }
353

    
354
        return;
355
    }
356
    else if (name == "IMAGE")
357
    {
358
        string value;
359

    
360
        get_image_attribute(vm,vname,vvar,vval,value);
361

    
362
        if (!value.empty())
363
        {
364
            parsed << value;
365
        }
366

    
367
        return;
368
    }
369
    else if (name == "USER")
370
    {
371
        string value;
372

    
373
        get_user_attribute(vm, vname, value);
374

    
375
        if (!value.empty())
376
        {
377
            parsed << value;
378
        }
379

    
380
        return;
381
    }
382
    else
383
    {
384
        if ( ( num = vm->get_template_attribute(name.c_str(),values) ) <= 0 )
385
        {
386
            return;
387
        }
388

    
389
        if ( vvar.empty() )
390
        {
391
            vattr = dynamic_cast<const VectorAttribute *>(values[0]);
392
        }
393
        else
394
        {
395
            const VectorAttribute * tmp = 0;
396

    
397
            for (int i=0 ; i < num ; i++)
398
            {
399
                tmp = dynamic_cast<const VectorAttribute *>(values[i]);
400

    
401
                if ( tmp && ( tmp->vector_value(vvar.c_str()) == vval ))
402
                {
403
                    vattr = tmp;
404
                    break;
405
                }
406
            }
407
        }
408

    
409
        if ( vattr != 0 )
410
        {
411
            parsed << vattr->vector_value(vname.c_str());
412
        }
413
    }
414
}
415

    
416
/* -------------------------------------------------------------------------- */
417
/* -------------------------------------------------------------------------- */
418

    
419
%}
420

    
421
%parse-param {mem_collector * mc}
422
%parse-param {VirtualMachine * vm}
423
%parse-param {ostringstream *  parsed}
424
%parse-param {char **          errmsg}
425

    
426
%lex-param {mem_collector * mc}
427

    
428
%union {
429
    char * val_str;
430
    int    val_int;
431
    char   val_char;
432
};
433

    
434
%defines
435
%locations
436
%pure_parser
437
%name-prefix = "vm_var__"
438
%output      = "vm_var_syntax.cc"
439

    
440
%token EQUAL COMMA OBRACKET CBRACKET
441

    
442
%token <val_char> EOA
443
%token <val_str>  STRING
444
%token <val_str>  VARIABLE
445
%token <val_str>  RSTRING
446
%token <val_int>  INTEGER
447
%type  <void>	  vm_variable
448
%type  <void>     vm_string
449

    
450
%%
451

    
452
vm_string:  vm_variable
453
    | vm_string vm_variable
454
    ;
455

    
456
vm_variable:RSTRING
457
    {
458
        (*parsed) << $1;
459
    }
460
    | VARIABLE EOA
461
    {
462
        string name($1);
463

    
464
        VM_VAR_TO_UPPER(name);
465

    
466
        insert_single(vm,*parsed,name);
467

    
468
        if ( $2 != '\0' )
469
        {
470
            (*parsed) << $2;
471
        }
472
    }
473
    | VARIABLE OBRACKET VARIABLE CBRACKET EOA
474
    {
475
        string name($1);
476
        string vname($3);
477

    
478
        VM_VAR_TO_UPPER(name);
479
        VM_VAR_TO_UPPER(vname);
480

    
481
        insert_vector(vm,*parsed,name,vname,"","");
482

    
483
        if ( $5 != '\0' )
484
        {
485
            (*parsed) << $5;
486
        }
487
    }
488
    | VARIABLE OBRACKET VARIABLE COMMA VARIABLE EQUAL STRING CBRACKET EOA
489
    {
490
        string name($1);
491
        string vname($3);
492
        string vvar($5);
493
        string vval($7);
494

    
495
        VM_VAR_TO_UPPER(name);
496
        VM_VAR_TO_UPPER(vname);
497
        VM_VAR_TO_UPPER(vvar);
498

    
499
        insert_vector(vm,*parsed,name,vname,vvar,vval);
500

    
501
        if ( $9 != '\0' )
502
        {
503
            (*parsed) << $9;
504
        }
505
    }
506
    ;
507
%%
508

    
509
extern "C" void vm_var__error(
510
    YYLTYPE *        llocp,
511
    mem_collector *  mc,
512
    VirtualMachine * vm,
513
    ostringstream *  parsed,
514
    char **          error_msg,
515
    const char *     str)
516
{
517
    int length;
518

    
519
    length = strlen(str)+ 64;
520

    
521
    *error_msg = (char *) malloc(sizeof(char)*length);
522

    
523
    if (*error_msg != 0)
524
    {
525
        snprintf(*error_msg,
526
            length,
527
            "%s at line %i, columns %i:%i",
528
            str,
529
            llocp->first_line,
530
            llocp->first_column,
531
            llocp->last_column);
532
    }
533
}