root/trunk/tnodefunc.h

Revision 1852, 42.4 KB (checked in by Dylan, 5 months ago)

unxsVZ added migration of stopped container support.

  • Property svn:keywords set to id
Line 
1/*
2FILE
3        $Id$
4PURPOSE
5        Non schema-dependent table and application table related functions.
6AUTHOR/LEGAL
7        (C) 2001-2009 Unixservice, LLC. GPLv2 license applies.
8 
9*/
10
11static unsigned uClone=0;
12static unsigned uTargetNode=0;
13static char cuTargetNodePullDown[256]={""};
14static unsigned uWizIPv4=0;
15static char cuWizIPv4PullDown[32]={""};
16static char cSearch[32]={""};
17static unsigned uTargetDatacenter=0;
18static char cuTargetDatacenterPullDown[256]={""};
19static unsigned uCloneStop=WARM_CLONE;
20static unsigned uSyncPeriod=0;
21
22
23//ModuleFunctionProtos()
24void CopyProperties(unsigned uOldNode,unsigned uNewNode,unsigned uType);
25void DelProperties(unsigned uNode,unsigned uType);
26void tNodeNavList(unsigned uDataCenter);
27void tContainerNavList(unsigned uNode, char *cSearch);//tcontainerfunc.h
28void htmlGroups(unsigned uNode, unsigned uContainer);
29unsigned FailoverCloneContainer(unsigned uDatacenter, unsigned uNode, unsigned uContainer, unsigned uSource,
30                        unsigned uSourceNode, unsigned uSourceDatacenter, unsigned uIPv4, unsigned uStatus,
31                        char *cLabel, char *cHostname,unsigned uOwner,unsigned uDebug);
32unsigned CloneNode(unsigned uSourceNode,unsigned uTargetNode,unsigned uWizIPv4,const char *cuWizIPv4PullDown,
33                        unsigned uSyncPeriod,unsigned uCloneStop,unsigned uTargetDatacenter);
34
35//external
36//tcontainerfunc.h
37void htmlHealth(unsigned uContainer,unsigned uType);
38void htmlNodeHealth(unsigned uNode);
39char *cRatioColor(float *fRatio);
40void SetContainerStatus(unsigned uContainer,unsigned uStatus);
41unsigned FailoverToJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer,unsigned uOwner,unsigned uLoginClient,unsigned uDebug);
42unsigned FailoverFromJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,
43                                unsigned uIPv4,char *cLabel,char *cHostname,unsigned uSource,
44                                unsigned uStatus,unsigned uFailToJob,unsigned uOwner,unsigned uLoginClient,unsigned uDebug);
45//tcontainer.c
46void tTablePullDownAvail(const char *cTableName, const char *cFieldName,
47                        const char *cOrderby, unsigned uSelector, unsigned uMode);
48//tclientfunc.h
49static unsigned uForClient=0;
50static char cForClientPullDown[256]={"---"};
51
52void ExtProcesstNodeVars(pentry entries[], int x)
53{
54        register int i;
55        for(i=0;i<x;i++)
56        {
57                if(!strcmp(entries[i].name,"cSearch"))
58                {
59                        sprintf(cSearch,"%.31s",TextAreaSave(entries[i].val));
60                }
61                else if(!strcmp(entries[i].name,"cForClientPullDown"))
62                {
63                        strcpy(cForClientPullDown,entries[i].val);
64                        uForClient=ReadPullDown(TCLIENT,"cLabel",cForClientPullDown);
65                }
66                else if(!strcmp(entries[i].name,"uClone"))
67                {
68                        uClone=1;
69                }
70                else if(!strcmp(entries[i].name,"cuTargetNodePullDown"))
71                {
72                        sprintf(cuTargetNodePullDown,"%.255s",entries[i].val);
73                        uTargetNode=ReadPullDown("tNode","cLabel",cuTargetNodePullDown);
74                }
75                else if(!strcmp(entries[i].name,"cuWizIPv4PullDown"))
76                {
77                        sprintf(cuWizIPv4PullDown,"%.31s",entries[i].val);
78                        uWizIPv4=ReadPullDown("tIP","cLabel",cuWizIPv4PullDown);
79                }
80                else if(!strcmp(entries[i].name,"cuTargetDatacenterPullDown"))
81                {
82                        sprintf(cuTargetDatacenterPullDown,"%.255s",entries[i].val);
83                        uTargetDatacenter=ReadPullDown("tDatacenter","cLabel",cuTargetDatacenterPullDown);
84                }
85                else if(!strcmp(entries[i].name,"uCloneStop"))
86                {
87                        sscanf(entries[i].val,"%u",&uCloneStop);
88                }
89                else if(!strcmp(entries[i].name,"uSyncPeriod"))
90                {
91                        sscanf(entries[i].val,"%u",&uSyncPeriod);
92                }
93        }
94
95}//void ExtProcesstNodeVars(pentry entries[], int x)
96
97
98void ExttNodeCommands(pentry entries[], int x)
99{
100
101        if(!strcmp(gcFunction,"tNodeTools"))
102        {
103                MYSQL_RES *res;
104                time_t uActualModDate= -1;
105
106                if(!strcmp(gcCommand,LANG_NB_NEW))
107                {
108                        if(guPermLevel>=9)
109                        {
110                                ProcesstNodeVars(entries,x);
111                                guMode=2000;
112                                tNode(LANG_NB_CONFIRMNEW);
113                        }
114                }
115                else if(!strcmp(gcCommand,LANG_NB_CONFIRMNEW))
116                {
117                        if(guPermLevel>=9)
118                        {
119                                ProcesstNodeVars(entries,x);
120                                unsigned uOldNode=uNode;
121
122                                guMode=2000;
123                                //Check entries here
124                                if(strlen(cLabel)<3)
125                                        tNode("<blink>Error</blink>: Must supply valid cLabel. Min 3 chars!");
126                                if(!uDatacenter)
127                                        tNode("<blink>Error</blink>: Must supply valid uDatacenter!");
128                                sprintf(gcQuery,"SELECT uNode FROM tNode WHERE cLabel='%s'",
129                                                cLabel);
130                                mysql_query(&gMysql,gcQuery);
131                                if(mysql_errno(&gMysql))
132                                                htmlPlainTextError(mysql_error(&gMysql));
133                                res=mysql_store_result(&gMysql);
134                                if(mysql_num_rows(res))
135                                {
136                                        mysql_free_result(res);
137                                        tNode("<blink>Error</blink>: Node cLabel is used!");
138                                }
139                                guMode=0;
140
141                                if(!uForClient)
142                                        uOwner=guCompany;
143                                else
144                                        uOwner=uForClient;
145                                uNode=0;
146                                uCreatedBy=guLoginClient;
147                                uStatus=1;//Initially active
148                                uModBy=0;//Never modified
149                                uModDate=0;//Never modified
150                                NewtNode(1);//Come back here uNode should be set
151                                if(!uNode)
152                                        tNode("<blink>Error</blink>: New node was not created!");
153
154                                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=2"
155                                                ",cName='Name',cValue='%s',uOwner=%u,uCreatedBy=%u"
156                                                ",uCreatedDate=UNIX_TIMESTAMP(NOW())"
157                                                        ,uNode,cLabel,guCompany,guLoginClient);
158                                mysql_query(&gMysql,gcQuery);
159                                if(mysql_errno(&gMysql))
160                                                htmlPlainTextError(mysql_error(&gMysql));
161
162                                if(uNode && uClone && uOldNode)
163                                {
164                                        CopyProperties(uOldNode,uNode,2);
165                                        tNode("New node created and properties copied");
166                                }
167                                tNode("New node created");
168                        }
169                }
170                else if(!strcmp(gcCommand,LANG_NB_DELETE))
171                {
172                        ProcesstNodeVars(entries,x);
173                        if(uAllowDel(uOwner,uCreatedBy))
174                        {
175                                guMode=0;
176                                sprintf(gcQuery,"SELECT uNode FROM tContainer WHERE uNode=%u",
177                                                                        uNode);
178                                mysql_query(&gMysql,gcQuery);
179                                if(mysql_errno(&gMysql))
180                                                htmlPlainTextError(mysql_error(&gMysql));
181                                res=mysql_store_result(&gMysql);
182                                if(mysql_num_rows(res))
183                                {
184                                        mysql_free_result(res);
185                                        tNode("<blink>Error</blink>: Can't delete a node"
186                                                        " used by a container!");
187                                }
188                                guMode=2001;
189                                tNode(LANG_NB_CONFIRMDEL);
190                        }
191                        else
192                                tNode("<blink>Error</blink>: Denied by permissions settings");
193                }
194                else if(!strcmp(gcCommand,LANG_NB_CONFIRMDEL))
195                {
196                        ProcesstNodeVars(entries,x);
197                        if(uAllowDel(uOwner,uCreatedBy))
198                        {
199                                guMode=5;
200                                sscanf(ForeignKey("tNode","uModDate",uNode),"%lu",&uActualModDate);
201                                if(uModDate!=uActualModDate)
202                                        tNode("<blink>Error</blink>: This record was modified. Reload it.");
203
204                                sprintf(gcQuery,"SELECT uNode FROM tContainer WHERE uNode=%u",
205                                                                        uNode);
206                                mysql_query(&gMysql,gcQuery);
207                                if(mysql_errno(&gMysql))
208                                                htmlPlainTextError(mysql_error(&gMysql));
209                                res=mysql_store_result(&gMysql);
210                                if(mysql_num_rows(res))
211                                {
212                                        mysql_free_result(res);
213                                        tNode("<blink>Error</blink>: Can't delete a node"
214                                                        " used by a container!");
215                                }
216                                guMode=0;
217                                DelProperties(uNode,2);
218                                DeletetNode();
219                        }
220                        else
221                                tNode("<blink>Error</blink>: Denied by permissions settings");
222                }
223                else if(!strcmp(gcCommand,LANG_NB_MODIFY))
224                {
225                        ProcesstNodeVars(entries,x);
226                        if(uAllowMod(uOwner,uCreatedBy))
227                        {
228                                guMode=2002;
229                                tNode(LANG_NB_CONFIRMMOD);
230                        }
231                        else
232                                tNode("<blink>Error</blink>: Denied by permissions settings");
233                }
234                else if(!strcmp(gcCommand,LANG_NB_CONFIRMMOD))
235                {
236                        ProcesstNodeVars(entries,x);
237                        if(uAllowMod(uOwner,uCreatedBy))
238                        {
239                                guMode=2002;
240                                sscanf(ForeignKey("tNode","uModDate",uNode),"%lu",&uActualModDate);
241                                if(uModDate!=uActualModDate)
242                                        tNode("<blink>Error</blink>: This record was modified. Reload it.");
243                                if(strlen(cLabel)<3)
244                                        tNode("<blink>Error</blink>: Must supply valid cLabel. Min 3 chars!");
245                                if(!uDatacenter)
246                                        tNode("<blink>Error</blink>: Must supply valid uDatacenter!");
247                                guMode=0;
248
249                                if(uForClient)
250                                {
251                                        sprintf(gcQuery,"UPDATE tNode SET uOwner=%u WHERE uNode=%u",
252                                                uForClient,uNode);
253                                        mysql_query(&gMysql,gcQuery);
254                                        if(mysql_errno(&gMysql))
255                                                htmlPlainTextError(mysql_error(&gMysql));
256                                        uOwner=uForClient;
257                                }
258                                uModBy=guLoginClient;
259                                ModtNode();
260                        }
261                        else
262                                tNode("<blink>Error</blink>: Denied by permissions settings");
263                }
264                else if(!strcmp(gcCommand,"Node Container Report"))
265                {
266                        ProcesstNodeVars(entries,x);
267                        if(uStatus==1 && uAllowMod(uOwner,uCreatedBy))
268                        {
269                                guMode=0;
270
271                                sscanf(ForeignKey("tNode","uModDate",uNode),"%lu",&uActualModDate);
272                                if(uModDate!=uActualModDate)
273                                        tNode("<blink>Error</blink>: This record was modified. Reload it.");
274                               
275                                guMode=9001;
276                                tNode("");
277                        }
278                        else
279                        {
280                                tNode("<blink>Error</blink>: Denied by permissions settings");
281                        }
282                }
283                else if(!strcmp(gcCommand,"Clone Node Wizard"))
284                {
285                        ProcesstNodeVars(entries,x);
286                        if(uStatus==1 && uAllowMod(uOwner,uCreatedBy))
287                        {
288                                guMode=0;
289
290                                sscanf(ForeignKey("tNode","uModDate",uNode),"%lu",&uActualModDate);
291                                if(uModDate!=uActualModDate)
292                                        tNode("<blink>Error</blink>: This record was modified. Reload it.");
293                               
294                                guMode=7001;
295                                tNode("Select datacenter");
296                        }
297                        else
298                        {
299                                tNode("<blink>Error</blink>: Denied by permissions settings");
300                        }
301                }
302                else if(!strcmp(gcCommand,"Select Clone Datacenter"))
303                {
304                        ProcesstNodeVars(entries,x);
305                        if(uStatus==1 && uAllowMod(uOwner,uCreatedBy))
306                        {
307                                guMode=0;
308
309                                sscanf(ForeignKey("tNode","uModDate",uNode),"%lu",&uActualModDate);
310                                if(uModDate!=uActualModDate)
311                                        tNode("<blink>Error</blink>: This record was modified. Reload it.");
312
313                                guMode=7001;
314                                if(!uTargetDatacenter)
315                                        tNode("<blink>Error:</blink> You must select a datacenter");
316                               
317                                guMode=7002;
318                                tNode("Select node, uIPv4 and more");
319                        }
320                        else
321                        {
322                                tNode("<blink>Error</blink>: Denied by permissions settings");
323                        }
324                }
325                else if(!strcmp(gcCommand,"Confirm Node Clone"))
326                {
327                        ProcesstNodeVars(entries,x);
328                        if(uStatus==1 && uAllowMod(uOwner,uCreatedBy))
329                        {
330                                char cTargetNodeIPv4[32]={""};
331                                unsigned uRetVal=0;
332                                unsigned uIPv4Datacenter=0;
333
334                                guMode=0;
335
336                                sscanf(ForeignKey("tNode","uModDate",uNode),"%lu",&uActualModDate);
337                                if(uModDate!=uActualModDate)
338                                        tNode("<blink>Error</blink>: This record was modified. Reload it.");
339
340                                guMode=7002;
341                                //tNode("Function not available. Try again later");
342
343                                if(!uWizIPv4)
344                                        tNode("<blink>Error</blink>: You must select a start IP!");
345                                if(uTargetNode==0)
346                                        tNode("<blink>Error</blink>: Please select a valid target node!");
347                                if(uTargetNode==uNode)
348                                        tNode("<blink>Error</blink>: Can't clone to same node!");
349                                GetNodeProp(uTargetNode,"cIPv4",cTargetNodeIPv4);
350                                if(!cTargetNodeIPv4[0])
351                                        tNode("<blink>Error</blink>: Your target node is"
352                                                        " missing it's cIPv4 property!");
353                                if(uCloneStop>COLD_CLONE || uCloneStop<HOT_CLONE)
354                                        tNode("<blink>Error:</blink> Unexpected initial state");
355                                sscanf(ForeignKey("tIP","uDatacenter",uWizIPv4),"%u",&uIPv4Datacenter);
356                                if(uTargetDatacenter!=uIPv4Datacenter)
357                                        tNode("<blink>Error:</blink> The specified target uIPv4 does not "
358                                                        "belong to the specified uDatacenter.");
359                                if(!uDatacenter || !uTargetDatacenter )
360                                        tNode("<blink>Error:</blink> Unexpected problem with missing source node"
361                                                        " settings!");
362                                if(uSyncPeriod>86400*30 || (uSyncPeriod && uSyncPeriod<300))
363                                                tNode("<blink>Error:</blink> Clone uSyncPeriod seconds out of range:"
364                                                                " Max 30 days, min 5 minutes or 0 off.");
365                                guMode=0;
366
367                               
368                                uRetVal=CloneNode(uNode,uTargetNode,uWizIPv4,cuWizIPv4PullDown,uSyncPeriod,uCloneStop,
369                                                        uTargetDatacenter);
370                                if(uRetVal==5)
371                                        tNode("<blink>Operation not completed</blink>: Not enough IPs are available");
372                                else if(uRetVal==2)
373                                        tNode("<blink>Error</blink>: Unexpected CommonCloneContainer() error! Check tJob");
374                                else if(uRetVal)
375                                        tNode("<blink>Error</blink>: Unexpected CloneNode() error! Check tJob");
376                                else if(!uRetVal)
377                                        tNode("Clone node container jobs created");
378                                       
379
380                        }
381                }
382                else if(!strcmp(gcCommand,"Failover Node Wizard"))
383                {
384                        ProcesstNodeVars(entries,x);
385                        if(uStatus==1 && uAllowMod(uOwner,uCreatedBy))
386                        {
387                                guMode=0;
388
389                                sscanf(ForeignKey("tNode","uModDate",uNode),"%lu",&uActualModDate);
390                                if(uModDate!=uActualModDate)
391                                        tNode("<blink>Error</blink>: This record was modified. Reload it.");
392                               
393                                guMode=8001;
394                                tNode("Candiate failover jobs listed below, double check.");
395                        }
396                        else
397                        {
398                                tNode("<blink>Error</blink>: Denied by permissions settings");
399                        }
400                }
401                else if(!strcmp(gcCommand,"Confirm Node Failover"))
402                {
403                        ProcesstNodeVars(entries,x);
404                        if(uStatus==1 && uAllowMod(uOwner,uCreatedBy))
405                        {
406                                guMode=0;
407
408                                sscanf(ForeignKey("tNode","uModDate",uNode),"%lu",&uActualModDate);
409                                if(uModDate!=uActualModDate)
410                                        tNode("<blink>Error</blink>: This record was modified. Reload it.");
411
412                                guMode=8002;
413
414                                tNode("For failover jobs created see clone panel below");
415
416                        }
417                }
418        }
419
420}//void ExttNodeCommands(pentry entries[], int x)
421
422
423void ExttNodeButtons(void)
424{
425        OpenFieldSet("tNode Aux Panel",100);
426        switch(guMode)
427        {
428                case 9001:
429                        printf("<p><u>Node Container Report</u><br>");
430                        printf("See bottom panel.");
431                break;
432
433                case 7001:
434                        printf("<p><u>Node Clone Wizard (Step 1/2)</u><br>");
435                        printf("Here you will select the datacenter. If it is oversubscribed or not"
436                                " configured for use, or otherwise unavailable you will have to select another.");
437                        printf("<p>Select datacenter<br>");
438                        tTablePullDown("tDatacenter;cuTargetDatacenterPullDown","cLabel","cLabel",uTargetDatacenter,1);
439                        printf("<p><input title='Step one of remote clone wizard'"
440                                        " type=submit class=largeButton"
441                                        " name=gcCommand value='Select Clone Datacenter'>\n");
442                break;
443
444                case 7002:
445                        printf("<p><u>Node Clone Wizard (Step 2/2)</u><br>");
446                        printf("Here you will select the hardware node target. If the selected node is"
447                                " oversubscribed, not available, or scheduled for maintenance. You will"
448                                " be informed at the next step.\n<p>\n"
449                                "You must also select a start uIPv4 for the cloned containers, and set the initial"
450                                " state of the clone."
451                                " Usually clones should be kept stopped to conserve resources and facilitate rsync."
452                                " Use the checkbox to change this default behavior."
453                                " Any mount/umount files of the source container will NOT be used"
454                                " by the new cloned container. This issue will be left for manual"
455                                " or automated failover to the cloned container.<p>If you wish to"
456                                " keep the source and clone container sync'd you can specify a non zero"
457                                " value via the 'cuSyncPeriod' entry below.");
458                        printf("<p>Selected datacenter<br>");
459                        tTablePullDown("tDatacenter;cuTargetDatacenterPullDown","cLabel","cLabel",uTargetDatacenter,0);
460                        printf("<p>Select target node<br>");
461                        tTablePullDownDatacenter("tNode;cuTargetNodePullDown","cLabel","cLabel",uTargetNode,1,
462                                cuTargetNodePullDown,0,uTargetDatacenter);//0 does not use tProperty, uses uDatacenter
463                        printf("<p>Select start uIPv4<br>");
464                        tTablePullDownOwnerAvailDatacenter("tIP;cuWizIPv4PullDown","cLabel","cLabel",uWizIPv4,1,
465                                uTargetDatacenter,uOwner);
466
467                        printf("<p>Select clone state<br>");
468                        printf("<input type=radio name=uCloneStop value=%u",WARM_CLONE);
469                        if(uCloneStop==WARM_CLONE)
470                                printf(" checked");
471                        printf("> Stopped/Warm");
472                        printf("<input type=radio name=uCloneStop value=%u",COLD_CLONE);
473                        if(uCloneStop==COLD_CLONE)
474                                printf(" checked");
475                        printf("> Initial Setup/Cold");
476                        printf("<input type=radio name=uCloneStop value=%u",HOT_CLONE);
477                        if(uCloneStop==HOT_CLONE)
478                                printf(" checked");
479                        printf("> Active/Hot");
480
481                        printf("<p>cuSyncPeriod<br>");
482                        printf("<input title='Keep clone in sync every cuSyncPeriod seconds"
483                                        ". You can change this at any time via the property panel.'"
484                                        " type=text size=10 maxlength=7"
485                                        " name=uSyncPeriod value='%u'>\n",uSyncPeriod);
486                        printf("<p>Optional primary group change<br>");
487                        printf("<p><input title='Create a clone job for the current container'"
488                                        " type=submit class=largeButton"
489                                        " name=gcCommand value='Confirm Node Clone'>\n");
490                break;
491
492                case 8001:
493                        printf("<p><u>Failover Node Wizard</u><br>");
494                        printf("The current node should be down (or offline.)"
495                                " Other nodes should have \"-clone\" (uSource!=0) containers that have been kept updated."
496                                " The candidate containers are presented below for your approval.<p>");
497                        printf("<p><input title='Create failover jobs for all the current node`s master containers"
498                                        " and for other node`s corresponding clone container`s'"
499                                        " type=submit class=lwarnButton"
500                                        " name=gcCommand value='Confirm Node Failover'>\n");
501                break;
502
503                case 8002:
504                        printf("<p><u>Failover Node Wizard</u><br>");
505                        printf("Failover jobs have been attempted to be created see panel below for results."
506                                " See <a href=unxsVZ.cgi?gcFunction=tJob>tJob</a> for details.<p>");
507                break;
508
509                case 2000:
510                        printf("<p><u>Enter/mod data</u><br>");
511                        printf(LANG_NBB_CONFIRMNEW);
512                        if(uNode)
513                                printf("<p><input title='Copies all properties'"
514                                        " type=checkbox name=uClone checked> Copy properties from property panel below.\n");
515                        if(guPermLevel>11)
516                                tTablePullDownResellers(uForClient,1);
517                break;
518
519                case 2001:
520                        printf("<p><u>Think twice</u><br>");
521                        printf(LANG_NBB_CONFIRMDEL);
522                break;
523
524                case 2002:
525                        printf("<p><u>Review changes</u><br>");
526                        printf(LANG_NBB_CONFIRMMOD);
527                        if(guPermLevel>11)
528                        {
529                                printf("<p>To change the record owner, just...");
530                                tTablePullDownResellers(guCompany,1);
531                        }
532                break;
533
534                default:
535                        printf("<u>Table Tips</u><br>");
536                        printf("Hardware nodes are defined here. Hardware nodes host containers, and allow"
537                                " for the autonomic migration to other nodes that may be better suited"
538                                " at specific points in time to accomplish QoS or other system admin"
539                                " created policies herein. uVeth='Yes' container traffic is not included"
540                                "in the node graphs at this time.");
541                        printf("<p><u>Record Context Info</u><br>");
542                        if(uDatacenter && uNode)
543                        {
544                                printf("Node belongs to ");
545                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction=tDatacenter&uDatacenter=%u>%s</a>",
546                                                uDatacenter,ForeignKey("tDatacenter","cLabel",uDatacenter));
547                                htmlGroups(uNode,0);
548                        }
549                        printf("<p><u>Container Search</u><br>");
550                        printf("<input title='Use [Search], enter cLabel start or MySQL LIKE pattern (%% or _ allowed)'"
551                                        " type=text name=cSearch value='%s'>",cSearch);
552                        tNodeNavList(0);
553                        tContainerNavList(uNode,cSearch);
554                        if(uNode)
555                        {
556                                htmlHealth(uNode,2);
557                                htmlNodeHealth(uNode);
558                                printf("<p><input type=submit class=largeButton title='Display node container"
559                                        " report'"
560                                        " name=gcCommand value='Node Container Report'><br>");
561                                printf("<p><input type=submit class=largeButton title='Clone all containers"
562                                        " on this node to another node'"
563                                        " name=gcCommand value='Clone Node Wizard'><br>");
564                                printf("<input type=submit class=largeButton title='Failover to this node`s clone containers"
565                                        " the master containers`s of down node'"
566                                        " name=gcCommand value='Failover Node Wizard'><br>");
567                        }
568        }
569        CloseFieldSet();
570
571}//void ExttNodeButtons(void)
572
573
574void ExttNodeAuxTable(void)
575{
576        MYSQL_RES *res;
577        MYSQL_ROW field;
578
579        switch(guMode)
580        {
581                //Node Container Report
582                case 9001:
583                        sprintf(gcQuery,"Non clone %s Containers",cLabel);
584                        OpenFieldSet(gcQuery,100);
585                        printf("<table>");
586                        printf("<tr>"
587                                //"<td><u>select</u></td>"
588                                "<td><u>master label</u></td>"
589                                "<td><u>master hostname</u></td>"
590                                "<td><u>template</u></td>"
591                                "<td><u>status</u></td>"
592                                "<td><u>clone label</u></td>"
593                                "<td><u>clone hostname</u></td>"
594                                "<td><u>seconds since rsync</u></td>"
595                                "</tr>");
596                        sprintf(gcQuery,"SELECT tContainer.uContainer,tContainer.cLabel,tContainer.cHostname,"
597                                        "tContainer.uNode,tContainer.uDatacenter,tOSTemplate.cLabel,tStatus.cLabel"
598                                        " FROM tContainer,tOSTemplate,tStatus"
599                                        " WHERE tContainer.uNode=%u"
600                                        " AND tContainer.uOSTemplate=tOSTemplate.uOSTemplate"
601                                        " AND tContainer.uStatus=tStatus.uStatus"
602                                        " AND tContainer.uSource=0"
603                                        " ORDER BY tContainer.cLabel",uNode);
604                        mysql_query(&gMysql,gcQuery);
605                        if(mysql_errno(&gMysql))
606                                htmlPlainTextError(mysql_error(&gMysql));
607                        res=mysql_store_result(&gMysql);
608                        if(mysql_num_rows(res))
609                        {
610                                MYSQL_RES *res2;
611                                MYSQL_ROW field2;
612                                long unsigned luTotalDiskSpace=0;
613                                long unsigned luDiskSpace;
614
615                                while((field=mysql_fetch_row(res)))
616                                {
617                                        printf( "<tr>"
618                                                //"<td><input type=checkbox name=CNW%s</td>"
619                                                "<td>"
620                                                "<a class=darkLink href=unxsVZ.cgi?gcFunction=tContainer&uContainer=%s>%s</a>"
621                                                "</td>"
622                                                "<td>%s</td>"
623                                                "<td>%s</td>"
624                                                "<td>%s</td>",
625                                                        //field[0],
626                                                        field[0],field[1],field[2],field[5],field[6]);
627                                        sprintf(gcQuery,"SELECT uContainer,cLabel,cHostname,(UNIX_TIMESTAMP(NOW())-uBackupDate),"
628                                                        "uDatacenter,uNode,uIPv4,uStatus,uOwner"
629                                                        " FROM tContainer WHERE uSource=%s",field[0]);
630                                        mysql_query(&gMysql,gcQuery);
631                                        if(mysql_errno(&gMysql))
632                                                htmlPlainTextError(mysql_error(&gMysql));
633                                        res2=mysql_store_result(&gMysql);
634                                        if((field2=mysql_fetch_row(res2)))
635                                        {
636                                                printf("<td><a class=darkLink href=unxsVZ.cgi?"
637                                                        "gcFunction=tContainer&uContainer=%s>"
638                                                        "%s</a></td><td>%s</td><td>%s</td>",
639                                                                field2[0],field2[1],field2[2],field2[3]);
640                                        }
641                                        else
642                                        {
643                                                printf("<td>---</a></td><td>---</td><td>---</td>");
644                                        }
645                                        mysql_free_result(res2);
646                                        printf("</tr>\n");
647
648                                        sprintf(gcQuery,"SELECT cValue FROM tProperty"
649                                                        " WHERE cName='1k-blocks.luUsage' AND uType=3 AND uKey=%s",field[0]);
650                                        mysql_query(&gMysql,gcQuery);
651                                        if(mysql_errno(&gMysql))
652                                                htmlPlainTextError(mysql_error(&gMysql));
653                                        res2=mysql_store_result(&gMysql);
654                                        if((field2=mysql_fetch_row(res2)))
655                                        {
656                                                luDiskSpace=0;
657                                                sscanf(field2[0],"%lu",&luDiskSpace);
658                                                luTotalDiskSpace+=luDiskSpace;
659                                        }
660                                        mysql_free_result(res2);
661
662                                }
663                                printf("<tr><td>Total disk space used: %lu</td></tr>",luTotalDiskSpace);
664                        }
665                        printf("</table>");
666                        CloseFieldSet();
667                break;
668
669                case 8001:
670                case 8002:
671                        sprintf(gcQuery,"%s Clone Panel",cLabel);
672                        OpenFieldSet(gcQuery,100);
673                        printf("<table>");
674                        printf("<tr>"
675                                "<td><u>master label</u></td>"
676                                "<td><u>master hostname</u></td>"
677                                "<td><u>clone label</u></td>"
678                                "<td><u>clone hostname</u></td>"
679                                "<td><u>seconds since rsync</u></td>"
680                                "<td><u>job created</u></td>"
681                                "</tr>");
682                        sprintf(gcQuery,"SELECT uContainer,cLabel,cHostname,uNode,uDatacenter FROM tContainer WHERE"
683                                                        " uNode=%u AND uSource=0 AND uStatus=%u ORDER BY cLabel",uNode,uACTIVE);
684                        mysql_query(&gMysql,gcQuery);
685                        if(mysql_errno(&gMysql))
686                                htmlPlainTextError(mysql_error(&gMysql));
687                        res=mysql_store_result(&gMysql);
688                        if(mysql_num_rows(res))
689                        {
690                                MYSQL_RES *res2;
691                                MYSQL_ROW field2;
692
693                                while((field=mysql_fetch_row(res)))
694                                {
695                                        printf("<tr>");
696                                        printf("<td><a class=darkLink href=unxsVZ.cgi?"
697                                                        "gcFunction=tContainer&uContainer=%s>"
698                                                        "%s</a></td><td>%s</td>",
699                                                                field[0],field[1],field[2]);
700                                        sprintf(gcQuery,"SELECT uContainer,cLabel,cHostname,(UNIX_TIMESTAMP(NOW())-uBackupDate),"
701                                                        "uDatacenter,uNode,uIPv4,uStatus,uOwner"
702                                                        " FROM tContainer WHERE uSource=%s",field[0]);
703                                        mysql_query(&gMysql,gcQuery);
704                                        if(mysql_errno(&gMysql))
705                                                htmlPlainTextError(mysql_error(&gMysql));
706                                        res2=mysql_store_result(&gMysql);
707                                        if((field2=mysql_fetch_row(res2)))
708                                        {
709                                                printf("<td><a class=darkLink href=unxsVZ.cgi?"
710                                                        "gcFunction=tContainer&uContainer=%s>"
711                                                        "%s</a></td><td>%s</td><td>%s</td>",
712                                                                field2[0],field2[1],field2[2],field2[3]);
713                                                if(guMode==8002)
714                                                {
715                                                        unsigned uRetVal=0;
716
717                                                        unsigned uDatacenter=0;
718                                                        unsigned uNode=0;
719                                                        unsigned uContainer=0;
720                                                        unsigned uIPv4=0;
721                                                        unsigned uStatus=0;
722
723                                                        unsigned uSource=0;
724                                                        unsigned uSourceNode=0;
725                                                        unsigned uSourceDatacenter=0;
726
727                                                        sscanf(field2[0],"%u",&uContainer);
728                                                        sscanf(field2[4],"%u",&uDatacenter);
729                                                        sscanf(field2[5],"%u",&uNode);
730                                                        sscanf(field2[6],"%u",&uIPv4);
731                                                        sscanf(field2[7],"%u",&uStatus);
732
733                                                        //TODO note file scope global
734                                                        //Used in tcontainerfunc failover funcs.
735                                                        sscanf(field2[8],"%u",&uOwner);
736
737                                                        sscanf(field[0],"%u",&uSource);
738                                                        sscanf(field[3],"%u",&uSourceNode);
739                                                        sscanf(field[4],"%u",&uSourceDatacenter);
740
741                                                        uRetVal=FailoverCloneContainer(uDatacenter,uNode,uContainer,uSource,
742                                                                uSourceNode,uSourceDatacenter,uIPv4,uStatus,field2[1],field2[2],
743                                                                uOwner,1);//1 debug on
744                                                        if(uRetVal==0)
745                                                                printf("<td>X</td>");
746                                                        else if(uRetVal==1)
747                                                                printf("<td>!</td>");
748                                                }
749                                        }
750                                        mysql_free_result(res2);
751                                        printf("</tr>\n");
752                                }
753                        }
754                        printf("</table>");
755                        CloseFieldSet();
756                break;
757
758                default:
759                        if(!uNode || guMode!=6) return;
760
761                        sprintf(gcQuery,"%s Property Panel",cLabel);
762                        OpenFieldSet(gcQuery,100);
763
764                        sprintf(gcQuery,"SELECT uProperty,cName,cValue FROM tProperty WHERE"
765                                                        " uKey=%u AND uType=2 ORDER BY cName",uNode);
766                        mysql_query(&gMysql,gcQuery);
767                        if(mysql_errno(&gMysql))
768                                htmlPlainTextError(mysql_error(&gMysql));
769                        res=mysql_store_result(&gMysql);
770                        if(mysql_num_rows(res))
771                        {
772                                printf("<table>");
773                                while((field=mysql_fetch_row(res)))
774                                {
775                                        printf("<tr>");
776                                        printf("<td width=200 valign=top><a class=darkLink href=unxsVZ.cgi?"
777                                                        "gcFunction=tProperty&uProperty=%s&cReturn=tNode_%u>"
778                                                        "%s</a></td><td>%s</td>\n",
779                                                                field[0],uNode,field[1],field[2]);
780                                        printf("</tr>");
781                                }
782                                printf("</table>");
783                        }
784
785                        CloseFieldSet();
786        }
787
788}//void ExttNodeAuxTable(void)
789
790
791void ExttNodeGetHook(entry gentries[], int x)
792{
793        register int i;
794
795        for(i=0;i<x;i++)
796        {
797                if(!strcmp(gentries[i].name,"uNode"))
798                {
799                        sscanf(gentries[i].val,"%u",&uNode);
800                        guMode=6;
801                }
802                else if(!strcmp(gentries[i].name,"cSearch"))
803                {
804                        sprintf(cSearch,"%.31s",gentries[i].val);
805                }
806        }
807        tNode("");
808
809}//void ExttNodeGetHook(entry gentries[], int x)
810
811
812void ExttNodeSelect(void)
813{
814        ExtSelectPublic("tNode",VAR_LIST_tNode);
815
816}//void ExttNodeSelect(void)
817
818
819void ExttNodeSelectRow(void)
820{
821        ExtSelectRowPublic("tNode",VAR_LIST_tNode,uNode);
822
823}//void ExttNodeSelectRow(void)
824
825
826void ExttNodeListSelect(void)
827{
828        char cCat[512];
829
830        ExtListSelectPublic("tNode",VAR_LIST_tNode);
831       
832        //Changes here must be reflected below in ExttNodeListFilter()
833        if(!strcmp(gcFilter,"uNode"))
834        {
835                sscanf(gcCommand,"%u",&uNode);
836                if(guLoginClient==1 && guPermLevel>11)
837                        strcat(gcQuery," WHERE ");
838                else
839                        strcat(gcQuery," AND ");
840                sprintf(cCat,"tNode.uNode=%u ORDER BY uNode",uNode);
841                strcat(gcQuery,cCat);
842        }
843        else if(1)
844        {
845                //None NO FILTER
846                strcpy(gcFilter,"None");
847                strcat(gcQuery," ORDER BY uNode");
848        }
849
850}//void ExttNodeListSelect(void)
851
852
853void ExttNodeListFilter(void)
854{
855        //Filter
856        printf("&nbsp;&nbsp;&nbsp;Filter on ");
857        printf("<select name=gcFilter>");
858        if(strcmp(gcFilter,"uNode"))
859                printf("<option>uNode</option>");
860        else
861                printf("<option selected>uNode</option>");
862        if(strcmp(gcFilter,"None"))
863                printf("<option>None</option>");
864        else
865                printf("<option selected>None</option>");
866        printf("</select>");
867
868}//void ExttNodeListFilter(void)
869
870
871void ExttNodeNavBar(void)
872{
873        printf(LANG_NBB_SEARCH);
874        printf(LANG_NBB_SKIPFIRST);
875        printf(LANG_NBB_SKIPBACK);
876
877        if(guPermLevel>=9 && !guListMode)
878                printf(LANG_NBB_NEW);
879
880        if(uAllowMod(uOwner,uCreatedBy))
881                printf(LANG_NBB_MODIFY);
882
883        if(uAllowDel(uOwner,uCreatedBy))
884                printf(LANG_NBB_DELETE);
885
886        if(uOwner)
887                printf(LANG_NBB_LIST);
888
889        printf(LANG_NBB_SKIPNEXT);
890        printf(LANG_NBB_SKIPLAST);
891        printf("&nbsp;&nbsp;&nbsp;\n");
892
893}//void ExttNodeNavBar(void)
894
895
896//Nodes are shared infrastructure
897void tNodeNavList(unsigned uDatacenter)
898{
899        MYSQL_RES *res;
900        MYSQL_ROW field;
901        unsigned uMysqlNumRows;
902        unsigned uNumRows=0;
903#define LIMIT " LIMIT 25"
904#define uLIMIT 24
905
906        if(uDatacenter)
907                sprintf(gcQuery,"SELECT uNode,cLabel FROM tNode WHERE uDatacenter=%u"
908                                " ORDER BY cLabel"
909                                LIMIT,uDatacenter);
910        else
911                sprintf(gcQuery,"SELECT uNode,cLabel FROM tNode ORDER BY cLabel"
912                                LIMIT);
913        mysql_query(&gMysql,gcQuery);
914        if(mysql_errno(&gMysql))
915        {
916                printf("<p><u>tNodeNavList</u><br>\n");
917                printf("%s",mysql_error(&gMysql));
918                return;
919        }
920
921        res=mysql_store_result(&gMysql);
922        if((uMysqlNumRows=mysql_num_rows(res)))
923        {       
924                printf("<p><u>tNodeNavList(%u)</u><br>\n",uMysqlNumRows);
925
926                while((field=mysql_fetch_row(res)))
927                {
928
929                       
930                        if(cSearch[0])
931                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction=tNode"
932                                        "&uNode=%s&cSearch=%s>%s</a><br>\n",
933                                                        field[0],cURLEncode(cSearch),field[1]);
934                        else
935                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction=tNode"
936                                        "&uNode=%s>%s</a><br>\n",
937                                                        field[0],field[1]);
938
939                        if(++uNumRows>=uLIMIT)
940                        {
941                                printf("Only %u of %u nodes shown use [List] to view all.<br>\n",
942                                                uLIMIT,uMysqlNumRows);
943                                break;
944                        }
945                }
946        }
947        mysql_free_result(res);
948
949}//void tNodeNavList()
950
951
952
953void CopyProperties(unsigned uOldNode,unsigned uNewNode,unsigned uType)
954{
955        MYSQL_RES *res;
956        MYSQL_ROW field;
957
958        if(uOldNode==0 || uNewNode==0 || uType==0) return;
959
960        sprintf(gcQuery,"SELECT cName,cValue FROM tProperty WHERE uKey=%u AND uType=%u",
961                                        uOldNode,uType);
962        mysql_query(&gMysql,gcQuery);
963        if(mysql_errno(&gMysql))
964                htmlPlainTextError(mysql_error(&gMysql));
965        res=mysql_store_result(&gMysql);
966        while((field=mysql_fetch_row(res)))
967        {
968                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,cName='%s',cValue='%s',uType=%u,uOwner=%u,"
969                                "uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
970                                        uNewNode,
971                                        field[0],TextAreaSave(field[1]),
972                                        uType,
973                                        guLoginClient,guLoginClient);
974                mysql_query(&gMysql,gcQuery);
975                if(mysql_errno(&gMysql))
976                        htmlPlainTextError(mysql_error(&gMysql));
977        }
978        mysql_free_result(res);
979
980}//void CopyProperties(uNode,uNewNode)
981
982
983void DelProperties(unsigned uNode,unsigned uType)
984{
985        if(uNode==0 || uType==0) return;
986        sprintf(gcQuery,"DELETE FROM tProperty WHERE uType=%u AND uKey=%u",
987                                uType,uNode);
988        mysql_query(&gMysql,gcQuery);
989        if(mysql_errno(&gMysql))
990                htmlPlainTextError(mysql_error(&gMysql));
991
992}//void DelProperties()
993
994
995void htmlNodeHealth(unsigned uNode)
996{
997        MYSQL_RES *res;
998        MYSQL_ROW field;
999        char *cColor;
1000        float fRatio;
1001        long unsigned luAllContainerPhyspages=0;
1002        long unsigned luAllContainer=0;
1003        long unsigned luTotalRAM=0;
1004        long unsigned luInstalledRam=0;
1005        char cluInstalledRam[256];
1006
1007        GetNodeProp(uNode,"luInstalledRam",cluInstalledRam);
1008        sscanf(cluInstalledRam,"%lu",&luInstalledRam);
1009        if(luInstalledRam==0) luInstalledRam=1;
1010
1011
1012        //printf("<u>Critical Node Usage Data</u><br>\n");
1013
1014        //1-. (privvmpages exceeds RAM )
1015        //Check fundamental memory constraints of containers per node:
1016        //The memory gap between privvmpages and the two resource guarantees (vmguarpages and
1017        // oomguarpages) is not safe to use in an ongoing basis if the sum of all container
1018        // privvmpages exceeds RAM + swap of the hardware node.
1019        sprintf(gcQuery,"SELECT SUM(CONVERT(tProperty.cValue,UNSIGNED)) FROM tProperty,tContainer WHERE"
1020                                " tProperty.cName='privvmpages.luMaxheld'"
1021                                " AND tProperty.uType=3"
1022                                " AND tProperty.uKey=tContainer.uContainer"
1023                                " AND tContainer.uStatus!=11"//Probably active not initial setup
1024                                " AND tContainer.uStatus!=31"// and not stopped
1025                                " AND tContainer.uNode=%u",uNode);
1026        mysql_query(&gMysql,gcQuery);
1027        if(mysql_errno(&gMysql))
1028        {
1029                printf("%s",mysql_error(&gMysql));
1030                return;
1031        }
1032        res=mysql_store_result(&gMysql);
1033        if((field=mysql_fetch_row(res)))
1034        {
1035                long unsigned luContainerPrivvmpagesMaxHeld=0;
1036
1037                if(field[0]==NULL)
1038                {
1039                        printf("No data available, no active containers?<br>\n");
1040                        goto NextSection;
1041                }
1042
1043                sscanf(field[0],"%lu",&luContainerPrivvmpagesMaxHeld);
1044                fRatio= ((float) luContainerPrivvmpagesMaxHeld/ (float) luInstalledRam) * 100.00 ;
1045                cColor=cRatioColor(&fRatio);
1046                printf("Max held privvmpages ratio %2.2f%%:"
1047                        " <font color=%s>%lu/%lu</font><br>\n",
1048                                fRatio,cColor,luContainerPrivvmpagesMaxHeld,luInstalledRam);
1049        }
1050NextSection:
1051        mysql_free_result(res);
1052
1053
1054        //2-.
1055        //Inform if hardware node is overcommitted: 1-. cpu power
1056        sprintf(gcQuery,"SELECT SUM(CONVERT(tProperty.cValue,UNSIGNED)) FROM tProperty,tContainer WHERE"
1057                                " tProperty.cName='vzcpucheck.fCPUUnits'"
1058                                " AND tProperty.uType=3"
1059                                " AND tProperty.uKey=tContainer.uContainer"
1060                                " AND tContainer.uStatus!=11"//Probably active not initial setup
1061                                " AND tContainer.uStatus!=31"// and not stopped
1062                                " AND tContainer.uNode=%u",uNode);
1063        mysql_query(&gMysql,gcQuery);
1064        if(mysql_errno(&gMysql))
1065        {
1066                printf("%s",mysql_error(&gMysql));
1067                return;
1068        }
1069        res=mysql_store_result(&gMysql);
1070        if((field=mysql_fetch_row(res)))
1071        {
1072                float fNodeCPUUnits=1.0;
1073                char cfNodeCPUUnits[256];
1074                float fAllContainerCPUUnits=0.0;
1075
1076                if(field[0]==NULL)
1077                {
1078                        printf("No power data available<br>\n");
1079                        goto NextSection2;
1080                }
1081
1082                GetNodeProp(uNode,"vzcpucheck-nodepwr.fCPUUnits",cfNodeCPUUnits);
1083                sscanf(cfNodeCPUUnits,"%f",&fNodeCPUUnits);
1084                sscanf(field[0],"%f",&fAllContainerCPUUnits);
1085                fRatio= (fAllContainerCPUUnits/fNodeCPUUnits) * 100.00 ;
1086                cColor=cRatioColor(&fRatio);
1087                printf("Container/Node power %2.2f%%:"
1088                        " <font color=%s>%2.0f/%2.0f</font><br>\n",
1089                                fRatio,cColor,fAllContainerCPUUnits,fNodeCPUUnits);
1090        }
1091NextSection2:
1092        mysql_free_result(res);
1093
1094        //3-.
1095        //Total RAM utilization http://wiki.openvz.org/UBC_systemwide_configuration
1096        //3a-. All container pages times 4096
1097        sprintf(gcQuery,"SELECT SUM(CONVERT(tProperty.cValue,UNSIGNED)*4096) FROM tProperty,tContainer WHERE"
1098                                " tProperty.cName='physpages.luMaxheld'"
1099                                " AND tProperty.uType=3"//Container type
1100                                " AND tProperty.uKey=tContainer.uContainer"
1101                                " AND tContainer.uStatus!=11"//uINITSETUP==11
1102                                " AND tContainer.uStatus!=31"//uSTOPPED==31
1103                                " AND tContainer.uNode=%u",uNode);
1104        mysql_query(&gMysql,gcQuery);
1105        if(mysql_errno(&gMysql))
1106        {
1107                printf("%s",mysql_error(&gMysql));
1108                return;
1109        }
1110        res=mysql_store_result(&gMysql);
1111        if((field=mysql_fetch_row(res)))
1112        {
1113                if(field[0]!=NULL)
1114                        sscanf(field[0],"%lu",&luAllContainerPhyspages);
1115        }
1116        mysql_free_result(res);
1117        //3b-. All container kmemsize + othersockbuf.luMaxheld + tcpsndbuf.luMaxheld + tcprcvbuf.luMaxheld +
1118        // dgramrcvbuf.luMaxheld
1119        //physpages.luHeld * 4096 needs to also be added from above
1120        sprintf(gcQuery,"SELECT SUM(CONVERT(tProperty.cValue,UNSIGNED)) FROM tProperty,tContainer WHERE"
1121                                " ( tProperty.cName='kmemsize.luMaxheld' OR"
1122                                " tProperty.cName='othersockbuf.luMaxheld' OR "
1123                                " tProperty.cName='tcpsndbuf.luMaxheld' OR "
1124                                " tProperty.cName='tcprcvbuf.luMaxheld' OR "
1125                                " tProperty.cName='dgramrcvbuf.luMaxheld' )"
1126                                //" ( tProperty.cName='kmemsize.luHeld' OR"
1127                                //" tProperty.cName='othersockbuf.luHeld' OR "
1128                                //" tProperty.cName='tcpsndbuf.luHeld' OR "
1129                                //" tProperty.cName='tcprcvbuf.luHeld' OR "
1130                                //" tProperty.cName='dgramrcvbuf.luHeld' )"
1131                                " AND tProperty.uType=3"
1132                                " AND tProperty.uKey=tContainer.uContainer"
1133                                " AND tContainer.uStatus!=11"//Probably active not initial setup
1134                                " AND tContainer.uStatus!=31"// and not stopped
1135                                " AND tContainer.uNode=%u",uNode);
1136        mysql_query(&gMysql,gcQuery);
1137        if(mysql_errno(&gMysql))
1138        {
1139                printf("%s",mysql_error(&gMysql));
1140                return;
1141        }
1142        res=mysql_store_result(&gMysql);
1143        if((field=mysql_fetch_row(res)))
1144        {
1145                if(field[0]!=NULL)
1146                        sscanf(field[0],"%lu",&luAllContainer);
1147        }
1148        mysql_free_result(res);
1149        luTotalRAM=(luAllContainerPhyspages+luAllContainer)/1000;
1150        fRatio= ((float)luTotalRAM/(float)luInstalledRam) * 100.00;
1151                cColor=cRatioColor(&fRatio);
1152                printf("Max RAM Util %2.2f%%:"
1153                        " <font color=%s>%lu/%lu</font><br>\n",
1154                                fRatio,cColor,luTotalRAM,luInstalledRam);
1155
1156        //4-.
1157        //Check all node activity via tProperty
1158        sprintf(gcQuery,"SELECT tNode.cLabel,FROM_UNIXTIME(MAX(tProperty.uModDate)),"
1159                        "(UNIX_TIMESTAMP(NOW()) - MAX(tProperty.uModDate) > 300 ) FROM"
1160                        " tProperty,tNode WHERE tProperty.uKey=tNode.uNode AND"
1161                        " tProperty.uType=2 GROUP BY tProperty.uKey");
1162        mysql_query(&gMysql,gcQuery);
1163        if(mysql_errno(&gMysql))
1164        {
1165                printf("%s",mysql_error(&gMysql));
1166                mysql_free_result(res);
1167                return;
1168        }
1169        res=mysql_store_result(&gMysql);
1170        if(mysql_num_rows(res)>0)
1171                printf("<u>Node Roll Call</u><br>\n");
1172        while((field=mysql_fetch_row(res)))
1173        {
1174                printf("<font color=");
1175                if(field[2][0]=='1')
1176                        printf("red>");
1177                else
1178                        printf("black>");
1179                printf("%s last contact: %s</font><br>\n",field[0],field[1]);
1180        }
1181        mysql_free_result(res);
1182
1183}//void htmlNodeHealth(unsigned uNode)
1184
1185
1186unsigned FailoverCloneContainer(unsigned uDatacenter, unsigned uNode, unsigned uContainer, unsigned uSource,
1187                        unsigned uSourceNode, unsigned uSourceDatacenter, unsigned uIPv4, unsigned uStatus,
1188                        char *cLabel, char *cHostname,unsigned uOwner,unsigned uDebug)
1189{
1190        unsigned uRetVal=2;
1191        unsigned uFailToJob=0;
1192
1193        if((uFailToJob=FailoverToJob(uDatacenter,uNode,uContainer,uOwner,1,uDebug)))
1194        {
1195                if(FailoverFromJob(uSourceDatacenter,uSourceNode,uSource,uIPv4,
1196                                cLabel,cHostname,uContainer,uStatus,uFailToJob,uOwner,1,uDebug))
1197                {
1198                        if(!uDebug)
1199                        {
1200                                SetContainerStatus(uContainer,uAWAITFAIL);
1201                                SetContainerStatus(uSource,uAWAITFAIL);
1202                        }
1203                        uRetVal=0;
1204                }
1205                else
1206                {
1207                        uRetVal=1;
1208                }
1209        }
1210
1211        return(uRetVal);
1212
1213}//unsigned FailoverCloneContainer()
1214
1215
1216//Can return 0,1,2,3 or 4
1217unsigned CloneNode(unsigned uSourceNode,unsigned uTargetNode,unsigned uWizIPv4,const char *cuWizIPv4PullDown,
1218                        unsigned uSyncPeriod,unsigned uCloneStop,unsigned uTargetDatacenter)
1219{
1220        MYSQL_RES *res;
1221        MYSQL_ROW field;
1222        unsigned uContainer=0;
1223        unsigned uDatacenter=0;
1224        unsigned uOSTemplate=0;
1225        unsigned uConfig=0;
1226        unsigned uNameserver=0;
1227        unsigned uSearchdomain=0;
1228        unsigned uNewVeid=0;
1229        unsigned uStatus=0;
1230        unsigned uOwner=0;
1231        unsigned uVeth=0;
1232        unsigned uGroup=0;
1233        char cWizLabel[32]={""};
1234        char cWizHostname[100]={""};
1235
1236
1237        //First lets make sure we have enough IPs available of same class C on target datacenter
1238        //Get container IP cIPv4ClassC
1239        char cIPv4ClassC[32]={""};
1240        int i;
1241        unsigned uIPsAvailable=0;
1242        unsigned uContainers=0;
1243        sprintf(gcQuery,"SELECT cLabel FROM tIP WHERE uIP=%u AND uAvailable=1"
1244                                        " AND uDatacenter=%u",uWizIPv4,uTargetDatacenter);
1245        mysql_query(&gMysql,gcQuery);
1246        if(mysql_errno(&gMysql))
1247                        htmlPlainTextError(mysql_error(&gMysql));
1248        res=mysql_store_result(&gMysql);
1249        if((field=mysql_fetch_row(res)))
1250                sprintf(cIPv4ClassC,"%.31s",field[0]);
1251        else
1252                return(1);
1253        mysql_free_result(res);
1254        for(i=strlen(cIPv4ClassC);i>0;i--)
1255        {
1256                if(cIPv4ClassC[i]=='.')
1257                {
1258                        cIPv4ClassC[i]=0;
1259                        break;
1260                }
1261        }
1262        //Count number of IPs available in same class C
1263        if(guCompany==1)
1264                sprintf(gcQuery,"SELECT COUNT(uIP) FROM tIP WHERE cLabel LIKE '%s.%%' AND uAvailable=1"
1265                                        " AND uDatacenter=%u",cIPv4ClassC,uTargetDatacenter);
1266        else
1267                sprintf(gcQuery,"SELECT COUNT(uIP) FROM tIP WHERE cLabel LIKE '%s.%%' AND uAvailable=1"
1268                                        " AND uOwner=%u AND uDatacenter=%u",cIPv4ClassC,guCompany,uTargetDatacenter);
1269        mysql_query(&gMysql,gcQuery);
1270        if(mysql_errno(&gMysql))
1271                        htmlPlainTextError(mysql_error(&gMysql));
1272        res=mysql_store_result(&gMysql);
1273        if((field=mysql_fetch_row(res)))
1274                sscanf(field[0],"%u",&uIPsAvailable);
1275        else
1276                return(1);
1277        mysql_free_result(res);
1278        //Count number of containers to clone
1279        sprintf(gcQuery,"SELECT COUNT(uContainer) FROM tContainer WHERE uNode=%u AND"
1280                        " (uStatus=%u OR uStatus=%u) AND uSource=0",uSourceNode,uSTOPPED,uACTIVE);
1281        mysql_query(&gMysql,gcQuery);
1282        if(mysql_errno(&gMysql))
1283                        htmlPlainTextError(mysql_error(&gMysql));
1284        res=mysql_store_result(&gMysql);
1285        if((field=mysql_fetch_row(res)))
1286                sscanf(field[0],"%u",&uContainers);
1287        else
1288                return(1);
1289        mysql_free_result(res);
1290        //Test
1291        if(uIPsAvailable<uContainers)
1292        {
1293                char cMsg[100];
1294                sprintf(cMsg,"<blink>Not enough IPs</blink>: uIPsAvailable(%u)&lt;uContainers(%u) for cIPv4ClassC=%s, uOwner=%u",
1295                        uIPsAvailable,uContainers,cIPv4ClassC,guCompany);
1296                tNode(cMsg);
1297        }
1298
1299        sprintf(gcQuery,"SELECT cLabel,cHostname,uOSTemplate,uConfig,uNameserver,uSearchdomain,uDatacenter"
1300                        ",uContainer,uStatus,uOwner,uVeth FROM tContainer WHERE uNode=%u AND"
1301                        " (uStatus=%u OR uStatus=%u) AND uSource=0",uSourceNode,uSTOPPED,uACTIVE);
1302        mysql_query(&gMysql,gcQuery);
1303        if(mysql_errno(&gMysql))
1304                htmlPlainTextError(mysql_error(&gMysql));
1305        res=mysql_store_result(&gMysql);
1306        while((field=mysql_fetch_row(res)))
1307        {
1308                sscanf(field[2],"%u",&uOSTemplate);
1309                sscanf(field[3],"%u",&uConfig);
1310                sscanf(field[4],"%u",&uNameserver);
1311                sscanf(field[5],"%u",&uSearchdomain);
1312                sscanf(field[6],"%u",&uDatacenter);
1313                sscanf(field[7],"%u",&uContainer);
1314                sscanf(field[8],"%u",&uStatus);
1315                sscanf(field[9],"%u",&uOwner);
1316                sscanf(field[10],"%u",&uVeth);
1317
1318                if(!uDatacenter || !uContainer || !uOSTemplate || !uConfig || ! uNameserver ||
1319                                                        !uSearchdomain || !field[0][0] || !field[1][0])
1320                {
1321                        mysql_free_result(res);
1322                        return(1);//unexpected error.
1323                }
1324
1325                uNewVeid=CommonCloneContainer(
1326                                                uContainer,
1327                                                uOSTemplate,
1328                                                uConfig,
1329                                                uNameserver,
1330                                                uSearchdomain,
1331                                                uDatacenter,
1332                                                uTargetDatacenter,
1333                                                uOwner,
1334                                                field[0],
1335                                                uNode,
1336                                                uStatus,
1337                                                field[1],
1338                                                "",//No cClassC
1339                                                uWizIPv4,
1340                                                cWizLabel,
1341                                                cWizHostname,
1342                                                uTargetNode,
1343                                                uSyncPeriod,
1344                                                guLoginClient,
1345                                                uCloneStop,1);//uMode 1 tNode errors
1346                if(!uNewVeid)
1347                {
1348                        mysql_free_result(res);
1349                        return(2);//unexpected error from CommonCloneContainer)(.
1350                }
1351                SetContainerStatus(uContainer,uStatus);//undo CommonCloneContainer() set
1352                uGroup=uGetGroup(0,uContainer);
1353                if(uGroup) ChangeGroup(uNewVeid,uGroup);
1354
1355                //debug only
1356                //tNode(cWizHostname);
1357        }
1358        mysql_free_result(res);
1359
1360        return(0);
1361
1362}//unsigned CloneNode()
Note: See TracBrowser for help on using the browser.