root/trunk/tcontainerfunc.h

Revision 1928, 238.5 KB (checked in by Dylan, 3 weeks ago)

unxsVZ ExecuteCommands? and support for cHostname lists have been added to the search set tContainer page and alpha tested.

  • Property svn:keywords set to id
Line 
1/*
2FILE
3        $Id$
4        (Built initially by unixservice.com mysqlRAD2)
5PURPOSE
6        Non schema-dependent table and application table related functions.
7AUTHOR/LEGAL
8        (C) 2001-2010 Gary Wallis for Unixservice, LLC.
9        GPLv2 license applies. See LICENSE file included.
10NOTES
11        mySQL 5.0+ now required
12USEFUL SQL
13        //Clean up SQL (rules/constraints) that should never be needed once code is stable.
14        DELETE FROM tProperty WHERE uType=3 AND uKey NOT IN (SELECT uContainer FROM tContainer);
15        UPDATE tIP SET uAvailable=1 WHERE uAvailable=0 AND uIP NOT IN (SELECT uIPv4 FROM tContainer);
16*/
17
18#define macro_mySQLQueryExitText        mysql_query(&gMysql,gcQuery);\
19                                        if(mysql_errno(&gMysql))\
20                                        {\
21                                                printf("%s\n",mysql_error(&gMysql));\
22                                                exit(1);\
23                                        }\
24                                        mysqlRes=mysql_store_result(&gMysql);
25
26struct structContainer
27{
28        char cLabel[32];
29        char cHostname[64];
30        unsigned uVeth;
31        unsigned uSource;
32        unsigned uIPv4;
33        unsigned uOSTemplate;
34        unsigned uConfig;
35        unsigned uNameserver;
36        unsigned uSearchdomain;
37        unsigned uDatacenter;
38        unsigned uNode;
39        unsigned uStatus;
40        unsigned uOwner;
41        unsigned uCreatedBy;
42        unsigned long uCreatedDate;
43        unsigned uModBy;
44        unsigned long uModDate;
45};
46void GetContainerProps(unsigned uContainer,struct structContainer *sContainer);
47void GetDatacenterProp(const unsigned uDatacenter,const char *cName,char *cValue);
48void GetNodeProp(const unsigned uNode,const char *cName,char *cValue);
49void InitContainerProps(struct structContainer *sContainer);
50unsigned uGetGroup(unsigned uNode, unsigned uContainer);
51unsigned uGetSearchGroup(const char *gcUser);
52unsigned unxsBindARecordJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,const char *cJobData,
53                unsigned uOwner,unsigned uCreatedBy);
54void ChangeGroup(unsigned uContainer, unsigned uGroup);
55static unsigned uHideProps=0;
56static unsigned uTargetNode=0;
57static char cuTargetNodePullDown[256]={""};
58static unsigned guCloneTargetNode=0;
59static char cuCloneTargetNodePullDown[256]={""};
60static unsigned uTargetDatacenter=0;
61static char cuTargetDatacenterPullDown[256]={""};
62static unsigned uMountTemplate=0;
63static char cuTemplateDropDown[256]={""};
64static char cConfigLabel[32]={""};
65static char cWizHostname[100]={""};
66static char cWizLabel[32]={""};
67static char cService1[32]={""};//Also used for optional container password
68static char cService2[32]={""};
69static char cService3[32]={""};
70static char cService4[32]={""};
71static char cPrivateIPs[64]={""};
72static char gcIPv4[16]={""};
73static char cNetmask[64]={""};
74static unsigned uWizIPv4=0;
75static char cuWizIPv4PullDown[32]={""};
76static unsigned uWizContainer=0;
77static char cuWizContainerPullDown[32]={""};
78static unsigned uAllPortsOpen=0;
79static unsigned uCloneStop=WARM_CLONE;
80static unsigned uSyncPeriod=0;
81static unsigned guSameNode=0;//Same node as right loaded container uNode.
82static unsigned guNoClones=0;
83static unsigned guOpOnClones=0;
84static unsigned guInitOnly=0;
85static char cSearch[32]={""};
86//static unsigned uGroupJobs=0;
87//uGroup: Group type association
88static unsigned uGroup=0;
89static char cuGroupPullDown[256]={""};
90static unsigned uChangeGroup=0;
91static char ctContainerGroupPullDown[256]={""};
92//uForClient: Create for, on 'New;
93static unsigned uForClient=0;
94static unsigned uCreateDNSJob=0;
95static char cForClientPullDown[256]={""};
96
97//ModuleFunctionProtos()
98void tContainerNavList(unsigned uNode, char *cSearch);//uNode is really a node mode
99unsigned CreateNewContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner);
100unsigned CreateStartContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner);
101unsigned DestroyContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner);
102unsigned StopContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner);
103unsigned CancelContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uCancelMode);
104void SetContainerStatus(unsigned uContainer,unsigned uStatus);
105void SetContainerNode(unsigned uContainer,unsigned uNode);
106void SetContainerDatacenter(unsigned uContainer,unsigned uDatacenter);
107void htmlContainerNotes(unsigned uContainer);
108void htmlContainerMount(unsigned uContainer);
109unsigned MigrateContainerJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer, unsigned uTargetNode,
110                        unsigned uOwner, unsigned uLoginClient, unsigned uIPv4,unsigned uPrevStatus);
111unsigned CloneContainerJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer,
112                                unsigned uTargetNode, unsigned uNewVeid, unsigned uPrevStatus,
113                                unsigned uOwner,unsigned uCreatedBy,unsigned uCloneStop);
114void htmlHealth(unsigned uContainer,unsigned uType);
115void htmlGroups(unsigned uNode, unsigned uContainer);
116unsigned TemplateContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uStatus,
117                unsigned uOwner,char *cConfigLabel);
118unsigned HostnameContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,char *cPrevHostname,unsigned uOwner,unsigned uLoginClient);
119unsigned IPContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,
120                        unsigned uOwner,unsigned uLoginClient,char const *cIPOld);
121unsigned IPSameNodeContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer1,unsigned uContainer2,
122                        unsigned uOwner,unsigned uLoginClient,char const *cIPOld1,char const *cIPOld2);
123unsigned ActionScriptsJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer);
124char *cRatioColor(float *fRatio);
125void htmlGenMountInputs(unsigned const uMountTemplate);
126unsigned uCheckMountSettings(unsigned uMountTemplate);
127void htmlMountTemplateSelect(unsigned uSelector);
128void AddMountProps(unsigned uContainer);
129void CopyContainerProps(unsigned uSource, unsigned uTarget);
130//These two jobs are always done in pairs. Even though the second may run much later
131//for example after hardware failure has been fixed.
132unsigned FailoverToJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer,unsigned uOwner,unsigned uLoginClient,unsigned uDebug);
133unsigned FailoverFromJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,
134                                unsigned uIPv4,char *cLabel,char *cHostname,unsigned uSource,
135                                unsigned uStatus,unsigned uFailToJob,unsigned uOwner,unsigned uLoginClient,unsigned uDebug);
136void htmlCloneInfo(unsigned uContainer);
137void CreateDNSJob(unsigned uIPv4,unsigned uOwner,char const *cOptionalIPv4,
138                        char const *cHostname,unsigned uDatacenter,unsigned uCreatedBy);
139unsigned CreateExecuteCommandsJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner,char *cCommands);
140
141//extern
142void GetNodeProp(const unsigned uNode,const char *cName,char *cValue);//jobqueue.c
143void DelProperties(unsigned uNode,unsigned uType);//tnodefunc.h
144
145#include <openisp/ucidr.h>
146#include <ctype.h>
147
148void htmlGenMountInputs(unsigned const uMountTemplate)
149{
150        char *cService1;
151        char *cService2;
152        char *cService3;
153        char *cService4;
154
155        cService1="";
156        cService2="";
157        cService3="";
158        cService4="";
159
160        printf("Fill in according to template and container purpose."
161                " If not sure leave blank or with suggested default value.\n");
162        if(strstr(cuTemplateDropDown,"dns"))
163        {
164                cService1="53";
165        }
166        else if(strstr(cuTemplateDropDown,"web"))
167        {
168                cService1="80";
169                cService2="443";
170        }
171        else if(strstr(cuTemplateDropDown,"mailstore"))
172        {
173                cService1="25";
174                cService2="995";
175                cService3="110";
176        }
177        else if(strstr(cuTemplateDropDown,"mx"))
178        {
179                cService1="25";
180                cService2="587";
181        }
182        else if(strstr(cuTemplateDropDown,"smtp"))
183        {
184                cService1="25";
185                cService2="587";
186        }
187        else if(strstr(cuTemplateDropDown,"mysql"))
188        {
189                cService1="3306";
190        }
191        else if(strstr(cuTemplateDropDown,"open"))
192        {
193                uAllPortsOpen=1;
194                printf("<p>All ports open for uIPv4 container IP.");
195        }
196
197        if(!uAllPortsOpen)
198        {
199                printf("<p><input type=text name=cService1 value='%s'> Service1 Port<br>",cService1);
200                printf("<input type=text name=cService2 value='%s'> Service2 Port<br>",cService2);
201                printf("<input type=text name=cService3 value='%s'> Service3 Port<br>",cService3);
202                printf("<input type=text name=cService4 value='%s'> Service4 Port<br>",cService4);
203        }
204        if(strstr(cuTemplateDropDown,"VE"))
205        {
206                printf("<p>DNAT/SNAT Mount Settings<p>Public or datacenter private IP<br>");
207                tTablePullDownAvail("tIP;cuWizIPv4PullDown","cLabel","cLabel",uWizIPv4,1);
208                printf("<br>Netmask for IP above<br>\n");
209                printf("<input type=text name=cNetmask value='255.255.255.0'>");
210                printf("<br>Datacenter wide private IP CIDR block<br>");
211                printf("<input type=text name=cPrivateIPs value='10.0.0.0/24'>\n");
212        }
213
214}//void htmlGenMountInputs(unsigned const uMountTemplate)
215
216
217unsigned uCheckMountSettings(unsigned uMountTemplate)
218{
219
220        //No mount/firewall option
221        if(!uMountTemplate)
222                return(0);
223
224        if(!cuTemplateDropDown[0] && uMountTemplate)
225        {
226                MYSQL_RES *res;
227                MYSQL_ROW field;
228
229                sprintf(gcQuery,"SELECT cLabel FROM tTemplate WHERE uTemplate=%u",uMountTemplate);
230                mysql_query(&gMysql,gcQuery);
231                if(mysql_errno(&gMysql))
232                        htmlPlainTextError(mysql_error(&gMysql));
233                res=mysql_store_result(&gMysql);
234                if((field=mysql_fetch_row(res)))
235                        sprintf(cuTemplateDropDown,"%.99s",field[0]);   
236                mysql_free_result(res);
237                if(strstr(cuTemplateDropDown,"open"))
238                        uAllPortsOpen=1;
239        }
240
241        //Very basic check...add the rest TODO
242        if(uWizIPv4 || uAllPortsOpen)
243                return(0);
244        else
245                return(1);
246
247}//unsigned uCheckMountSettings(unsigned uMountTemplate)
248
249
250void ExtProcesstContainerVars(pentry entries[], int x)
251{
252        register int i;
253
254        for(i=0;i<x;i++)
255        {
256                //Some of these must go before group Ct operations
257                if(!strcmp(entries[i].name,"cSearch"))
258                {
259                        sprintf(cSearch,"%.31s",TextAreaSave(entries[i].val));
260                }
261                else if(!strcmp(entries[i].name,"uGroup"))
262                {
263                        sscanf(entries[i].val,"%u",&uGroup);
264                }
265                else if(!strcmp(entries[i].name,"cuGroupPullDown"))
266                {
267                        sprintf(cuGroupPullDown,"%.255s",entries[i].val);
268                        uGroup=ReadPullDown("tGroup","cLabel",cuGroupPullDown);
269                }
270                else if(!strcmp(entries[i].name,"ctContainerGroupPullDown"))
271                {
272                        sprintf(ctContainerGroupPullDown,"%.255s",entries[i].val);
273                        uChangeGroup=ReadPullDown("tGroup","uGroupType=1 AND cLabel",ctContainerGroupPullDown);
274                        uGroup=uChangeGroup;//For legacy support TODO
275                }
276                else if(!strcmp(entries[i].name,"guOpOnClonesNoCA"))
277                {
278                        guOpOnClones=1;
279                }
280                else if(!strncmp(entries[i].name,"Ct",2))
281                {
282                        //insider xss protection
283                        if(guPermLevel<10)
284                                continue;
285
286                        unsigned uCtContainer=0;
287                        sscanf(entries[i].name,"Ct%u",&uCtContainer);
288                        if(uCtContainer)
289                        {
290                                if(!strcmp(gcFunction,"tContainerTools"))
291                                {
292                                        ;
293                                }
294                        }
295                }
296                else if(!strcmp(entries[i].name,"guSameNode"))
297                {
298                        guSameNode=1;
299                }
300                else if(!strcmp(entries[i].name,"guNoClones"))
301                {
302                        guNoClones=1;
303                }
304                else if(!strcmp(entries[i].name,"guInitOnly"))
305                {
306                        guInitOnly=1;
307                }
308                else if(!strcmp(entries[i].name,"cuTargetNodePullDown"))
309                {
310                        sprintf(cuTargetNodePullDown,"%.255s",entries[i].val);
311                        uTargetNode=ReadPullDown("tNode","cLabel",cuTargetNodePullDown);
312                }
313                else if(!strcmp(entries[i].name,"cuCloneTargetNodePullDown"))
314                {
315                        sprintf(cuCloneTargetNodePullDown,"%.255s",entries[i].val);
316                        guCloneTargetNode=ReadPullDown("tNode","cLabel",cuCloneTargetNodePullDown);
317                }
318                else if(!strcmp(entries[i].name,"cuTargetDatacenterPullDown"))
319                {
320                        sprintf(cuTargetDatacenterPullDown,"%.255s",entries[i].val);
321                        uTargetDatacenter=ReadPullDown("tDatacenter","cLabel",cuTargetDatacenterPullDown);
322                }
323                else if(!strcmp(entries[i].name,"MountTemplateSelect"))
324                {
325                        sprintf(cuTemplateDropDown,"%.255s",entries[i].val);
326                        uMountTemplate=ReadPullDown("tTemplate","cLabel",cuTemplateDropDown);
327                }
328                else if(!strcmp(entries[i].name,"uMountTemplate"))
329                {
330                        sscanf(entries[i].val,"%u",&uMountTemplate);
331                }
332                else if(!strcmp(entries[i].name,"uCreateDNSJob"))
333                {
334                        uCreateDNSJob=1;
335                }
336                else if(!strcmp(entries[i].name,"uCloneStop"))
337                {
338                        sscanf(entries[i].val,"%u",&uCloneStop);
339                }
340                else if(!strcmp(entries[i].name,"uSyncPeriod"))
341                {
342                        sscanf(entries[i].val,"%u",&uSyncPeriod);
343                }
344                else if(!strcmp(entries[i].name,"cConfigLabel"))
345                {
346                        sprintf(cConfigLabel,"%.31s",WordToLower(entries[i].val));
347                }
348                else if(!strcmp(entries[i].name,"cWizLabel"))
349                {
350                        sprintf(cWizLabel,"%.31s",WordToLower(entries[i].val));
351                }
352                else if(!strcmp(entries[i].name,"cWizHostname"))
353                {
354                        sprintf(cWizHostname,"%.99s",WordToLower(entries[i].val));
355                }
356                else if(!strcmp(entries[i].name,"cService1"))
357                {
358                        sprintf(cService1,"%.31s",entries[i].val);
359                }
360                else if(!strcmp(entries[i].name,"cService2"))
361                {
362                        sprintf(cService2,"%.31s",entries[i].val);
363                }
364                else if(!strcmp(entries[i].name,"cService3"))
365                {
366                        sprintf(cService3,"%.31s",entries[i].val);
367                }
368                else if(!strcmp(entries[i].name,"cService4"))
369                {
370                        sprintf(cService4,"%.31s",entries[i].val);
371                }
372                else if(!strcmp(entries[i].name,"cNetmask"))
373                {
374                        sprintf(cNetmask,"%.63s",entries[i].val);
375                }
376                else if(!strcmp(entries[i].name,"cPrivateIPs"))
377                {
378                        sprintf(cPrivateIPs,"%.63s",entries[i].val);
379                }
380                else if(!strcmp(entries[i].name,"gcIPv4"))
381                {
382                        sprintf(gcIPv4,"%.15s",IPNumber(entries[i].val));
383                }
384                else if(!strcmp(entries[i].name,"cuWizIPv4PullDown"))
385                {
386                        sprintf(cuWizIPv4PullDown,"%.31s",entries[i].val);
387                        uWizIPv4=ReadPullDown("tIP","cLabel",cuWizIPv4PullDown);
388                }
389                else if(!strcmp(entries[i].name,"cForClientPullDown"))
390                {
391                        sprintf(cForClientPullDown,"%.255s",entries[i].val);
392                        uForClient=ReadPullDown("tClient","cLabel",cForClientPullDown);
393                }
394                else if(!strcmp(entries[i].name,"cuWizContainerPullDown"))
395                {
396                        sprintf(cuWizContainerPullDown,"%.31s",entries[i].val);
397                        uWizContainer=ReadPullDown("tContainer","cLabel",cuWizContainerPullDown);
398                }
399                else if(!strcmp(entries[i].name,"cHostnameSearch"))
400                {
401                        sprintf(cHostnameSearch,"%.99s",entries[i].val);
402                }
403                else if(!strcmp(entries[i].name,"cIPv4Search"))
404                {
405                        sprintf(cIPv4Search,"%.15s",entries[i].val);
406                }
407        }
408
409}//void ExtProcesstContainerVars(pentry entries[], int x)
410
411
412void ExttContainerCommands(pentry entries[], int x)
413{
414        MYSQL_RES *res;
415
416        if(!strcmp(gcFunction,"tContainerTools"))
417        {
418                unsigned uIPv4Datacenter=0;
419                unsigned uNodeDatacenter=0;
420                time_t uActualModDate= -1;
421                char cContainerType[256]={""};
422                char cNCMDatacenter[256]={""};
423                char cNCMNode[256]={""};
424                char cNCCloneRange[256]={""};
425
426                uHideProps=1;
427
428                if(!strcmp(gcCommand,LANG_NB_NEW))
429                {
430                        if(guPermLevel>=9)
431                        {
432                                ProcesstContainerVars(entries,x);
433                                guMode=9001;
434                                tContainer("New container step 1");
435                        }
436                        else
437                        {
438                                tContainer("<blink>Error:</blink> Denied by permissions settings");
439                        }
440                }
441                else if(!strcmp(gcCommand,"Reload Search Set"))
442                {
443                        if(guPermLevel>=9)
444                        {
445                                ProcesstContainerVars(entries,x);
446                                guMode=12002;
447                                tContainer("Search set reloaded");
448                        }
449                        else
450                        {
451                                tContainer("<blink>Error:</blink> Denied by permissions settings");
452                        }
453                }
454                else if(!strcmp(gcCommand,"Remove from Search Set"))
455                {
456                        if(guPermLevel>=9)
457                        {
458                                ProcesstContainerVars(entries,x);
459                                guMode=12002;
460                                char cQuerySection[256];
461                                unsigned uLink=0;
462                                unsigned uNumber=0;
463
464                                if((uGroup=uGetSearchGroup(gcUser))==0)
465                                        tContainer("No search set exists. Please create one first.");
466
467                                //We extend to this other optional list and ignore the other filter items
468                                if(cCommands[0])
469                                {
470                                        register int i,j;
471                                        char cHostname[64];
472
473                                        for(i=0,j=0;cCommands[i];i++)
474                                        {
475                                                if( isspace(cCommands[i]) || cCommands[i]==';' || cCommands[i]=='#' || j>62)
476                                                {
477                                                        cHostname[j]=0;
478                                                        j=0;
479
480                                                        sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uGroup=%u AND uContainer IN"
481                                                                        " (SELECT uContainer FROM tContainer WHERE cHostname='%s')",
482                                                                                uGroup,cHostname);
483                                                        mysql_query(&gMysql,gcQuery);
484                                                        if(mysql_errno(&gMysql))
485                                                                htmlPlainTextError(mysql_error(&gMysql));
486                                                        uNumber+=mysql_affected_rows(&gMysql);
487
488                                                        for(;cCommands[i];i++)
489                                                        {
490                                                                //jump to next line
491                                                                if( cCommands[i]=='\n' || cCommands[i]=='\r')
492                                                                        break;
493                                                        }
494                                                }
495                                                else
496                                                {
497                                                        cHostname[j++]=cCommands[i];
498                                                }
499                                        }
500                                        //Last line case
501                                        sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uGroup=%u AND uContainer IN"
502                                                                " (SELECT uContainer FROM tContainer WHERE cHostname='%s')",
503                                                                        uGroup,cHostname);
504                                        mysql_query(&gMysql,gcQuery);
505                                        if(mysql_errno(&gMysql))
506                                                htmlPlainTextError(mysql_error(&gMysql));
507                                        uNumber+=mysql_affected_rows(&gMysql);
508
509                                        sprintf(gcQuery,"%u container records removed via cHostname list",uNumber);
510                                        tContainer(gcQuery);
511                                }//if(cCommands[0])
512
513                                if(cHostnameSearch[0]==0 && cIPv4Search[0]==0 && uDatacenter==0 && uNode==0 && uSearchStatus==0
514                                                && uForClient==0 && uOSTemplate==0)
515                                        tContainer("You must specify at least one search parameter");
516
517
518                                //Initial query section
519                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uGroup=%u AND uContainer IN"
520                                                " (SELECT uContainer FROM tContainer WHERE",uGroup);
521
522                                //Build AND query section
523                                if(cHostnameSearch[0])
524                                {
525                                        sprintf(cQuerySection," cHostname LIKE '%s%%'",cHostnameSearch);
526                                        strcat(gcQuery,cQuerySection);
527                                        uLink=1;
528                                }
529                                else
530                                {
531                                        uLink=0;
532                                }
533
534                                if(cIPv4Search[0])
535                                {
536                                        if(uLink)
537                                                strcat(gcQuery," AND");
538                                        sprintf(cQuerySection," uIPv4 IN (SELECT uIP FROM tIP WHERE cLabel LIKE '%s%%')",cIPv4Search);
539                                        strcat(gcQuery,cQuerySection);
540                                        uLink=1;
541                                }
542
543                                if(uDatacenter)
544                                {
545                                        if(uLink)
546                                                strcat(gcQuery," AND");
547                                        sprintf(cQuerySection," uDatacenter=%u",uDatacenter);
548                                        strcat(gcQuery,cQuerySection);
549                                        uLink=1;
550                                }
551
552                                if(uNode)
553                                {
554                                        if(uLink)
555                                                strcat(gcQuery," AND");
556                                        sprintf(cQuerySection," uNode=%u",uNode);
557                                        strcat(gcQuery,cQuerySection);
558                                        uLink=1;
559                                }
560
561                                if(uSearchStatus)
562                                {
563                                        if(uLink)
564                                                strcat(gcQuery," AND");
565                                        if(uSearchStatusNot)
566                                                sprintf(cQuerySection," uStatus!=%u",uSearchStatus);
567                                        else
568                                                sprintf(cQuerySection," uStatus=%u",uSearchStatus);
569                                        strcat(gcQuery,cQuerySection);
570                                        uLink=1;
571                                }
572
573                                //Clone YesNo tristate
574                                if(uSearchSource)
575                                {
576                                        if(uLink)
577                                                strcat(gcQuery," AND");
578                                        if(uSearchSource==2)//Tri state Yes
579                                                sprintf(cQuerySection," uSource>0");
580                                        else
581                                                sprintf(cQuerySection," uSource=0");
582                                        strcat(gcQuery,cQuerySection);
583                                        uLink=1;
584                                }
585
586                                if(uOSTemplate)
587                                {
588                                        if(uLink)
589                                                strcat(gcQuery," AND");
590                                        sprintf(cQuerySection," uOSTemplate=%u",uOSTemplate);
591                                        strcat(gcQuery,cQuerySection);
592                                        uLink=1;
593                                }
594
595                                if(uForClient)
596                                {
597                                        if(uLink)
598                                                strcat(gcQuery," AND");
599                                        sprintf(cQuerySection," uOwner=%u",uForClient);
600                                        strcat(gcQuery,cQuerySection);
601                                        uLink=1;
602                                }
603
604                                strcat(gcQuery,")");
605                                //debug only
606                                //tContainer(gcQuery);
607
608                                mysql_query(&gMysql,gcQuery);
609                                if(mysql_errno(&gMysql))
610                                                htmlPlainTextError(mysql_error(&gMysql));
611                                if((uNumber=mysql_affected_rows(&gMysql))>0)
612                                {
613                                        sprintf(gcQuery,"%u container records were removed from your search set",uNumber);
614                                        tContainer(gcQuery);
615                                }
616                                else
617                                {
618                                        tContainer("No records were removed from your search set");
619                                }
620                        }
621                        else
622                        {
623                                tContainer("<blink>Error:</blink> Denied by permissions settings");
624                        }
625                }
626                else if(!strcmp(gcCommand,"Add to Search Set") || !strcmp(gcCommand,"Create Search Set"))
627                {
628                        if(guPermLevel>=9)
629                        {
630                                ProcesstContainerVars(entries,x);
631                                guMode=12002;
632                                char cQuerySection[256];
633                                unsigned uLink=0;
634                                unsigned uNumber=0;
635
636                                if(cHostnameSearch[0]==0 && cIPv4Search[0]==0 && uDatacenter==0 && uNode==0 && uSearchStatus==0
637                                                && uForClient==0 && uOSTemplate==0 && cCommands[0]==0)
638                                        tContainer("You must specify at least one search parameter");
639
640                                if((uGroup=uGetSearchGroup(gcUser))==0)
641                                {
642                                        sprintf(gcQuery,"INSERT INTO tGroup SET cLabel='%s',uGroupType=2"//2 is search group
643                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
644                                                        gcUser,guCompany,guLoginClient);//2=search set type TODO
645                                        mysql_query(&gMysql,gcQuery);
646                                        if(mysql_errno(&gMysql))
647                                                        htmlPlainTextError(mysql_error(&gMysql));
648                                        if((uGroup=mysql_insert_id(&gMysql))==0)
649                                                tContainer("An error ocurred when attempting to create your search set");
650                                }
651                                else
652                                {
653                                        if(!strcmp(gcCommand,"Create Search Set"))
654                                        {
655                                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uGroup=%u",uGroup);
656                                                mysql_query(&gMysql,gcQuery);
657                                                if(mysql_errno(&gMysql))
658                                                        htmlPlainTextError(mysql_error(&gMysql));
659                                        }
660                                }
661
662                                //We extend to this other optional list and ignore the other filter items
663                                if(cCommands[0])
664                                {
665                                        register int i,j;
666                                        char cHostname[64];
667
668                                        for(i=0,j=0;cCommands[i];i++)
669                                        {
670                                                if( isspace(cCommands[i]) || cCommands[i]==';' || cCommands[i]=='#' || j>62)
671                                                {
672                                                        cHostname[j]=0;
673                                                        j=0;
674
675                                                        sprintf(gcQuery,"INSERT INTO tGroupGlue (uGroup,uContainer)"
676                                                                        " SELECT %u,uContainer FROM tContainer WHERE cHostname='%s'",
677                                                                                                uGroup,cHostname);
678                                                        mysql_query(&gMysql,gcQuery);
679                                                        if(mysql_errno(&gMysql))
680                                                                htmlPlainTextError(mysql_error(&gMysql));
681                                                        uNumber+=mysql_affected_rows(&gMysql);
682
683                                                        for(;cCommands[i];i++)
684                                                        {
685                                                                //jump to next line
686                                                                if( cCommands[i]=='\n' || cCommands[i]=='\r')
687                                                                        break;
688                                                        }
689                                                }
690                                                else
691                                                {
692                                                        cHostname[j++]=cCommands[i];
693                                                }
694                                        }
695                                        //Last line case
696                                        sprintf(gcQuery,"INSERT INTO tGroupGlue (uGroup,uContainer)"
697                                                        " SELECT %u,uContainer FROM tContainer WHERE cHostname='%s'",
698                                                                                                uGroup,cHostname);
699                                        mysql_query(&gMysql,gcQuery);
700                                        if(mysql_errno(&gMysql))
701                                                htmlPlainTextError(mysql_error(&gMysql));
702                                        uNumber+=mysql_affected_rows(&gMysql);
703
704                                        sprintf(gcQuery,"%u container records added via cHostname list",uNumber);
705                                        tContainer(gcQuery);
706                                }//if(cCommands[0])
707
708                                //Initial query section
709                                sprintf(gcQuery,"INSERT INTO tGroupGlue (uGroupGlue,uGroup,uNode,uContainer)"
710                                                " SELECT 0,%u,0,uContainer FROM tContainer WHERE",uGroup);
711
712                                //Build AND query section
713
714                                if(cHostnameSearch[0])
715                                {
716                                        sprintf(cQuerySection," cHostname LIKE '%s%%'",cHostnameSearch);
717                                        strcat(gcQuery,cQuerySection);
718                                        uLink=1;
719                                }
720                                else
721                                {
722                                        uLink=0;
723                                }
724
725                                if(cIPv4Search[0])
726                                {
727                                        if(uLink)
728                                                strcat(gcQuery," AND");
729                                        sprintf(cQuerySection," uIPv4 IN (SELECT uIP FROM tIP WHERE cLabel LIKE '%s%%')",cIPv4Search);
730                                        strcat(gcQuery,cQuerySection);
731                                        uLink=1;
732                                }
733
734                                if(uDatacenter)
735                                {
736                                        if(uLink)
737                                                strcat(gcQuery," AND");
738                                        sprintf(cQuerySection," uDatacenter=%u",uDatacenter);
739                                        strcat(gcQuery,cQuerySection);
740                                        uLink=1;
741                                }
742
743                                if(uNode)
744                                {
745                                        if(uLink)
746                                                strcat(gcQuery," AND");
747                                        sprintf(cQuerySection," uNode=%u",uNode);
748                                        strcat(gcQuery,cQuerySection);
749                                        uLink=1;
750                                }
751
752                                if(uSearchStatus)
753                                {
754                                        if(uLink)
755                                                strcat(gcQuery," AND");
756                                        if(uSearchStatusNot)
757                                                sprintf(cQuerySection," uStatus!=%u",uSearchStatus);
758                                        else
759                                                sprintf(cQuerySection," uStatus=%u",uSearchStatus);
760                                        strcat(gcQuery,cQuerySection);
761                                        uLink=1;
762                                }
763
764                                //Clone YesNo tristate
765                                if(uSearchSource)
766                                {
767                                        if(uLink)
768                                                strcat(gcQuery," AND");
769                                        if(uSearchSource==2)//Tri state Yes
770                                                sprintf(cQuerySection," uSource>0");
771                                        else
772                                                sprintf(cQuerySection," uSource=0");
773                                        strcat(gcQuery,cQuerySection);
774                                        uLink=1;
775                                }
776
777                                if(uOSTemplate)
778                                {
779                                        if(uLink)
780                                                strcat(gcQuery," AND");
781                                        sprintf(cQuerySection," uOSTemplate=%u",uOSTemplate);
782                                        strcat(gcQuery,cQuerySection);
783                                        uLink=1;
784                                }
785
786                                if(uForClient)
787                                {
788                                        if(uLink)
789                                                strcat(gcQuery," AND");
790                                        sprintf(cQuerySection," uOwner=%u",uForClient);
791                                        strcat(gcQuery,cQuerySection);
792                                        uLink=1;
793                                }
794
795                                //debug only
796                                //tContainer(gcQuery);
797
798                                mysql_query(&gMysql,gcQuery);
799                                if(mysql_errno(&gMysql))
800                                                htmlPlainTextError(mysql_error(&gMysql));
801                                if((uNumber=mysql_affected_rows(&gMysql))>0)
802                                {
803                                        sprintf(gcQuery,"%u container records were added to your search set",uNumber);
804                                        tContainer(gcQuery);
805                                }
806                                else
807                                {
808                                        tContainer("No records were added to your search set. Filter returned 0 records");
809                                }
810                        }
811                        else
812                        {
813                                tContainer("<blink>Error:</blink> Denied by permissions settings");
814                        }
815                }
816                else if(!strcmp(gcCommand,"Search Set Operations"))
817                {
818                        if(guPermLevel>=9)
819                        {
820                                ProcesstContainerVars(entries,x);
821                                guMode=12001;
822                                tContainer("Search Set Operations");
823                        }
824                        else
825                        {
826                                tContainer("<blink>Error:</blink> Denied by permissions settings");
827                        }
828                }
829                else if(!strcmp(gcCommand,"Select Datacenter/Org"))
830                {
831                        if(guPermLevel>=9)
832                        {
833                                ProcesstContainerVars(entries,x);
834                                guMode=9001;
835                                if(!uDatacenter)
836                                        tContainer("<blink>Error:</blink> Must select a datacenter.");
837                                GetDatacenterProp(uDatacenter,"NewContainerMode",cNCMDatacenter);
838                                if(cNCMDatacenter[0] && !strstr(cNCMDatacenter,"Active"))
839                                        tContainer("<blink>Error:</blink> Selected datacenter is full or not active. Select another.");
840                                if(!uForClient)
841                                        tContainer("<blink>Error:</blink> Must select an organization"
842                                                        " (company, NGO or similar.)");
843
844                                guMode=9002;
845                                tContainer("New container step 2");
846                        }
847                        else
848                        {
849                                tContainer("<blink>Error:</blink> Denied by permissions settings");
850                        }
851                }
852                else if(!strcmp(gcCommand,"Select Node"))
853                {
854                        if(guPermLevel>=9)
855                        {
856                                ProcesstContainerVars(entries,x);
857                                guMode=9002;
858                                if(!uDatacenter)
859                                        tContainer("<blink>Error:</blink> Must select a datacenter.");
860                                if(!uForClient)
861                                        tContainer("<blink>Error:</blink> Must select an organization"
862                                                        " (company, NGO or similar.)");
863                                if(!uNode)
864                                        tContainer("<blink>Error:</blink> Must select a node.");
865
866                                GetDatacenterProp(uDatacenter,"NewContainerMode",cNCMDatacenter);
867                                if(cNCMDatacenter[0] && !strstr(cNCMDatacenter,"Active"))
868                                        tContainer("<blink>Error:</blink> Selected datacenter is full or not active. Select another.");
869
870                                GetNodeProp(uNode,"NewContainerMode",cNCMNode);
871                                if(cNCMNode[0] && !strstr(cNCMNode,"Active"))
872                                        tContainer("<blink>Error:</blink> Selected node is not configured for active containers."
873                                                        "Select another.");
874
875                                guMode=9003;
876                                tContainer("New container step 3");
877                        }
878                        else
879                        {
880                                tContainer("<blink>Error:</blink> Denied by permissions settings");
881                        }
882                }
883                else if(!strcmp(gcCommand,"Cancel"))
884                {
885                        guMode=0;
886                }
887                else if(!strcmp(gcCommand,"Single Container Creation") || !strcmp(gcCommand,"Appliance Creation"))
888                {
889                        if(guPermLevel>=9)
890                        {
891                                MYSQL_ROW field;
892                                unsigned uNewVeid=0;
893                                register int i;
894                                char cIPv4ClassC[32]={""};
895                                char cIPv4ClassCClone[32]={""};
896                                unsigned uAvailableIPs=0;
897                                unsigned uHostnameLen=0;
898                                unsigned uLabelLen=0;
899                                unsigned uCreateAppliance=0;
900
901                                ProcesstContainerVars(entries,x);
902
903                                if(!strcmp(gcCommand,"Appliance Creation"))
904                                        uCreateAppliance=1;
905
906                                guMode=9003;
907                                //Check entries here
908                                if(uDatacenter==0)
909                                        tContainer("<blink>Error:</blink> Unexpected uDatacenter==0!");
910                                if(uNode==0)
911                                        tContainer("<blink>Error:</blink> Unexpected uNode==0!");
912
913                                GetDatacenterProp(uDatacenter,"NewContainerMode",cNCMDatacenter);
914                                if(cNCMDatacenter[0] && !strstr(cNCMDatacenter,"Active"))
915                                        tContainer("<blink>Error:</blink> Selected datacenter is full or not active. Select another.");
916
917                                GetNodeProp(uNode,"NewContainerMode",cNCMNode);
918                                if(cNCMNode[0] && !strstr(cNCMNode,"Active"))
919                                        tContainer("<blink>Error:</blink> Selected node is not configured for active containers."
920                                                        "Select another.");
921
922                                if((uLabelLen=strlen(cLabel))<2)
923                                        tContainer("<blink>Error:</blink> cLabel is too short");
924                                if(strchr(cLabel,'.'))
925                                        tContainer("<blink>Error:</blink> cLabel has at least one '.'");
926                                if(strstr(cLabel,"-clone"))
927                                        tContainer("<blink>Error:</blink> cLabel can't have '-clone'");
928                                if(uCreateAppliance)
929                                {
930                                        if(!strstr(cLabel+(uLabelLen-strlen("-app")-1),"-app"))
931                                                tContainer("<blink>Error:</blink> Appliance cLabel must end with '-app'.");
932                                        if(strlen(gcIPv4)<7 || strlen(gcIPv4)>15)
933                                                tContainer("<blink>Error:</blink> Appliance requires valid gcIPv4.");
934
935                                        unsigned a=0,b=0,c=0,d=0;
936                                        sscanf(gcIPv4,"%u.%u.%u.%u",&a,&b,&c,&d);
937                                        if(a==0 || d==0)
938                                                tContainer("<blink>Error:</blink> Appliance requires valid gcIPv4.");
939                                }
940
941                                if((uHostnameLen=strlen(cHostname))<5)
942                                        tContainer("<blink>Error:</blink> cHostname is too short");
943                                if(cHostname[uHostnameLen-1]=='.')
944                                        tContainer("<blink>Error:</blink> cHostname can't end with a '.'");
945                                if(strstr(cHostname,"-clone"))
946                                        tContainer("<blink>Error:</blink> cHostname can't have '-clone'");
947                                //New rule: cLabel must be first part (first stop) of cHostname.
948                                if(strncmp(cLabel,cHostname,uLabelLen))
949                                        tContainer("<blink>Error:</blink> cLabel must be first part of cHostname.");
950                                if(uIPv4==0)
951                                        tContainer("<blink>Error:</blink> You must select a uIPv4");
952
953                                //Let's not allow same cLabel containers in our system for now.
954                                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE cLabel='%s'",cLabel);
955                                mysql_query(&gMysql,gcQuery);
956                                if(mysql_errno(&gMysql))
957                                                htmlPlainTextError(mysql_error(&gMysql));
958                                res=mysql_store_result(&gMysql);
959                                if(mysql_num_rows(res)>0)
960                                {
961                                        mysql_free_result(res);
962                                        tContainer("<blink>Error:</blink> cLabel already in use");
963                                }
964                                mysql_free_result(res);
965
966                                GetDatacenterProp(uDatacenter,"NewContainerCloneRange",cNCCloneRange);
967                                if(cNCCloneRange[0] && uIpv4InCIDR4(ForeignKey("tIP","cLabel",uIPv4),cNCCloneRange))
968                                        tContainer("<blink>Error:</blink> uIPv4 must not be in datacenter clone IP range");
969
970                                if(uOSTemplate==0)
971                                        tContainer("<blink>Error:</blink> You must select a uOSTemplate");
972                                if(uConfig==0)
973                                        tContainer("<blink>Error:</blink> You must select a uConfig");
974                                if(uNameserver==0)
975                                        tContainer("<blink>Error:</blink> You must select a uNameserver");
976                                if(uSearchdomain==0)
977                                        tContainer("<blink>Error:</blink> You must select a uSearchdomain");
978
979                                if(uGroup==0 && cService3[0]==0)
980                                        tContainer("<blink>Error:</blink> Group is now required");
981                                if(uGroup!=0 && cService3[0]!=0)
982                                        tContainer("<blink>Error:</blink> Or select a group or create a new one, not both");
983
984
985                                //DNS sanity check
986                                if(uCreateDNSJob)
987                                {
988                                        cunxsBindARecordJobZone[0]=0;
989                                        GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
990                                        if(!cunxsBindARecordJobZone[0])
991                                                tContainer("<blink>Error:</blink> Create job for unxsBind,"
992                                                                " but no cunxsBindARecordJobZone");
993                                       
994                                        if(!strstr(cHostname+(uHostnameLen-strlen(cunxsBindARecordJobZone)-1),cunxsBindARecordJobZone))
995                                                tContainer("<blink>Error:</blink> cHostname must end with cunxsBindARecordJobZone");
996                                }
997                                       
998                                if(cService1[0] && strlen(cService1)<6)
999                                        tContainer("<blink>Error:</blink> Optional password must be at least 6 chars");
1000                                //Direct datacenter checks
1001                                sscanf(ForeignKey("tIP","uDatacenter",uIPv4),"%u",&uIPv4Datacenter);
1002                                if(uDatacenter!=uIPv4Datacenter)
1003                                        tContainer("<blink>Error:</blink> The specified uIPv4 does not "
1004                                                        "belong to the specified uDatacenter.");
1005                                sscanf(ForeignKey("tNode","uDatacenter",uNode),"%u",&uNodeDatacenter);
1006                                if(uDatacenter!=uNodeDatacenter)
1007                                        tContainer("<blink>Error:</blink> The specified uNode does not "
1008                                                        "belong to the specified uDatacenter.");
1009                                //tProperty based datacenter checks
1010                                //VETH device
1011                                if(uVeth)
1012                                {
1013                                        GetNodeProp(uNode,"Container-Type",cContainerType);
1014                                        if(!strstr(cContainerType,"VETH"))
1015                                                tContainer("<blink>Error:</blink> uNode selected does not support VETH");
1016                                               
1017                                }
1018
1019                                //If auto clone setup check required values
1020                                GetConfiguration("cAutoCloneNode",cAutoCloneNode,uDatacenter,0,0,0);
1021                                if(cAutoCloneNode[0])
1022                                {
1023
1024                                        if(uTargetNode==0)
1025                                                tContainer("<blink>Error:</blink> Please select a valid target node"
1026                                                                " for the clone");
1027                                        if(uTargetNode==uNode)
1028                                                tContainer("<blink>Error:</blink> Can't clone to same node");
1029
1030                                        GetNodeProp(uTargetNode,"NewContainerMode",cNCMNode);
1031                                        if(cNCMNode[0] && !strstr(cNCMNode,"Clone"))
1032                                        tContainer("<blink>Error:</blink> Selected clone target node is not configured for clone containers."
1033                                                        "Select another.");
1034
1035                                        sscanf(ForeignKey("tNode","uDatacenter",uTargetNode),"%u",&uNodeDatacenter);
1036                                        //if(uDatacenter!=uNodeDatacenter)
1037                                        //      tContainer("<blink>Error:</blink> The specified clone uNode does not "
1038                                        //              "belong to the specified uDatacenter.");
1039                                        if(!uWizIPv4)
1040                                                tContainer("<blink>Error:</blink> You must select an IP for the clone");
1041                                        if(uWizIPv4==uIPv4)
1042                                                tContainer("<blink>Error:</blink> You must select a different IP for the"
1043                                                                                " clone");
1044                                        sscanf(ForeignKey("tIP","uDatacenter",uWizIPv4),"%u",&uIPv4Datacenter);
1045                                        if(uNodeDatacenter!=uIPv4Datacenter)
1046                                                tContainer("<blink>Error:</blink> The specified clone uIPv4 does not "
1047                                                        "belong to the specified uNodeDatacenter.");
1048                                        //Allow for two ranges to be configured
1049                                        if(cNCCloneRange[0] && !uIpv4InCIDR4(ForeignKey("tIP","cLabel",uWizIPv4),cNCCloneRange))
1050                                        {
1051                                                GetDatacenterProp(uDatacenter,"NewContainerCloneRange2",cNCCloneRange);
1052                                                if(cNCCloneRange[0] && !uIpv4InCIDR4(ForeignKey("tIP","cLabel",uWizIPv4),cNCCloneRange))
1053                                                        tContainer("<blink>Error:</blink> Clone start uIPv4 must be in datacenter clone IP range");
1054                                        }
1055                                        if(uSyncPeriod>86400*30 || (uSyncPeriod && uSyncPeriod<300))
1056                                                tContainer("<blink>Error:</blink> Clone uSyncPeriod out of range:"
1057                                                                " Max 30 days, min 5 minutes or 0 off.");
1058                                        //tContainer("<blink>Error:</blink> d1");
1059                                }
1060
1061                                //TODO review this policy.
1062                                //No same names or hostnames for same datacenter allowed.
1063                                //TODO periods "." should be expanded to "[.]"
1064                                //for correct cHostname REGEXP.
1065                                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE ("
1066                                                        " cHostname REGEXP '^%s[0-9]+%s$'"
1067                                                        " OR cLabel REGEXP '%s[0-9]+$'"
1068                                                        " ) AND uDatacenter=%u LIMIT 1",
1069                                                                cLabel,cHostname,cLabel,uDatacenter);
1070                                mysql_query(&gMysql,gcQuery);
1071                                if(mysql_errno(&gMysql))
1072                                                htmlPlainTextError(mysql_error(&gMysql));
1073                                res=mysql_store_result(&gMysql);
1074                                if(mysql_num_rows(res)>0)
1075                                {
1076                                        mysql_free_result(res);
1077                                        //debug only
1078                                        //tContainer(gcQuery);
1079                                        tContainer("<blink>Error:</blink> Single container, similar cHostname"
1080                                        " cLabel pattern already used at this datacenter!");
1081                                }
1082                                mysql_free_result(res);
1083
1084                                //Check to see if enough IPs are available early to avoid
1085                                //complex cleanup/rollback below
1086                                //First get class c mask will be used here and again in main loop below
1087
1088                                //Get container IP cIPv4ClassC
1089                                sprintf(gcQuery,"SELECT cLabel FROM tIP WHERE uIP=%u AND uAvailable=1"
1090                                                " AND uOwner=%u AND uDatacenter=%u",uIPv4,uForClient,uDatacenter);
1091                                mysql_query(&gMysql,gcQuery);
1092                                if(mysql_errno(&gMysql))
1093                                                htmlPlainTextError(mysql_error(&gMysql));
1094                                res=mysql_store_result(&gMysql);
1095                                if((field=mysql_fetch_row(res)))
1096                                {
1097                                        sprintf(cIPv4ClassC,"%.31s",field[0]);
1098                                }
1099                                else
1100                                {
1101                                        tContainer("<blink>Error:</blink> Someone grabbed your IP"
1102                                                ", single container creation aborted -if Root select"
1103                                                " a company with IPs!");
1104                                }
1105                                mysql_free_result(res);
1106                                for(i=strlen(cIPv4ClassC);i>0;i--)
1107                                {
1108                                        if(cIPv4ClassC[i]=='.')
1109                                        {
1110                                                cIPv4ClassC[i]=0;
1111                                                break;
1112                                        }
1113                                }
1114                                //Check IPs for clones first if so configured
1115                                if(cAutoCloneNode[0])
1116                                {
1117                                        //TODO clean...uNodeDatacenter is set above in clone section. So it is really
1118                                        //uCloneNodeDatacenter
1119                                        sprintf(gcQuery,"SELECT cLabel FROM tIP WHERE uIP=%u AND uAvailable=1"
1120                                                " AND uOwner=%u AND uDatacenter=%u",uWizIPv4,uForClient,uNodeDatacenter);
1121                                        mysql_query(&gMysql,gcQuery);
1122                                        if(mysql_errno(&gMysql))
1123                                                htmlPlainTextError(mysql_error(&gMysql));
1124                                        res=mysql_store_result(&gMysql);
1125                                        if((field=mysql_fetch_row(res)))
1126                                        {
1127                                                sprintf(cIPv4ClassCClone,"%.31s",field[0]);
1128                                        }
1129                                        else
1130                                        {
1131                                                tContainer("<blink>Error:</blink> Someone grabbed your clone IP"
1132                                                        ", single container creation aborted -if Root select"
1133                                                        " a company with IPs!");
1134                                        }
1135                                        mysql_free_result(res);
1136                                        for(i=strlen(cIPv4ClassCClone);i>0;i--)
1137                                        {
1138                                                if(cIPv4ClassCClone[i]=='.')
1139                                                {
1140                                                        cIPv4ClassCClone[i]=0;
1141                                                        break;
1142                                                }
1143                                        }
1144                                        //TODO --WHY can't they?
1145                                        if(!strcmp(cIPv4ClassCClone,cIPv4ClassC))
1146                                                tContainer("<blink>Error:</blink> Clone IPs must belong to a different"
1147                                                                " class C");
1148                                        //Count clone IPs
1149                                        sprintf(gcQuery,"SELECT COUNT(uIP) FROM tIP WHERE uAvailable=1 AND uOwner=%u"
1150                                                        " AND cLabel LIKE '%s%%' AND uDatacenter=%u",
1151                                                                uForClient,cIPv4ClassCClone,uNodeDatacenter);
1152                                        mysql_query(&gMysql,gcQuery);
1153                                        if(mysql_errno(&gMysql))
1154                                                htmlPlainTextError(mysql_error(&gMysql));
1155                                        res=mysql_store_result(&gMysql);
1156                                        if((field=mysql_fetch_row(res)))
1157                                                sscanf(field[0],"%u",&uAvailableIPs);
1158                                        mysql_free_result(res);
1159                                        if(!uAvailableIPs)
1160                                                tContainer("<blink>Error:</blink> No clone IP in given"
1161                                                        " class C"
1162                                                        " available!");
1163                                }//cAutoCloneNode
1164
1165                                //Count main IPs
1166                                uAvailableIPs=0;
1167                                sprintf(gcQuery,"SELECT COUNT(uIP) FROM tIP WHERE uAvailable=1 AND uOwner=%u"
1168                                                " AND cLabel LIKE '%s%%' AND uDatacenter=%u",
1169                                                                uForClient,cIPv4ClassC,uDatacenter);
1170                                mysql_query(&gMysql,gcQuery);
1171                                if(mysql_errno(&gMysql))
1172                                        htmlPlainTextError(mysql_error(&gMysql));
1173                                res=mysql_store_result(&gMysql);
1174                                if((field=mysql_fetch_row(res)))
1175                                        sscanf(field[0],"%u",&uAvailableIPs);
1176                                mysql_free_result(res);
1177                                if(!uAvailableIPs)
1178                                        tContainer("<blink>Error:</blink> No IP in given class C"
1179                                                " available!");
1180
1181                                //User chooses to create a new group
1182                                if(cService3[0])
1183                                {
1184                                        if(strlen(cService3)<3)
1185                                                tContainer("<blink>Error:</blink> New tGroup.cLabel too short!");
1186                                        sprintf(gcQuery,"SELECT uGroup FROM tGroup WHERE cLabel='%s'",cService3);
1187                                        mysql_query(&gMysql,gcQuery);
1188                                        if(mysql_errno(&gMysql))
1189                                                        htmlPlainTextError(mysql_error(&gMysql));
1190                                        res=mysql_store_result(&gMysql);
1191                                        if(mysql_num_rows(res)>0)
1192                                        {
1193                                                tContainer("<blink>Error:</blink> New tGroup.cLabel already in use!");
1194                                        }
1195                                        else
1196                                        {
1197                                                sprintf(gcQuery,"INSERT INTO tGroup SET cLabel='%s',uGroupType=1,"//1 is container type
1198                                                        "uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
1199                                                                cService3,uForClient,guLoginClient);
1200                                                mysql_query(&gMysql,gcQuery);
1201                                                if(mysql_errno(&gMysql))
1202                                                        htmlPlainTextError(mysql_error(&gMysql));
1203                                                uGroup=mysql_insert_id(&gMysql);
1204                                        }
1205                                        mysql_free_result(res);
1206                                }
1207
1208
1209                                unsigned uApplianceIPv4=0;
1210                                unsigned uApplianceDatacenter=41;//My current default for testing
1211                                unsigned uApplianceNode=81;//My current default for testing
1212                                char cuApplianceDatacenter[256]={""};
1213                                char cuApplianceNode[256]={""};
1214                                GetConfiguration("uApplianceDatacenter",cuApplianceDatacenter,uDatacenter,0,0,0);
1215                                sscanf(cuApplianceDatacenter,"%u",&uApplianceDatacenter);
1216                                GetConfiguration("uApplianceNode",cuApplianceNode,uDatacenter,0,0,0);
1217                                sscanf(cuApplianceNode,"%u",&uApplianceNode);
1218                                if(uCreateAppliance)
1219                                {
1220
1221                                        //New tIP for remote appliance
1222                                        sprintf(gcQuery,"SELECT uIP FROM tIP WHERE cLabel='%s' AND uAvailable=1",gcIPv4);
1223                                        mysql_query(&gMysql,gcQuery);
1224                                        if(mysql_errno(&gMysql))
1225                                                        htmlPlainTextError(mysql_error(&gMysql));
1226                                        res=mysql_store_result(&gMysql);
1227                                        if(mysql_num_rows(res)>0)
1228                                        {
1229                                                if((field=mysql_fetch_row(res)))
1230                                                        sscanf(field[0],"%u",&uApplianceIPv4);
1231                                        }
1232                                        else
1233                                        {
1234                                                sprintf(gcQuery,"INSERT INTO tIP SET cLabel='%s',uDatacenter=%u,"
1235                                                        "uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
1236                                                                gcIPv4,uApplianceDatacenter,uForClient,guLoginClient);
1237                                                mysql_query(&gMysql,gcQuery);
1238                                                if(mysql_errno(&gMysql))
1239                                                        htmlPlainTextError(mysql_error(&gMysql));
1240                                                uApplianceIPv4=mysql_insert_id(&gMysql);
1241                                        }
1242                                        if(!uApplianceIPv4)
1243                                        {
1244                                                tContainer("<blink>Error:</blink> uApplianceIPv4 not determined!!");
1245                                        }
1246                                }
1247
1248                                unsigned uApplianceContainer=0;
1249                                char cApplianceLabel[33]={""};
1250                                char cApplianceHostname[100]={""};
1251                                if(uCreateAppliance)
1252                                {
1253                                        char *cp;
1254
1255                                        if((cp=strstr(cLabel,"-app")))
1256                                        {
1257                                                *cp=0;
1258                                                sprintf(cApplianceLabel,"%.32s",cLabel);
1259                                                *cp='-';
1260                                        }
1261
1262                                        if((cp=strstr(cHostname,"-app.")))
1263                                                sprintf(cApplianceHostname,"%.99s",cp+5);
1264
1265                                        if(cApplianceLabel[0]==0 || cApplianceHostname[0]==0)
1266                                                tContainer("<blink>Error:</blink> cApplianceLabel/cApplianceHostname not defined");
1267
1268                                        sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE cLabel='%s'",cApplianceLabel);
1269                                        mysql_query(&gMysql,gcQuery);
1270                                        if(mysql_errno(&gMysql))
1271                                                htmlPlainTextError(mysql_error(&gMysql));
1272                                        res=mysql_store_result(&gMysql);
1273                                        if(mysql_num_rows(res)>0)
1274                                        {
1275                                                mysql_free_result(res);
1276                                                tContainer("<blink>Error:</blink> cApplianceLabel already in use");
1277                                        }
1278                                        mysql_free_result(res);
1279
1280#define uREMOTEAPPLIANCE 101
1281                                        sprintf(gcQuery,"INSERT INTO tContainer SET cLabel='%s',cHostname='%s.%s',"
1282                                                        "uIPv4=%u,"
1283                                                        "uDatacenter=%u,"
1284                                                        "uNode=%u,"
1285                                                        "uStatus=%u,"
1286                                                        "uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
1287                                                                cApplianceLabel,cApplianceLabel,cApplianceHostname,
1288                                                                uApplianceIPv4,
1289                                                                uApplianceDatacenter,
1290                                                                uApplianceNode,
1291                                                                uREMOTEAPPLIANCE,
1292                                                                uForClient,
1293                                                                guLoginClient);
1294                                        mysql_query(&gMysql,gcQuery);
1295                                        if(mysql_errno(&gMysql))
1296                                                        htmlPlainTextError(mysql_error(&gMysql));
1297                                        uApplianceContainer=mysql_insert_id(&gMysql);
1298
1299                                        if(!uApplianceContainer)
1300                                                tContainer("<blink>Error:</blink> uApplianceContainer not determined!!");
1301
1302                                        //Add to appliance group
1303                                        if(uGroup)
1304                                                ChangeGroup(uApplianceContainer,uGroup);
1305
1306                                        //Add properties
1307                                        //Name property
1308                                        sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1309                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1310                                                ",cName='Name',cValue='%s'",
1311                                                        uApplianceContainer,uForClient,guLoginClient,cApplianceLabel);
1312                                        mysql_query(&gMysql,gcQuery);
1313                                        if(mysql_errno(&gMysql))
1314                                                htmlPlainTextError(mysql_error(&gMysql));
1315                                        //cOrg_FreePBXAdminPasswd property
1316                                        sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1317                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1318                                                ",cName='cOrg_FreePBXAdminPasswd',cValue='unknown'",
1319                                                        uApplianceContainer,uForClient,guLoginClient);
1320                                        mysql_query(&gMysql,gcQuery);
1321                                        if(mysql_errno(&gMysql))
1322                                                htmlPlainTextError(mysql_error(&gMysql));
1323                                        //cPasswd property
1324                                        sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1325                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1326                                                ",cName='cPasswd',cValue='unknown'",
1327                                                        uApplianceContainer,uForClient,guLoginClient);
1328                                        mysql_query(&gMysql,gcQuery);
1329                                        if(mysql_errno(&gMysql))
1330                                                htmlPlainTextError(mysql_error(&gMysql));
1331
1332                                }//end if uCreateAppliance
1333
1334                                //
1335                                //debug after initial checks
1336                                //char cBuffer[256];
1337                                //sprintf(cBuffer,"uIPv4=%u uOSTemplate=%u uConfig=%u uNameserver=%u uSearchdomain=%u"
1338                                //              " uNode=%u uDatacenter=%u",
1339                                //                      uIPv4,uOSTemplate,uConfig,uNameserver,uSearchdomain,
1340                                //                      uNode,uDatacenter);
1341                                //tContainer(cBuffer);
1342                                //
1343
1344                                //Checks done commited to create
1345                                guMode=0;
1346                                uStatus=uINITSETUP;//Initial setup
1347                                uContainer=0;
1348                                uCreatedBy=guLoginClient;
1349                                guCompany=uForClient;
1350                                uOwner=guCompany;
1351                                uModBy=0;//Never modified
1352                                uModDate=0;//Never modified
1353                                //Convenience
1354                                if(uCreateAppliance)
1355                                        sprintf(cSearch,"%.31s",cApplianceLabel);
1356                                else
1357                                        sprintf(cSearch,"%.31s",cLabel);
1358
1359
1360                                //This sets new file global uContainer
1361                                uContainer=0;
1362                                if(uCreateAppliance)
1363                                        uSource=uApplianceContainer;
1364                                NewtContainer(1);
1365
1366                                //tIP
1367                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
1368                                                " WHERE uIP=%u AND uAvailable=1 AND uOwner=%u AND uDatacenter=%u",
1369                                                                        uIPv4,uForClient,uDatacenter);
1370                                mysql_query(&gMysql,gcQuery);
1371                                if(mysql_errno(&gMysql))
1372                                        htmlPlainTextError(mysql_error(&gMysql));
1373                                if(mysql_affected_rows(&gMysql)!=1)
1374                                {
1375                                        sprintf(gcQuery,"DELETE FROM tContainer WHERE uContainer=%u",
1376                                                uContainer);
1377                                        mysql_query(&gMysql,gcQuery);
1378                                        if(mysql_errno(&gMysql))
1379                                                htmlPlainTextError(mysql_error(&gMysql));
1380                                        tContainer("<blink>Error:</blink> Someone grabbed your IP"
1381                                                ", container creation aborted!");
1382                                }
1383                               
1384                                //Name property
1385                                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1386                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1387                                                ",cName='Name',cValue='%s'",
1388                                                        uContainer,uForClient,guLoginClient,cLabel);
1389                                mysql_query(&gMysql,gcQuery);
1390                                if(mysql_errno(&gMysql))
1391                                        htmlPlainTextError(mysql_error(&gMysql));
1392
1393                                //Optional passwd
1394                                if(cService1[0])
1395                                {
1396                                        sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1397                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1398                                                ",cName='cPasswd',cValue='%s'",
1399                                                        uContainer,uForClient,guLoginClient,cService1);
1400                                        mysql_query(&gMysql,gcQuery);
1401                                        if(mysql_errno(&gMysql))
1402                                                htmlPlainTextError(mysql_error(&gMysql));
1403                                }
1404
1405                                //Optional timezone note the --- not selected value.
1406                                if(gcNewContainerTZ[0]!='-')
1407                                {
1408                                        sprintf(gcQuery,"INSERT INTO tProperty SET cName='cOrg_TimeZone',cValue='%s',uType=3,uKey=%u"
1409                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
1410                                                        gcNewContainerTZ,uContainer,uForClient,guLoginClient);
1411                                        mysql_query(&gMysql,gcQuery);
1412                                        if(mysql_errno(&gMysql))
1413                                                htmlPlainTextError(mysql_error(&gMysql));
1414                                }
1415
1416                                //Add property template entries for VETH device based container
1417                                if(uVeth)
1418                                {
1419                                        sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1420                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1421                                                ",cName='cVEID.mount',cValue='defaultVETH.mount'",
1422                                                        uContainer,uForClient,guLoginClient);
1423                                        mysql_query(&gMysql,gcQuery);
1424                                        if(mysql_errno(&gMysql))
1425                                                htmlPlainTextError(mysql_error(&gMysql));
1426
1427                                        sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1428                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1429                                                ",cName='cVEID.start',cValue='defaultVETH.start'",
1430                                                        uContainer,uForClient,guLoginClient);
1431                                        mysql_query(&gMysql,gcQuery);
1432                                        if(mysql_errno(&gMysql))
1433                                                htmlPlainTextError(mysql_error(&gMysql));
1434                                }
1435
1436                                if(uGroup)
1437                                        ChangeGroup(uContainer,uGroup);
1438
1439                                if(cAutoCloneNode[0])
1440                                {
1441                                        //TODO what about clone datacenter?
1442                                        uNewVeid=CommonCloneContainer(
1443                                                                        uContainer,
1444                                                                        uOSTemplate,
1445                                                                        uConfig,
1446                                                                        uNameserver,
1447                                                                        uSearchdomain,
1448                                                                        uDatacenter,
1449                                                                        uNodeDatacenter,//uCloneNodeDatacenter
1450                                                                        uForClient,
1451                                                                        cLabel,
1452                                                                        uNode,
1453                                                                        uStatus,
1454                                                                        cHostname,
1455                                                                        cIPv4ClassCClone,
1456                                                                        uWizIPv4,
1457                                                                        cWizLabel,
1458                                                                        cWizHostname,
1459                                                                        uTargetNode,
1460                                                                        uSyncPeriod,
1461                                                                        guLoginClient,
1462                                                                        uCloneStop,0);
1463                                        SetContainerStatus(uContainer,uINITSETUP);
1464                                        if(uGroup)
1465                                                ChangeGroup(uNewVeid,uGroup);
1466
1467                                                //TODO cIPv4ClassCClone can't = cIPv4ClassC
1468                                                //Get next available uWizIPv4
1469                                        sprintf(gcQuery,"SELECT uIP FROM tIP WHERE uAvailable=1 AND uOwner=%u"
1470                                                        " AND cLabel LIKE '%s%%' AND uDatacenter=%u LIMIT 1",
1471                                                                uForClient,cIPv4ClassCClone,uNodeDatacenter);
1472                                        mysql_query(&gMysql,gcQuery);
1473                                        if(mysql_errno(&gMysql))
1474                                                htmlPlainTextError(mysql_error(&gMysql));
1475                                        res=mysql_store_result(&gMysql);
1476                                        if((field=mysql_fetch_row(res)))
1477                                                sscanf(field[0],"%u",&uWizIPv4);
1478                                        else
1479                                                tContainer("<blink>Error:</blink> No clone IP available"
1480                                                                ", container creation aborted!");
1481                                        mysql_free_result(res);
1482
1483                                        //Create DNS job for clones also
1484                                        if(uCreateDNSJob)
1485                                                CreateDNSJob(uWizIPv4,uForClient,NULL,cWizHostname,uNodeDatacenter,guLoginClient);
1486                                }//cAutoCloneNode
1487
1488                                if(uCreateDNSJob)
1489                                        CreateDNSJob(uIPv4,uForClient,NULL,cHostname,uDatacenter,guLoginClient);
1490
1491                                tContainer("New container created");
1492                        }
1493                        else
1494                        {
1495                                tContainer("<blink>Error:</blink> Denied by permissions settings");
1496                        }
1497                }//Single and appliance container creation end
1498                else if(!strcmp(gcCommand,"Multiple Container Creation"))
1499                {
1500                        if(guPermLevel>=9)
1501                        {
1502                                ProcesstContainerVars(entries,x);
1503
1504                                guMode=9003;
1505                                if(!uDatacenter)
1506                                        tContainer("<blink>Error:</blink> Must select a datacenter.");
1507                                if(!uForClient)
1508                                        tContainer("<blink>Error:</blink> Must select an organization"
1509                                                        " (company, NGO or similar.)");
1510                                if(!uNode)
1511                                        tContainer("<blink>Error:</blink> Must select a node.");
1512
1513                                GetDatacenterProp(uDatacenter,"NewContainerMode",cNCMDatacenter);
1514                                if(cNCMDatacenter[0] && !strstr(cNCMDatacenter,"Active"))
1515                                        tContainer("<blink>Error:</blink> Selected datacenter is full or not active. Select another.");
1516
1517                                GetNodeProp(uNode,"NewContainerMode",cNCMNode);
1518                                if(cNCMNode[0] && !strstr(cNCMNode,"Active"))
1519                                        tContainer("<blink>Error:</blink> Selected node is not configured for active containers."
1520                                                        "Select another.");
1521
1522                                guMode=9004;
1523                                tContainer("New container step 4");
1524                        }
1525                        else
1526                        {
1527                                tContainer("<blink>Error:</blink> Denied by permissions settings");
1528                        }
1529                }
1530                else if(!strcmp(gcCommand,"Create Multiple Containers"))
1531                {
1532                        if(guPermLevel>=9)
1533                        {
1534                                unsigned uNumContainer=0;
1535                                MYSQL_ROW field;
1536                                unsigned uNewVeid=0;
1537                                register int i;
1538                                char cIPv4ClassC[32]={""};
1539                                char cIPv4ClassCClone[32]={""};
1540                                unsigned uAvailableIPs=0;
1541                                char cGenLabel[32]={""};
1542                                char cGenHostname[100]={""};
1543                                char cOrgLabel[32]={""};
1544                                char cOrgHostname[100]={""};
1545                                unsigned uHostnameLen=0;
1546                                unsigned uLabelLen=0;
1547                                unsigned uTargetDatacenter=0;
1548
1549                                ProcesstContainerVars(entries,x);
1550                                sscanf(cService2,"%u",&uNumContainer);
1551
1552                                guMode=9004;
1553                                //Check entries here
1554                                if(uNumContainer==0)
1555                                        tContainer("<blink>Error:</blink> You must specify the number of containers");
1556                                if(uNumContainer>64)
1557                                {
1558                                        sprintf(cService2,"64");
1559                                        tContainer("<blink>Error:</blink> The maximum number of containers you can"
1560                                                        " create at once is 64");
1561                                }
1562                                if(uDatacenter==0)
1563                                        tContainer("<blink>Error:</blink> Unexpected uDatacenter==0!");
1564                                if(uNode==0)
1565                                        tContainer("<blink>Error:</blink> Unexpected uNode==0!");
1566
1567                                GetDatacenterProp(uDatacenter,"NewContainerMode",cNCMDatacenter);
1568                                if(cNCMDatacenter[0] && !strstr(cNCMDatacenter,"Active"))
1569                                        tContainer("<blink>Error:</blink> Selected datacenter is full or not active. Select another.");
1570
1571                                GetNodeProp(uNode,"NewContainerMode",cNCMNode);
1572                                if(cNCMNode[0] && !strstr(cNCMNode,"Active"))
1573                                        tContainer("<blink>Error:</blink> Selected node is not configured for active containers."
1574                                                        "Select another.");
1575
1576                                if((uLabelLen=strlen(cLabel))<2)
1577                                        tContainer("<blink>Error:</blink> cLabel is too short");
1578                                if(strchr(cLabel,'.'))
1579                                        tContainer("<blink>Error:</blink> cLabel has at least one '.'");
1580                                if(strstr(cLabel,"-clone"))
1581                                        tContainer("<blink>Error:</blink> cLabel can't have '-clone'");
1582                                if((uHostnameLen=strlen(cHostname))<5)
1583                                        tContainer("<blink>Error:</blink> cHostname is too short");
1584                                if(cHostname[uHostnameLen-1]=='.')
1585                                        tContainer("<blink>Error:</blink> cHostname can't end with a '.'");
1586                                if(strstr(cHostname,"-clone"))
1587                                        tContainer("<blink>Error:</blink> cHostname can't have '-clone'");
1588                                if(cHostname[0]!='.')
1589                                        tContainer("<blink>Error:</blink> Multiple containers cHostname has"
1590                                                        " to start with '.'");
1591                                if((uHostnameLen+uLabelLen)>62)
1592                                        tContainer("<blink>Error:</blink> Combined length of cLabel+cHostname is too long");
1593
1594                                if(uIPv4==0)
1595                                        tContainer("<blink>Error:</blink> You must select a uIPv4");
1596                                GetDatacenterProp(uDatacenter,"NewContainerCloneRange",cNCCloneRange);
1597                                if(cNCCloneRange[0] && uIpv4InCIDR4(ForeignKey("tIP","cLabel",uIPv4),cNCCloneRange))
1598                                        tContainer("<blink>Error:</blink> uIPv4 must not be in datacenter clone IP range");
1599
1600                                if(uOSTemplate==0)
1601                                        tContainer("<blink>Error:</blink> You must select a uOSTemplate");
1602                                if(uConfig==0)
1603                                        tContainer("<blink>Error:</blink> You must select a uConfig");
1604                                if(uNameserver==0)
1605                                        tContainer("<blink>Error:</blink> You must select a uNameserver");
1606                                if(uSearchdomain==0)
1607                                        tContainer("<blink>Error:</blink> You must select a uSearchdomain");
1608                                if(uGroup==0 && cService3[0]==0)
1609                                        tContainer("<blink>Error:</blink> Group is now required");
1610                                if(uGroup!=0 && cService3[0]!=0)
1611                                        tContainer("<blink>Error:</blink> Or select a group or create a new one, not both");
1612
1613                                //DNS sanity check
1614                                if(uCreateDNSJob)
1615                                {
1616                                        cunxsBindARecordJobZone[0]=0;
1617                                        GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
1618                                        if(!cunxsBindARecordJobZone[0])
1619                                                tContainer("<blink>Error:</blink> Create job for unxsBind,"
1620                                                                " but no cunxsBindARecordJobZone");
1621                                       
1622                                        if(!strstr(cHostname+(uHostnameLen-strlen(cunxsBindARecordJobZone)-1),cunxsBindARecordJobZone))
1623                                                tContainer("<blink>Error:</blink> cHostname must end with cunxsBindARecordJobZone");
1624                                }
1625                                       
1626                                if(cService1[0] && strlen(cService1)<6)
1627                                        tContainer("<blink>Error:</blink> Optional password must be at least 6 chars");
1628                                //Direct datacenter checks
1629                                sscanf(ForeignKey("tIP","uDatacenter",uIPv4),"%u",&uIPv4Datacenter);
1630                                if(uDatacenter!=uIPv4Datacenter)
1631                                        tContainer("<blink>Error:</blink> The specified uIPv4 does not "
1632                                                        "belong to the specified uDatacenter.");
1633                                sscanf(ForeignKey("tNode","uDatacenter",uNode),"%u",&uNodeDatacenter);
1634                                if(uDatacenter!=uNodeDatacenter)
1635                                        tContainer("<blink>Error:</blink> The specified uNode does not "
1636                                                        "belong to the specified uDatacenter.");
1637                                //tProperty based datacenter checks
1638                                //VETH device
1639                                if(uVeth)
1640                                {
1641                                        GetNodeProp(uNode,"Container-Type",cContainerType);
1642                                        if(!strstr(cContainerType,"VETH"))
1643                                                tContainer("<blink>Error:</blink> uNode selected does not support VETH");
1644                                               
1645                                }
1646
1647                                //If auto clone setup check required values
1648                                GetConfiguration("cAutoCloneNode",cAutoCloneNode,uDatacenter,0,0,0);
1649                                if(cAutoCloneNode[0])
1650                                {
1651
1652                                        if(uTargetNode==0)
1653                                                tContainer("<blink>Error:</blink> Please select a valid target node"
1654                                                                " for the clone");
1655                                        if(uTargetNode==uNode)
1656                                                tContainer("<blink>Error:</blink> Can't clone to same node");
1657
1658                                        GetNodeProp(uTargetNode,"NewContainerMode",cNCMNode);
1659                                        if(cNCMNode[0] && !strstr(cNCMNode,"Clone"))
1660                                        tContainer("<blink>Error:</blink> Selected node is not configured for clone containers."
1661                                                        "Select another.");
1662
1663                                        //We are moving to normal remote datacenter clone containers
1664                                        sscanf(ForeignKey("tNode","uDatacenter",uTargetNode),"%u",&uTargetDatacenter);
1665                                        //if(uDatacenter!=uTargetDatacenter)
1666                                        //      tContainer("<blink>Error:</blink> The specified clone uNode does not "
1667                                        //              "belong to the specified uDatacenter.");
1668                                        if(!uWizIPv4)
1669                                                tContainer("<blink>Error:</blink> You must select an IP for the clone");
1670                                        if(uWizIPv4==uIPv4)
1671                                                tContainer("<blink>Error:</blink> You must select a different IP for the"
1672                                                                                " clone");
1673                                        sscanf(ForeignKey("tIP","uDatacenter",uWizIPv4),"%u",&uIPv4Datacenter);
1674                                        if(uTargetDatacenter!=uIPv4Datacenter)
1675                                                tContainer("<blink>Error:</blink> The specified clone uIPv4 does not "
1676                                                        "belong to the specified uTargetDatacenter.");
1677                                        GetDatacenterProp(uTargetDatacenter,"NewContainerCloneRange",cNCCloneRange);
1678                                        if(cNCCloneRange[0] && !uIpv4InCIDR4(ForeignKey("tIP","cLabel",uWizIPv4),cNCCloneRange))
1679                                        {
1680                                                GetDatacenterProp(uTargetDatacenter,"NewContainerCloneRange2",cNCCloneRange);
1681                                                if(cNCCloneRange[0] && !uIpv4InCIDR4(ForeignKey("tIP","cLabel",uWizIPv4),cNCCloneRange))
1682                                                {
1683                                                        GetDatacenterProp(uTargetDatacenter,"NewContainerCloneRange3",cNCCloneRange);
1684                                                        if(cNCCloneRange[0] && !uIpv4InCIDR4(ForeignKey("tIP","cLabel",uWizIPv4),cNCCloneRange))
1685                                                                tContainer("<blink>Error:</blink> Clone start uIPv4 must be in datacenter"
1686                                                                                " clone IP range (cmc)");
1687                                                }
1688                                        }
1689                                        if(uSyncPeriod>86400*30 || (uSyncPeriod && uSyncPeriod<300))
1690                                                tContainer("<blink>Error:</blink> Clone uSyncPeriod out of range:"
1691                                                                " Max 30 days, min 5 minutes or 0 off.");
1692                                }
1693
1694                                //TODO review this policy.
1695                                //No same names or hostnames for same datacenter allowed.
1696                                //TODO periods "." should be expanded to "[.]"
1697                                //for correct cHostname REGEXP.
1698                                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE ("
1699                                                        " cHostname REGEXP '^%s[0-9]+%s$'"
1700                                                        " OR cLabel REGEXP '%s[0-9]+$'"
1701                                                        " ) AND uDatacenter=%u LIMIT 1",
1702                                                                cLabel,cHostname,cLabel,uDatacenter);
1703                                mysql_query(&gMysql,gcQuery);
1704                                if(mysql_errno(&gMysql))
1705                                                htmlPlainTextError(mysql_error(&gMysql));
1706                                res=mysql_store_result(&gMysql);
1707                                if(mysql_num_rows(res)>0)
1708                                {
1709                                        mysql_free_result(res);
1710                                        //debug only
1711                                        //tContainer(gcQuery);
1712                                        tContainer("<blink>Error:</blink> Multiple containers, similar cHostname"
1713                                        " cLabel pattern already used at this datacenter!");
1714                                }
1715                                mysql_free_result(res);
1716
1717                                //Check to see if enough IPs are available early to avoid
1718                                //complex cleanup/rollback below
1719                                //First get class c mask will be used here and again in main loop below
1720
1721                                //Get container IP cIPv4ClassC
1722                                sprintf(gcQuery,"SELECT cLabel FROM tIP WHERE uIP=%u AND uAvailable=1"
1723                                                " AND uOwner=%u AND uDatacenter=%u",uIPv4,uForClient,uDatacenter);
1724                                mysql_query(&gMysql,gcQuery);
1725                                if(mysql_errno(&gMysql))
1726                                                htmlPlainTextError(mysql_error(&gMysql));
1727                                res=mysql_store_result(&gMysql);
1728                                if((field=mysql_fetch_row(res)))
1729                                {
1730                                        sprintf(cIPv4ClassC,"%.31s",field[0]);
1731                                }
1732                                else
1733                                {
1734                                        tContainer("<blink>Error:</blink> Someone grabbed your IP"
1735                                                ", multiple container creation aborted -if Root select"
1736                                                " a company with IPs!");
1737                                }
1738                                mysql_free_result(res);
1739                                for(i=strlen(cIPv4ClassC);i>0;i--)
1740                                {
1741                                        if(cIPv4ClassC[i]=='.')
1742                                        {
1743                                                cIPv4ClassC[i]=0;
1744                                                break;
1745                                        }
1746                                }
1747                                //Check IPs for clones first if so configured
1748                                if(cAutoCloneNode[0])
1749                                {
1750                                        sprintf(gcQuery,"SELECT cLabel FROM tIP WHERE uIP=%u AND uAvailable=1"
1751                                                " AND uOwner=%u AND uDatacenter=%u",uWizIPv4,uForClient,uTargetDatacenter);
1752                                        mysql_query(&gMysql,gcQuery);
1753                                        if(mysql_errno(&gMysql))
1754                                                htmlPlainTextError(mysql_error(&gMysql));
1755                                        res=mysql_store_result(&gMysql);
1756                                        if((field=mysql_fetch_row(res)))
1757                                        {
1758                                                sprintf(cIPv4ClassCClone,"%.31s",field[0]);
1759                                        }
1760                                        else
1761                                        {
1762                                                tContainer("<blink>Error:</blink> Someone grabbed your clone IP"
1763                                                        ", multiple container creation aborted -if Root select"
1764                                                        " a company with IPs!");
1765                                        }
1766                                        mysql_free_result(res);
1767                                        for(i=strlen(cIPv4ClassCClone);i>0;i--)
1768                                        {
1769                                                if(cIPv4ClassCClone[i]=='.')
1770                                                {
1771                                                        cIPv4ClassCClone[i]=0;
1772                                                        break;
1773                                                }
1774                                        }
1775                                        //TODO
1776                                        if(!strcmp(cIPv4ClassCClone,cIPv4ClassC))
1777                                                tContainer("<blink>Error:</blink> Clone IPs must belong to a different"
1778                                                                " class C");
1779                                        //Count clone IPs
1780                                        sprintf(gcQuery,"SELECT COUNT(uIP) FROM tIP WHERE uAvailable=1 AND uOwner=%u"
1781                                                        " AND cLabel LIKE '%s%%' AND uDatacenter=%u",
1782                                                                uForClient,cIPv4ClassCClone,uTargetDatacenter);
1783                                        mysql_query(&gMysql,gcQuery);
1784                                        if(mysql_errno(&gMysql))
1785                                                htmlPlainTextError(mysql_error(&gMysql));
1786                                        res=mysql_store_result(&gMysql);
1787                                        if((field=mysql_fetch_row(res)))
1788                                                sscanf(field[0],"%u",&uAvailableIPs);
1789                                        mysql_free_result(res);
1790                                        if(uNumContainer>uAvailableIPs)
1791                                                tContainer("<blink>Error:</blink> Not enough clone IPs in given"
1792                                                        " class C"
1793                                                        " available!");
1794                                }//cAutoCloneNode
1795
1796                                //Count main IPs
1797                                uAvailableIPs=0;
1798                                sprintf(gcQuery,"SELECT COUNT(uIP) FROM tIP WHERE uAvailable=1 AND uOwner=%u"
1799                                                " AND cLabel LIKE '%s%%' AND uDatacenter=%u",
1800                                                                uForClient,cIPv4ClassC,uDatacenter);
1801                                mysql_query(&gMysql,gcQuery);
1802                                if(mysql_errno(&gMysql))
1803                                        htmlPlainTextError(mysql_error(&gMysql));
1804                                res=mysql_store_result(&gMysql);
1805                                if((field=mysql_fetch_row(res)))
1806                                        sscanf(field[0],"%u",&uAvailableIPs);
1807                                mysql_free_result(res);
1808                                if(uNumContainer>uAvailableIPs)
1809                                        tContainer("<blink>Error:</blink> Not enough IPs in given class C"
1810                                                " available!");
1811
1812                                //User chooses to create a new group
1813                                if(cService3[0])
1814                                {
1815                                        if(strlen(cService3)<3)
1816                                                tContainer("<blink>Error:</blink> New tGroup.cLabel too short!");
1817                                        sprintf(gcQuery,"SELECT uGroup FROM tGroup WHERE cLabel='%s'",cService3);
1818                                        mysql_query(&gMysql,gcQuery);
1819                                        if(mysql_errno(&gMysql))
1820                                                        htmlPlainTextError(mysql_error(&gMysql));
1821                                        res=mysql_store_result(&gMysql);
1822                                        if(mysql_num_rows(res)>0)
1823                                        {
1824                                                tContainer("<blink>Error:</blink> New tGroup.cLabel already in use!");
1825                                        }
1826                                        else
1827                                        {
1828                                                sprintf(gcQuery,"INSERT INTO tGroup SET cLabel='%s',uGroupType=1,"//1 is container type
1829                                                        "uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
1830                                                                cService3,uForClient,guLoginClient);
1831                                                mysql_query(&gMysql,gcQuery);
1832                                                if(mysql_errno(&gMysql))
1833                                                        htmlPlainTextError(mysql_error(&gMysql));
1834                                                uGroup=mysql_insert_id(&gMysql);
1835                                        }
1836                                        mysql_free_result(res);
1837                                }
1838
1839                                //
1840                                //debug after initial checks
1841                                //char cBuffer[256];
1842                                //sprintf(cBuffer,"uIPv4=%u uOSTemplate=%u uConfig=%u uNameserver=%u uSearchdomain=%u"
1843                                //              " uNode=%u uDatacenter=%u",
1844                                //                      uIPv4,uOSTemplate,uConfig,uNameserver,uSearchdomain,
1845                                //                      uNode,uDatacenter);
1846                                //tContainer(cBuffer);
1847                                //
1848
1849                                //Checks done commited to create
1850                                guMode=0;
1851                                uStatus=uINITSETUP;//Initial setup
1852                                uContainer=0;
1853                                uCreatedBy=guLoginClient;
1854                                guCompany=uForClient;
1855                                uOwner=guCompany;
1856                                uModBy=0;//Never modified
1857                                uModDate=0;//Never modified
1858                                sprintf(cOrgLabel,"%.31s",cLabel);
1859                                sprintf(cOrgHostname,"%.68s",cHostname);
1860                                //Convenience
1861                                sprintf(cSearch,"%.31s",cLabel);
1862
1863                                //Loop creation
1864                                for(i=0;i<uNumContainer;i++)
1865                                {
1866
1867                                        //Create cLabel and cHostname
1868                                        sprintf(cGenLabel,"%.29s%d",cOrgLabel,i);//i is limited to 2 digits
1869                                        sprintf(cGenHostname,"%.29s%d%.68s",cOrgLabel,i,cOrgHostname);
1870                                        if(strlen(cGenLabel)>31)
1871                                                tContainer("<blink>Error:</blink> cLabel length exceeded"
1872                                                        ", multiple container creation aborted!");
1873                                        if(strlen(cGenHostname)>64)
1874                                                tContainer("<blink>Error:</blink> cHostname length exceeded"
1875                                                        ", multiple container creation aborted!");
1876                                        sprintf(cLabel,"%.31s",cGenLabel);
1877                                        sprintf(cHostname,"%.64s",cGenHostname);//TODO check above
1878
1879                                        //This sets new file global uContainer
1880                                        uContainer=0;
1881                                        NewtContainer(1);
1882
1883                                        //tIP
1884                                        sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
1885                                                " WHERE uIP=%u AND uAvailable=1 AND uOwner=%u AND uDatacenter=%u",
1886                                                                        uIPv4,uForClient,uDatacenter);
1887                                        mysql_query(&gMysql,gcQuery);
1888                                        if(mysql_errno(&gMysql))
1889                                                htmlPlainTextError(mysql_error(&gMysql));
1890                                        if(mysql_affected_rows(&gMysql)!=1)
1891                                        {
1892                                                sprintf(gcQuery,"DELETE FROM tContainer WHERE uContainer=%u",
1893                                                        uContainer);
1894                                                mysql_query(&gMysql,gcQuery);
1895                                                if(mysql_errno(&gMysql))
1896                                                        htmlPlainTextError(mysql_error(&gMysql));
1897                                                tContainer("<blink>Error:</blink> Someone grabbed your IP"
1898                                                        ", multiple container creation aborted!");
1899                                        }
1900                               
1901                                        //Name property
1902                                        sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1903                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1904                                                ",cName='Name',cValue='%s'",
1905                                                        uContainer,uForClient,guLoginClient,cLabel);
1906                                        mysql_query(&gMysql,gcQuery);
1907                                        if(mysql_errno(&gMysql))
1908                                                htmlPlainTextError(mysql_error(&gMysql));
1909
1910                                        //Optional passwd
1911                                        if(cService1[0])
1912                                        {
1913                                                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1914                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1915                                                ",cName='cPasswd',cValue='%s'",
1916                                                        uContainer,uForClient,guLoginClient,cService1);
1917                                                mysql_query(&gMysql,gcQuery);
1918                                                if(mysql_errno(&gMysql))
1919                                                        htmlPlainTextError(mysql_error(&gMysql));
1920                                        }
1921
1922                                        //Optional timezone note the --- not selected value.
1923                                        if(gcNewContainerTZ[0]!='-')
1924                                        {
1925                                                sprintf(gcQuery,"INSERT INTO tProperty SET cName='cOrg_TimeZone',cValue='%s',"
1926                                                                "uType=3,uKey=%u,uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
1927                                                        gcNewContainerTZ,uContainer,uForClient,guLoginClient);
1928                                                mysql_query(&gMysql,gcQuery);
1929                                                if(mysql_errno(&gMysql))
1930                                                        htmlPlainTextError(mysql_error(&gMysql));
1931                                        }
1932
1933                                        //Add property template entries for VETH device based container
1934                                        if(uVeth)
1935                                        {
1936                                                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1937                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1938                                                ",cName='cVEID.mount',cValue='defaultVETH.mount'",
1939                                                        uContainer,uForClient,guLoginClient);
1940                                                mysql_query(&gMysql,gcQuery);
1941                                                if(mysql_errno(&gMysql))
1942                                                        htmlPlainTextError(mysql_error(&gMysql));
1943
1944                                                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
1945                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
1946                                                ",cName='cVEID.start',cValue='defaultVETH.start'",
1947                                                        uContainer,uForClient,guLoginClient);
1948                                                mysql_query(&gMysql,gcQuery);
1949                                                if(mysql_errno(&gMysql))
1950                                                        htmlPlainTextError(mysql_error(&gMysql));
1951                                        }
1952
1953                                        if(uGroup)
1954                                                ChangeGroup(uContainer,uGroup);
1955
1956                                        if(cAutoCloneNode[0])
1957                                        {
1958                                                uNewVeid=CommonCloneContainer(
1959                                                                        uContainer,
1960                                                                        uOSTemplate,
1961                                                                        uConfig,
1962                                                                        uNameserver,
1963                                                                        uSearchdomain,
1964                                                                        uDatacenter,
1965                                                                        uTargetDatacenter,
1966                                                                        uForClient,
1967                                                                        cLabel,
1968                                                                        uNode,
1969                                                                        uStatus,
1970                                                                        cHostname,
1971                                                                        cIPv4ClassCClone,
1972                                                                        uWizIPv4,
1973                                                                        cWizLabel,
1974                                                                        cWizHostname,
1975                                                                        uTargetNode,
1976                                                                        uSyncPeriod,
1977                                                                        guLoginClient,
1978                                                                        uCloneStop,0);
1979                                                SetContainerStatus(uContainer,uINITSETUP);
1980                                                if(uGroup)
1981                                                        ChangeGroup(uNewVeid,uGroup);
1982
1983                                                //Get next available clone uIPv4 only if not last loop iteration
1984                                                if((i+1)<uNumContainer)
1985                                                {
1986                                                        //TODO cIPv4ClassCClone can't = cIPv4ClassC
1987                                                        //Get next available uWizIPv4
1988                                                        sprintf(gcQuery,"SELECT uIP FROM tIP WHERE uAvailable=1 AND uOwner=%u"
1989                                                                " AND cLabel LIKE '%s%%' AND uDatacenter=%u LIMIT 1",
1990                                                                        uForClient,cIPv4ClassCClone,uTargetDatacenter);
1991                                                        mysql_query(&gMysql,gcQuery);
1992                                                        if(mysql_errno(&gMysql))
1993                                                                htmlPlainTextError(mysql_error(&gMysql));
1994                                                        res=mysql_store_result(&gMysql);
1995                                                        if((field=mysql_fetch_row(res)))
1996                                                                sscanf(field[0],"%u",&uWizIPv4);
1997                                                        else
1998                                                                tContainer("<blink>Error:</blink> No more clone IPs available"
1999                                                                        ", multiple container creation aborted!");
2000                                                        mysql_free_result(res);
2001                                                }
2002
2003                                                if(uCreateDNSJob)
2004                                                        CreateDNSJob(uWizIPv4,uForClient,NULL,cWizHostname,uTargetDatacenter,guLoginClient);
2005                                        }//cAutoCloneNode
2006
2007
2008                                        //For some reason cHostname is cLabel at this point. TODO debug.
2009                                        if(uCreateDNSJob)
2010                                                CreateDNSJob(uIPv4,uForClient,NULL,cHostname,uDatacenter,guLoginClient);
2011
2012                                        //Get next available uIPv4 only if not last loop iteration
2013                                        if((i+1)<uNumContainer)
2014                                        {
2015                                                sprintf(gcQuery,"SELECT uIP FROM tIP WHERE uAvailable=1 AND uOwner=%u"
2016                                                " AND cLabel LIKE '%s%%' AND uDatacenter=%u LIMIT 1",
2017                                                                uForClient,cIPv4ClassC,uDatacenter);
2018                                                mysql_query(&gMysql,gcQuery);
2019                                                if(mysql_errno(&gMysql))
2020                                                        htmlPlainTextError(mysql_error(&gMysql));
2021                                                res=mysql_store_result(&gMysql);
2022                                                if((field=mysql_fetch_row(res)))
2023                                                        sscanf(field[0],"%u",&uIPv4);
2024                                                else
2025                                                        tContainer("<blink>Error:</blink> No more IPs available"
2026                                                        ", multiple container creation aborted!");
2027                                                mysql_free_result(res);
2028                                        }
2029
2030                                }//end of loop
2031
2032                                tContainer("New containers created");
2033                        }
2034                        else
2035                        {
2036                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2037                        }
2038                }//Multiple containers
2039                //New wizard section ends
2040
2041
2042
2043                //TODO mount settings wizard
2044                else if(!strcmp(gcCommand,"Confirm Mount Settings") ||
2045                        !strcmp(gcCommand,"Confirm Container Settings"))
2046                {
2047                        ProcesstContainerVars(entries,x);
2048                        if(guPermLevel>=9)
2049                        {
2050
2051                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2052                                if(uModDate!=uActualModDate)
2053                                        tContainer("<blink>Error:</blink> This record was modified. Reload it!");
2054
2055                                guMode=200;
2056                                if(uStatus!=uINITSETUP)
2057                                        tContainer("<blink>Unexpected Error</blink>: uStatus not 'Initial Setup'");
2058
2059                                guMode=201;
2060                                if(!uVeth)
2061                                {
2062                                        if(uCheckMountSettings(uMountTemplate))
2063                                                tContainer("<blink>Error:</blink> Incorrect mount settings!");
2064                                        AddMountProps(uContainer);
2065                                }
2066                       
2067                                guMode=0;
2068                                tContainer("New container setup completed");
2069                        }
2070                        else
2071                        {
2072                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2073                        }
2074                }
2075                else if(!strcmp(gcCommand,LANG_NB_DELETE))
2076                {
2077                        ProcesstContainerVars(entries,x);
2078                        if(uAllowDel(uOwner,uCreatedBy))
2079                        {
2080                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2081                                if(uModDate!=uActualModDate)
2082                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2083
2084                                guMode=2001;
2085                                tContainer(LANG_NB_CONFIRMDEL);
2086                        }
2087                        else
2088                        {
2089                                tContainer("<blink>Error:</blink> Delete denied by permissions settings");
2090                        }
2091                }
2092                else if(!strcmp(gcCommand,LANG_NB_CONFIRMDEL))
2093                {
2094                        ProcesstContainerVars(entries,x);
2095                        if(uAllowDel(uOwner,uCreatedBy))
2096                        {
2097                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2098                                if(uModDate!=uActualModDate)
2099                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2100
2101                                guMode=2001;
2102                                //Special safety for root level cleanup dels
2103                                if(uStatus!=uINITSETUP && uSource)
2104                                {
2105                                        sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE uContainer=%u",uSource);
2106                                        mysql_query(&gMysql,gcQuery);
2107                                        if(mysql_errno(&gMysql))
2108                                                htmlPlainTextError(mysql_error(&gMysql));
2109                                        res=mysql_store_result(&gMysql);
2110                                        if(mysql_num_rows(res)!=0)
2111                                                tContainer("<blink>Error:</blink> This container has a source. Delete it first.");
2112                                }
2113
2114                                guMode=5;
2115                                uStatus=0;//Internal hack for deploy button turn off
2116                                //Release IPs
2117                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=1,uModBy=%u,uModDate=UNIX_TIMESTAMP(NOW())"
2118                                                " WHERE uIP=%u AND uAvailable=0",guLoginClient,uIPv4);
2119                                mysql_query(&gMysql,gcQuery);
2120                                if(mysql_errno(&gMysql))
2121                                        htmlPlainTextError(mysql_error(&gMysql));
2122                                //TODO this operation may not be datacenter safe review
2123                                //Node IP if any MySQL5+
2124                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=1,uModBy=%u,uModDate=UNIX_TIMESTAMP(NOW()) WHERE cLabel IN"
2125                                                " (SELECT cValue FROM tProperty WHERE uKey=%u"
2126                                                " AND uType=3 AND cName='cNodeIP')",guLoginClient,uContainer);
2127                                mysql_query(&gMysql,gcQuery);
2128                                if(mysql_errno(&gMysql))
2129                                        htmlPlainTextError(mysql_error(&gMysql));
2130                                //Now we can remove properties
2131                                DelProperties(uContainer,3);
2132                                //Remove from any groups
2133                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uContainer=%u",uContainer);//Ok to delete from all groups
2134                                mysql_query(&gMysql,gcQuery);
2135                                if(mysql_errno(&gMysql))
2136                                        htmlPlainTextError(mysql_error(&gMysql));
2137                                CancelContainerJob(uDatacenter,uNode,uContainer,0);
2138                                //81=Awaiting clone
2139                                sprintf(gcQuery,"DELETE FROM tContainer WHERE uStatus=81 AND uSource=%u",uContainer);
2140                                mysql_query(&gMysql,gcQuery);
2141                                if(mysql_errno(&gMysql))
2142                                        htmlPlainTextError(mysql_error(&gMysql));
2143                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uContainer IN "
2144                                                "(SELECT uContainer FROM tContainer WHERE uSource=%u AND uStatus=81)",uContainer);
2145                                mysql_query(&gMysql,gcQuery);
2146                                if(mysql_errno(&gMysql))
2147                                        htmlPlainTextError(mysql_error(&gMysql));
2148                                //Release clone IP
2149                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=1,uModBy=%u,uModDate=UNIX_TIMESTAMP(NOW())"
2150                                                " WHERE uIP=(SELECT uIPv4 FROM tContainer WHERE uSource=%u AND uStatus=81)"
2151                                                " AND uAvailable=0",guLoginClient,uContainer);
2152                                mysql_query(&gMysql,gcQuery);
2153                                if(mysql_errno(&gMysql))
2154                                        htmlPlainTextError(mysql_error(&gMysql));
2155                                DeletetContainer();
2156                        }
2157                        else
2158                        {
2159                                tContainer("<blink>Error:</blink> Delete denied by permissions settings");
2160                        }
2161                }
2162                else if(!strcmp(gcCommand,LANG_NB_MODIFY))
2163                {
2164                        ProcesstContainerVars(entries,x);
2165                        if( (uStatus==uINITSETUP) && uAllowMod(uOwner,uCreatedBy))
2166                        {
2167                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2168                                if(uModDate!=uActualModDate)
2169                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2170
2171                                guMode=2002;
2172
2173                                tContainer(LANG_NB_CONFIRMMOD);
2174                        }
2175                        else
2176                        {
2177                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2178                        }
2179                }
2180                else if(!strcmp(gcCommand,LANG_NB_CONFIRMMOD))
2181                {
2182                        ProcesstContainerVars(entries,x);
2183                        if( (uStatus==uINITSETUP) && uAllowMod(uOwner,uCreatedBy))
2184                        {
2185                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2186                                if(uModDate!=uActualModDate)
2187                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2188
2189                                guMode=2002;
2190                                //Check entries here
2191                                if(uContainer==0)
2192                                        tContainer("<blink>Error:</blink> uContainer==0!");
2193                                if(uDatacenter==0)
2194                                        tContainer("<blink>Error:</blink> uDatacenter==0!");
2195                                if(uNode==0)
2196                                        tContainer("<blink>Error:</blink> uNode==0!");
2197                                sscanf(ForeignKey("tNode","uDatacenter",uNode),"%u",&uNodeDatacenter);
2198                                if(uDatacenter!=uNodeDatacenter)
2199                                        tContainer("<blink>Error:</blink> The specified uNode does not "
2200                                                        "belong to the specified uDatacenter.");
2201                                if(uIPv4==0)
2202                                        tContainer("<blink>Error:</blink> uIPv4==0!");
2203                                if(uOSTemplate==0)
2204                                        tContainer("<blink>Error:</blink> uOSTemplate==0!");
2205                                if(uConfig==0)
2206                                        tContainer("<blink>Error:</blink> uConfig==0!");
2207                                if(uNameserver==0)
2208                                        tContainer("<blink>Error:</blink> uNameserver==0!");
2209                                if(uSearchdomain==0)
2210                                        tContainer("<blink>Error:</blink> uSearchdomain==0!");
2211                                if(strlen(cHostname)<5)
2212                                        tContainer("<blink>Error:</blink> cHostname too short!");
2213                                if(strlen(cLabel)<2)
2214                                        tContainer("<blink>Error:</blink> cLabel too short!");
2215                                if(strstr(cLabel,"-clone"))
2216                                        tContainer("<blink>Error:</blink> cLabel can't have '-clone'!");
2217                                if(strstr(cHostname,"-clone"))
2218                                        tContainer("<blink>Error:</blink> cHostname can't have '-clone'!");
2219                                //No same names or hostnames for same datacenter allowed.
2220                                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE (cHostname='%s' OR cLabel='%s')"
2221                                                " AND uContainer!=%u",
2222                                                        cHostname,cLabel,uContainer);
2223                                mysql_query(&gMysql,gcQuery);
2224                                if(mysql_errno(&gMysql))
2225                                                htmlPlainTextError(mysql_error(&gMysql));
2226                                res=mysql_store_result(&gMysql);
2227                                if(mysql_num_rows(res)>0)
2228                                {
2229                                        mysql_free_result(res);
2230                                        tContainer("<blink>Error:</blink> cHostname or cLabel already used at this"
2231                                                        " datacenter!");
2232                                }
2233                                mysql_free_result(res);
2234                                guMode=0;
2235
2236                                //Set the selected IP as not available upon modify
2237                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
2238                                                " WHERE uIP=%u AND uAvailable=1",uIPv4);
2239
2240                                //Optional change group.
2241                                if(uGroup)
2242                                        ChangeGroup(uContainer,uGroup);
2243                                               
2244                                mysql_query(&gMysql,gcQuery);
2245                                if(mysql_errno(&gMysql))
2246                                        htmlPlainTextError(mysql_error(&gMysql));
2247                                       
2248                                uModBy=guLoginClient;
2249                                ModtContainer();
2250                        }
2251                        else
2252                        {
2253                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2254                        }
2255                }
2256                else if(!strncmp(gcCommand,"Start ",6))
2257                {
2258                        ProcesstContainerVars(entries,x);
2259                        if(uStatus==uSTOPPED && uAllowMod(uOwner,uCreatedBy))
2260                        {
2261                                guMode=0;
2262
2263                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2264                                if(uModDate!=uActualModDate)
2265                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2266
2267                                if(CreateStartContainerJob(uDatacenter,uNode,uContainer,uOwner))
2268                                {
2269                                        uStatus=uAWAITACT;
2270                                        SetContainerStatus(uContainer,6);//Awaiting Activation
2271                                        //Since the above function changes the mod date
2272                                        //and we want to avoid frivoulous reload error msgs:
2273                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
2274                                        tContainer("CreateStartContainerJob() Done");
2275                                }
2276                                else
2277                                {
2278                                        tContainer("<blink>Error:</blink> No jobs created!");
2279                                }
2280                        }
2281                        else
2282                        {
2283                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2284                        }
2285                }
2286                else if(!strncmp(gcCommand,"Deploy ",7))
2287                {
2288                        ProcesstContainerVars(entries,x);
2289                        if(uStatus==uINITSETUP && uAllowMod(uOwner,uCreatedBy))
2290                        {
2291                                guMode=0;
2292
2293                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2294                                if(uModDate!=uActualModDate)
2295                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2296
2297                                if(CreateNewContainerJob(uDatacenter,uNode,uContainer,uOwner))
2298                                {
2299                                        uStatus=uAWAITACT;
2300                                        SetContainerStatus(uContainer,6);//Awaiting Activation
2301                                        //Since the above function changes the mod date
2302                                        //and we want to avoid frivoulous reload error msgs:
2303                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
2304                                        uModBy=guLoginClient;
2305                                        tContainer("CreateNewContainerJob() Done");
2306                                }
2307                                else
2308                                {
2309                                        tContainer("<blink>Error:</blink> No jobs created!");
2310                                }
2311                        }
2312                        else
2313                        {
2314                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2315                        }
2316                }
2317                else if(!strncmp(gcCommand,"Destroy ",8))
2318                {
2319                        ProcesstContainerVars(entries,x);
2320                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowDel(uOwner,uCreatedBy))
2321                        {
2322                                guMode=0;
2323                                       
2324                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2325                                if(uModDate!=uActualModDate)
2326                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2327
2328                                if(DestroyContainerJob(uDatacenter,uNode,uContainer,uOwner))
2329                                {
2330                                        uStatus=uAWAITDEL;
2331                                        SetContainerStatus(uContainer,5);//Awaiting Deletion
2332                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
2333                                        tContainer("DestroyContainerJob() Done");
2334                                }
2335                                else
2336                                {
2337                                        tContainer("<blink>Error:</blink> No jobs created!");
2338                                }
2339                        }
2340                        else
2341                        {
2342                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2343                        }
2344                }
2345                else if(!strncmp(gcCommand,"Stop ",5))
2346                {
2347                        ProcesstContainerVars(entries,x);
2348                        if(uStatus==uACTIVE && uAllowMod(uOwner,uCreatedBy))
2349                        {
2350                                guMode=0;
2351                                       
2352                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2353                                if(uModDate!=uActualModDate)
2354                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2355
2356                                if(StopContainerJob(uDatacenter,uNode,uContainer,guCompany))
2357                                {
2358                                        uStatus=uAWAITSTOP;
2359                                        SetContainerStatus(uContainer,41);//Awaiting Stop
2360                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
2361                                        tContainer("StopContainerJob() Done");
2362                                }
2363                                else
2364                                {
2365                                        tContainer("<blink>Error:</blink> No jobs created!");
2366                                }
2367                        }
2368                        else
2369                        {
2370                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2371                        }
2372                }
2373                else if(!strcmp(gcCommand,"Cancel Job"))
2374                {
2375                        ProcesstContainerVars(entries,x);
2376                        if(uAllowMod(uOwner,uCreatedBy))
2377                        {
2378                                guMode=0;
2379                                if(uStatus!=uAWAITDEL && uStatus!=uAWAITACT && uStatus!=uAWAITSTOP)
2380                                        tContainer("<blink>Error:</blink> Unexpected uStatus!");
2381
2382                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2383                                if(uModDate!=uActualModDate)
2384                                        tContainer("<blink>Error:</blink> This record was modified. Job may have run!");
2385
2386                                //Cancel any outstanding jobs.
2387                                if(CancelContainerJob(uDatacenter,uNode,uContainer,1))
2388                                {
2389                                        tContainer("<blink>Error:</blink> Unexpected no jobs canceled! Late?");
2390                                }
2391                                else
2392                                {
2393                                        if(uStatus==uAWAITDEL || uStatus==uAWAITSTOP)
2394                                        {
2395                                                uStatus=uACTIVE;
2396                                                SetContainerStatus(uContainer,1);//Awaiting Deletion/Stop to Active
2397                                        }
2398                                        else if(uStatus==uAWAITACT)
2399                                        {
2400                                                uStatus=uINITSETUP;
2401                                                SetContainerStatus(uContainer,uINITSETUP);//Awaiting Activation to Initial
2402                                        }
2403                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
2404                                        tContainer("CancelContainerJob() Done");
2405                                }
2406                        }
2407                        else
2408                        {
2409                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2410                        }
2411                }
2412                else if(!strcmp(gcCommand,"Create Action Scripts"))
2413                {
2414                        ProcesstContainerVars(entries,x);
2415                        if( (uStatus==uSTOPPED || uStatus==uINITSETUP ) && uAllowMod(uOwner,uCreatedBy))
2416                        {
2417                                guMode=0;
2418
2419                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2420                                if(uModDate!=uActualModDate)
2421                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2422
2423                                if(ActionScriptsJob(uDatacenter,uNode,uContainer))
2424                                {
2425                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
2426                                        tContainer("ActionScriptsJob() Done");
2427                                }
2428                                else
2429                                {
2430                                        tContainer("<blink>Error:</blink> No jobs created!"
2431                                                        " Make sure correct properties exist.");
2432                                }
2433                        }
2434                        else
2435                        {
2436                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2437                        }
2438                }
2439                else if(!strcmp(gcCommand,"Remote Clone Wizard"))
2440                {
2441                        ProcesstContainerVars(entries,x);
2442                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2443                        {
2444                                guMode=0;
2445
2446                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2447                                if(uModDate!=uActualModDate)
2448                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2449                               
2450                                if(uSource)
2451                                        tContainer("<blink>Error:</blink> No clones of clones allowed");
2452
2453                                guMode=11001;
2454                                tContainer("Select datacenter");
2455                        }
2456                        else
2457                        {
2458                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2459                        }
2460                }
2461                else if(!strcmp(gcCommand,"Select Clone Datacenter"))
2462                {
2463                        ProcesstContainerVars(entries,x);
2464                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2465                        {
2466                                guMode=0;
2467
2468                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2469                                if(uModDate!=uActualModDate)
2470                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2471                               
2472                                guMode=11001;
2473                                if(uSource)
2474                                        tContainer("<blink>Error:</blink> No clones of clones allowed");
2475                                if(uTargetDatacenter==uDatacenter)
2476                                        tContainer("<blink>Error:</blink> Can't remote clone to same datacenter");
2477
2478                                guMode=11002;
2479                                tContainer("Select node, uIPv4 and more");
2480                        }
2481                        else
2482                        {
2483                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2484                        }
2485                }
2486                else if(!strcmp(gcCommand,"Confirm Remote Clone"))
2487                {
2488                        ProcesstContainerVars(entries,x);
2489                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2490                        {
2491                                unsigned uNewVeid=0;
2492
2493                                guMode=0;
2494
2495                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2496                                if(uModDate!=uActualModDate)
2497                                        tContainer("<blink>Error:</blink> This record was modified. Reload it");
2498
2499                                guMode=11002;
2500                                if(uCloneStop>COLD_CLONE || uCloneStop<HOT_CLONE)
2501                                        tContainer("<blink>Error:</blink> Unexpected initial state");
2502                                if(uTargetNode==0)
2503                                        tContainer("<blink>Error:</blink> Please select a valid target node");
2504                                if(uTargetNode==uNode)
2505                                        tContainer("<blink>Error:</blink> Can't clone to same node");
2506                                if(uTargetDatacenter==uDatacenter)
2507                                        tContainer("<blink>Error:</blink> Can't remote clone to same datacenter");
2508                                if(uSource)
2509                                        tContainer("<blink>Error:</blink> No clones of clones allowed");
2510                                if(!uWizIPv4)
2511                                        tContainer("<blink>Error:</blink> You must select an IP");
2512                                sscanf(ForeignKey("tIP","uDatacenter",uWizIPv4),"%u",&uIPv4Datacenter);
2513                                if(uTargetDatacenter!=uIPv4Datacenter)
2514                                        tContainer("<blink>Error:</blink> The specified target uIPv4 does not "
2515                                                        "belong to the specified uDatacenter.");
2516                                if(!uOSTemplate || !uConfig || !uNameserver || !uSearchdomain || !uDatacenter || !uTargetDatacenter )
2517                                        tContainer("<blink>Error:</blink> Unexpected problem with missing source container"
2518                                                        " settings!");
2519                                if(uSyncPeriod>86400*30 || (uSyncPeriod && uSyncPeriod<300))
2520                                                tContainer("<blink>Error:</blink> Clone uSyncPeriod seconds out of range:"
2521                                                                " Max 30 days, min 5 minutes or 0 off.");
2522                                if(uVeth)
2523                                {
2524                                        GetNodeProp(uNode,"Container-Type",cContainerType);
2525                                        if(!strstr(cContainerType,"VETH"))
2526                                                tContainer("<blink>Error:</blink> uNode selected does not support VETH");
2527                                               
2528                                }
2529
2530                                //we don't allow extra remote clones on same node --seems to be no reason to do so
2531                                //      since you can always clone a local container if you need to make "copies."
2532                                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE uSource=%u AND uDatacenter=%u"
2533                                                        " AND uNode=%u",uContainer,uTargetDatacenter,uTargetNode);
2534                                mysql_query(&gMysql,gcQuery);
2535                                if(mysql_errno(&gMysql))
2536                                        htmlPlainTextError(mysql_error(&gMysql));
2537                                res=mysql_store_result(&gMysql);
2538                                if(mysql_num_rows(res))
2539                                        tContainer("<blink>Error:</blink> A clone of this container already exists on selected node");
2540                                mysql_free_result(res);
2541
2542                                //tContainer("debug break point");
2543
2544                                //Optional change group of source container.
2545                                if(uGroup)
2546                                        ChangeGroup(uContainer,uGroup);
2547
2548                                //This is needed to distinguish destroyed clone containers from
2549                                //initial setup clone containers for remote cold backup
2550                                if(uCloneStop==COLD_CLONE)
2551                                {
2552                                        sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
2553                                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
2554                                                ",cName='cSyncMode',cValue='Cold'",
2555                                                        uContainer,guCompany,guLoginClient);
2556                                        mysql_query(&gMysql,gcQuery);
2557                                        if(mysql_errno(&gMysql))
2558                                                htmlPlainTextError(mysql_error(&gMysql));
2559                                }
2560
2561                                //Set local global cWizHostname
2562                                //Insert clone container into tContainer
2563                                uNewVeid=CommonCloneContainer(
2564                                        uContainer,
2565                                        uOSTemplate,
2566                                        uConfig,
2567                                        uNameserver,
2568                                        uSearchdomain,
2569                                        uDatacenter,
2570                                        uTargetDatacenter,
2571                                        uOwner,
2572                                        cLabel,
2573                                        uNode,
2574                                        uStatus,
2575                                        cHostname,
2576                                        "",//Do not check Class C
2577                                        uWizIPv4,
2578                                        cWizLabel,
2579                                        cWizHostname,
2580                                        uTargetNode,
2581                                        uSyncPeriod,
2582                                        guLoginClient,
2583                                        uCloneStop,0);
2584
2585                                //Set group of clone to group of source.
2586                                uGroup=uGetGroup(0,uContainer);
2587                                if(uGroup)
2588                                        ChangeGroup(uNewVeid,uGroup);
2589                                guMode=0;
2590                                tContainer("CloneContainerJob() Done");
2591                        }
2592                        else
2593                        {
2594                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2595                        }
2596                }
2597                else if(!strcmp(gcCommand,"Clone Wizard"))
2598                {
2599                        ProcesstContainerVars(entries,x);
2600                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2601                        {
2602                                guMode=0;
2603
2604                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2605                                if(uModDate!=uActualModDate)
2606                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2607                               
2608                                guMode=7001;
2609                                tContainer("Select target node, uIPv4 and set other settings");
2610                        }
2611                        else
2612                        {
2613                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2614                        }
2615                }
2616                else if(!strcmp(gcCommand,"Confirm Clone"))
2617                {
2618                        ProcesstContainerVars(entries,x);
2619                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2620                        {
2621                                unsigned uNewVeid=0;
2622
2623                                guMode=0;
2624
2625                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2626                                if(uModDate!=uActualModDate)
2627                                        tContainer("<blink>Error:</blink> This record was modified. Reload it");
2628
2629                                guMode=7001;
2630                                if(uCloneStop>WARM_CLONE || uCloneStop<HOT_CLONE)
2631                                        tContainer("<blink>Error:</blink> Unexpected initial state");
2632                                if(uTargetNode==0)
2633                                        tContainer("<blink>Error:</blink> Please select a valid target node");
2634                                if(uTargetNode==uNode)
2635                                        tContainer("<blink>Error:</blink> Can't clone to same node");
2636                                if(uSource)
2637                                        tContainer("<blink>Error:</blink> No clones of clones allowed");
2638                                if(!uWizIPv4)
2639                                        tContainer("<blink>Error:</blink> You must select an IP");
2640                                sscanf(ForeignKey("tIP","uDatacenter",uWizIPv4),"%u",&uIPv4Datacenter);
2641                                if(uDatacenter!=uIPv4Datacenter)
2642                                        tContainer("<blink>Error:</blink> The specified target uIPv4 does not "
2643                                                        "belong to the specified uDatacenter.");
2644                                if(!uOSTemplate || !uConfig || !uNameserver || !uSearchdomain || !uDatacenter )
2645                                        tContainer("<blink>Error:</blink> Unexpected problem with missing source container"
2646                                                        " settings!");
2647                                if(uSyncPeriod>86400*30 || (uSyncPeriod && uSyncPeriod<300))
2648                                                tContainer("<blink>Error:</blink> Clone uSyncPeriod seconds out of range:"
2649                                                                " Max 30 days, min 5 minutes or 0 off.");
2650                                if(uVeth)
2651                                {
2652                                        GetNodeProp(uNode,"Container-Type",cContainerType);
2653                                        if(!strstr(cContainerType,"VETH"))
2654                                                tContainer("<blink>Error:</blink> uNode selected does not support VETH");
2655                                               
2656                                }
2657                                guMode=0;
2658
2659                                //Optional change group of source container.
2660                                if(uGroup)
2661                                        ChangeGroup(uContainer,uGroup);
2662
2663                                //Set local global cWizHostname
2664                                //Insert clone container into tContainer
2665                                uNewVeid=CommonCloneContainer(
2666                                        uContainer,
2667                                        uOSTemplate,
2668                                        uConfig,
2669                                        uNameserver,
2670                                        uSearchdomain,
2671                                        uDatacenter,
2672                                        uDatacenter,
2673                                        uOwner,
2674                                        cLabel,
2675                                        uNode,
2676                                        uStatus,
2677                                        cHostname,
2678                                        "",//Do not check Class C
2679                                        uWizIPv4,
2680                                        cWizLabel,
2681                                        cWizHostname,
2682                                        uTargetNode,
2683                                        uSyncPeriod,
2684                                        guLoginClient,
2685                                        uCloneStop,0);
2686
2687                                //Set group of clone to group of source.
2688                                uGroup=uGetGroup(0,uContainer);
2689                                if(uGroup)
2690                                        ChangeGroup(uNewVeid,uGroup);
2691                                tContainer("CloneContainerJob() Done");
2692                        }
2693                        else
2694                        {
2695                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2696                        }
2697                }
2698                else if(!strcmp(gcCommand,"Migration Wizard"))
2699                {
2700                        ProcesstContainerVars(entries,x);
2701                        if( (uStatus==uACTIVE || uStatus==uSTOPPED ) && uAllowMod(uOwner,uCreatedBy))
2702                        {
2703                                guMode=0;
2704
2705                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2706                                if(uModDate!=uActualModDate)
2707                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2708                                guMode=3001;
2709                                tContainer("Select Migration Target");
2710                        }
2711                        else
2712                        {
2713                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2714                        }
2715                }
2716                else if(!strcmp(gcCommand,"Confirm Migration"))
2717                {
2718                        ProcesstContainerVars(entries,x);
2719                        if( (uStatus==uACTIVE || uStatus==uSTOPPED ) && uAllowMod(uOwner,uCreatedBy))
2720                        {
2721                                unsigned uTargetDatacenter=0;
2722                                guMode=0;
2723
2724                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2725                                if(uModDate!=uActualModDate)
2726                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2727
2728                                guMode=3001;
2729                                if(uTargetNode==uNode)
2730                                        tContainer("<blink>Error:</blink> Can't migrate to same node. Try 'Template Wizard'");
2731                                if(uTargetNode==0)
2732                                        tContainer("<blink>Error:</blink> Please select a valid target node");
2733                                sscanf(ForeignKey("tNode","uDatacenter",uTargetNode),"%u",&uTargetDatacenter);
2734                                if(uTargetDatacenter!=uDatacenter)
2735                                        tContainer("<blink>Error:</blink> Can't migrate to different datacenter. Try 'Remote Migration'");
2736                                if(uVeth)
2737                                {
2738                                        GetNodeProp(uNode,"Container-Type",cContainerType);
2739                                        if(!strstr(cContainerType,"VETH"))
2740                                                tContainer("<blink>Error:</blink> uNode selected does not support VETH!");
2741                                               
2742                                }
2743                                guMode=0;
2744
2745                                //Optional change group.
2746                                if(uGroup)
2747                                        ChangeGroup(uContainer,uGroup);
2748
2749                                if(MigrateContainerJob(uDatacenter,uNode,uContainer,uTargetNode,uOwner,guLoginClient,0,uStatus))
2750                                {
2751                                        uStatus=uAWAITMIG;
2752                                        SetContainerStatus(uContainer,uAWAITMIG);//Awaiting Migration
2753                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
2754                                        tContainer("MigrateContainerJob() Done");
2755                                }
2756                                else
2757                                {
2758                                        tContainer("<blink>Error:</blink> No jobs created!");
2759                                }
2760                        }
2761                        else
2762                        {
2763                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2764                        }
2765                }
2766                else if(!strcmp(gcCommand,"Remote Migration"))
2767                {
2768                        ProcesstContainerVars(entries,x);
2769                        if( (uStatus==uACTIVE||uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2770                        {
2771                                guMode=0;
2772
2773                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2774                                if(uModDate!=uActualModDate)
2775                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2776                                guMode=10001;
2777                                tContainer("Select Migration Target");
2778                        }
2779                        else
2780                        {
2781                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2782                        }
2783                }
2784                else if(!strcmp(gcCommand,"Confirm Remote Migration"))
2785                {
2786                        ProcesstContainerVars(entries,x);
2787                        if( (uStatus==uACTIVE||uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2788                        {
2789                                unsigned uTargetDatacenter=0;
2790                                unsigned uIPv4Available=0;
2791                                guMode=0;
2792
2793                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2794                                if(uModDate!=uActualModDate)
2795                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2796
2797                                guMode=10001;
2798                                if(uTargetNode==uNode)
2799                                        tContainer("<blink>Error:</blink> Can't migrate to same node. Try 'Template Wizard'");
2800                                if(uTargetNode==0)
2801                                        tContainer("<blink>Error:</blink> Please select a valid target node");
2802                                sscanf(ForeignKey("tNode","uDatacenter",uTargetNode),"%u",&uTargetDatacenter);
2803                                if(uTargetDatacenter==uDatacenter)
2804                                        tContainer("<blink>Error:</blink> Can't migrate to same datacenter. Try 'Migration Wizard'");
2805                                if(uVeth)
2806                                {
2807                                        GetNodeProp(uNode,"Container-Type",cContainerType);
2808                                        if(!strstr(cContainerType,"VETH"))
2809                                                tContainer("<blink>Error:</blink> uNode selected does not support VETH!");
2810                                               
2811                                }
2812                                if(uIPv4==0)
2813                                        tContainer("<blink>Error:</blink> Unexpected current uIPv4");
2814                                if(uWizIPv4==0)
2815                                        tContainer("<blink>Error:</blink> Please select a valid uIPv4");
2816                                sscanf(ForeignKey("tIP","uDatacenter",uWizIPv4),"%u",&uIPv4Datacenter);
2817                                if(uTargetDatacenter!=uIPv4Datacenter)
2818                                        tContainer("<blink>Error:</blink> The specified uIPv4 does not "
2819                                                        "belong to the remote datacenter.");
2820                                sscanf(ForeignKey("tIP","uAvailable",uWizIPv4),"%u",&uIPv4Available);
2821                                if(!uIPv4Available)
2822                                        tContainer("<blink>Error:</blink> The specified uIPv4 is no longer"
2823                                                        "available, select another.");
2824
2825                                //External DNS job check
2826                                unsigned uHostnameLen=0;
2827                                cunxsBindARecordJobZone[0]=0;
2828                                GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
2829                                if(!cunxsBindARecordJobZone[0])
2830                                        tContainer("<blink>Error:</blink> Create job for unxsBind,"
2831                                                                " but no cunxsBindARecordJobZone");
2832
2833                                //This code should be compatible with new -clone hostname scheme
2834                                char cPrevHostname[100]={""};
2835                                if(uSource)
2836                                {
2837                                        char cSourceHostname[100]={""};
2838                                        char cWizLabel[33]={""};
2839                                        char cNewLabel[33]={""};
2840                                        char *cp=NULL;
2841                                        unsigned uWizLabelLoop=1;
2842                                        unsigned uWizLabelSuffix=0;
2843
2844                                        sprintf(cPrevHostname,"%s",cHostname);
2845
2846                                        sprintf(cLabel,"%.25s",ForeignKey("tContainer","cLabel",uSource));
2847                                        //Get first available <cLabel>-clone<uNum>
2848                                        while(uWizLabelLoop)
2849                                        {
2850                                                uWizLabelSuffix++;
2851                                                if(uWizLabelSuffix>9) tContainer("<blink>Error:</blink> Clone limit reached");
2852                                                sprintf(cWizLabel,"%.25s-clone%u",cLabel,uWizLabelSuffix);
2853                                                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE cLabel='%s'",cWizLabel);
2854                                                mysql_query(&gMysql,gcQuery);
2855                                                if(mysql_errno(&gMysql))
2856                                                        htmlPlainTextError(mysql_error(&gMysql));
2857                                                res=mysql_store_result(&gMysql);
2858                                                uWizLabelLoop=mysql_num_rows(res);
2859                                                mysql_free_result(res);
2860                                        }
2861                                        sprintf(cNewLabel,"%.25s-clone%u",cLabel,uWizLabelSuffix);
2862                                        sprintf(cLabel,"%.32s",cNewLabel);
2863
2864                                        sprintf(cSourceHostname,"%.99s",ForeignKey("tContainer","cHostname",uSource));
2865                                        if((cp=strchr(cSourceHostname,'.')))
2866                                        {
2867                                                sprintf(cHostname,"%.32s.%.64s",cLabel,cp+1);
2868                                        }
2869                                }
2870
2871                                uHostnameLen=strlen(cHostname);
2872                                if(!strstr(cHostname+(uHostnameLen-strlen(cunxsBindARecordJobZone)-1),cunxsBindARecordJobZone))
2873                                                tContainer("<blink>Error:</blink> cHostname must end with cunxsBindARecordJobZone");
2874                                if(uSource)
2875                                {
2876                                        sprintf(gcQuery,"UPDATE tContainer SET cHostname='%s',cLabel='%s'"
2877                                                                " WHERE uContainer=%u",cHostname,cLabel,uContainer);
2878                                        mysql_query(&gMysql,gcQuery);
2879                                        if(mysql_errno(&gMysql))
2880                                                htmlPlainTextError(mysql_error(&gMysql));
2881                                }
2882
2883                                guMode=0;
2884
2885                                //Optional change group.
2886                                if(uGroup)
2887                                        ChangeGroup(uContainer,uGroup);
2888
2889                                if(MigrateContainerJob(uDatacenter,uNode,uContainer,uTargetNode,uOwner,guLoginClient,uWizIPv4,uStatus))
2890                                {
2891                                        char cIPOld[32]={""};
2892
2893                                        uStatus=uAWAITMIG;
2894                                        SetContainerStatus(uContainer,uAWAITMIG);//Awaiting Migration
2895
2896                                        //Mark IP used
2897                                        sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
2898                                                                " WHERE uIP=%u and uAvailable=1",uWizIPv4);
2899                                        mysql_query(&gMysql,gcQuery);
2900                                        if(mysql_errno(&gMysql))
2901                                                htmlPlainTextError(mysql_error(&gMysql));
2902
2903                                        //Change container IP
2904                                        sprintf(gcQuery,"UPDATE tContainer SET uIPv4=%u"
2905                                                                " WHERE uContainer=%u",uWizIPv4,uContainer);
2906                                        mysql_query(&gMysql,gcQuery);
2907                                        if(mysql_errno(&gMysql))
2908                                                htmlPlainTextError(mysql_error(&gMysql));
2909
2910                                        //Create change IP job
2911                                        sprintf(cIPOld,"%.31s",ForeignKey("tIP","cLabel",uIPv4));
2912                                        if(!cIPOld[0])
2913                                                htmlPlainTextError("Unexpected !cIPOld");
2914
2915                                        //Note that these jobs are for new node
2916                                        //Then this job must run after migration.
2917                                        IPContainerJob(uTargetDatacenter,uTargetNode,uContainer,uOwner,guLoginClient,cIPOld);
2918                                        //Create unxsBind DNS
2919                                        CreateDNSJob(uWizIPv4,uOwner,NULL,cHostname,uDatacenter,guLoginClient);
2920
2921                                        //Create change hostname job
2922                                        if(uSource)
2923                                                HostnameContainerJob(uTargetDatacenter,uTargetNode,uContainer,cPrevHostname,uOwner,guLoginClient);
2924
2925                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
2926                                        tContainer("MigrateContainerJob() Done");
2927                                }
2928                                else
2929                                {
2930                                        tContainer("<blink>Error:</blink> No jobs created!");
2931                                }
2932                        }
2933                        else
2934                        {
2935                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2936                        }
2937                }
2938                else if(!strcmp(gcCommand,"Template Wizard"))
2939                {
2940                        ProcesstContainerVars(entries,x);
2941                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2942                        {
2943                                guMode=0;
2944
2945                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2946                                if(uModDate!=uActualModDate)
2947                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2948                                if(!uOSTemplate)
2949                                        tContainer("<blink>Error:</blink> No tOSTemplate.cLabel!");
2950                                guMode=4001;
2951                                tContainer("Select Template Name");
2952                        }
2953                        else
2954                        {
2955                                tContainer("<blink>Error:</blink> Denied by permissions settings");
2956                        }
2957                }
2958                else if(!strcmp(gcCommand,"Confirm Template"))
2959                {
2960                        ProcesstContainerVars(entries,x);
2961                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
2962                        {
2963                                MYSQL_ROW field;
2964                                char cOSTLabel[101]={""};
2965
2966                                guMode=0;
2967                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
2968                                if(uModDate!=uActualModDate)
2969                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
2970                                guMode=4001;
2971                                if(strlen(cConfigLabel)<2)
2972                                        tContainer("<blink>Error:</blink> Must provide valid tConfig.cLabel!");
2973                                if(strchr(cConfigLabel,'-'))
2974                                        tContainer("<blink>Error:</blink> tConfig.cLabel can't contain '-' chars!");
2975                                sprintf(gcQuery,"SELECT uConfig FROM tConfig WHERE cLabel='%s'",cConfigLabel);
2976                                mysql_query(&gMysql,gcQuery);
2977                                if(mysql_errno(&gMysql))
2978                                        htmlPlainTextError(mysql_error(&gMysql));
2979                                res=mysql_store_result(&gMysql);
2980                                if(mysql_num_rows(res)>0)
2981                                        tContainer("<blink>Error:</blink> tConfig.cLabel already exists create another!");
2982                                mysql_free_result(res);
2983                                sprintf(gcQuery,"SELECT cLabel FROM tOSTemplate WHERE uOSTemplate=%u",uOSTemplate);
2984                                mysql_query(&gMysql,gcQuery);
2985                                if(mysql_errno(&gMysql))
2986                                        htmlPlainTextError(mysql_error(&gMysql));
2987                                res=mysql_store_result(&gMysql);
2988                                if((field=mysql_fetch_row(res)))
2989                                        sprintf(cOSTLabel,"%.100s",field[0]);
2990                                else
2991                                        tContainer("<blink>Error:</blink> No tOSTemplate.cLabel!");
2992                                mysql_free_result(res);
2993                                sprintf(gcQuery,"SELECT uOSTemplate FROM tOSTemplate WHERE cLabel='%.67s-%.32s'",
2994                                                cOSTLabel,cConfigLabel);
2995                                mysql_query(&gMysql,gcQuery);
2996                                if(mysql_errno(&gMysql))
2997                                        htmlPlainTextError(mysql_error(&gMysql));
2998                                res=mysql_store_result(&gMysql);
2999                                if(mysql_num_rows(res)>0)
3000                                        tContainer("<blink>Error:</blink> tOSTemplate.cLabel collision."
3001                                                        " Select another tConfig.cLabel!");
3002                                mysql_free_result(res);
3003                                guMode=0;
3004                                if(TemplateContainerJob(uDatacenter,uNode,uContainer,uStatus,uOwner,cConfigLabel))
3005                                {
3006                                        uStatus=uAWAITTML;
3007                                        SetContainerStatus(uContainer,uStatus);
3008                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
3009                                        tContainer("TemplateContainerJob() Done");
3010                                }
3011                                else
3012                                {
3013                                        tContainer("<blink>Error:</blink> No jobs created!");
3014                                }
3015                        }
3016                        else
3017                        {
3018                                tContainer("<blink>Error:</blink> Denied by permissions settings");
3019                        }
3020                }
3021                else if(!strcmp(gcCommand,"Hostname Change Wizard"))
3022                {
3023                        ProcesstContainerVars(entries,x);
3024                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
3025                        {
3026                                guMode=0;
3027
3028                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
3029                                if(uModDate!=uActualModDate)
3030                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
3031                                guMode=5001;
3032                                tContainer("Provide container hostname and name");
3033                        }
3034                        else
3035                        {
3036                                tContainer("<blink>Error:</blink> Denied by permissions settings");
3037                        }
3038                }
3039                else if(!strcmp(gcCommand,"Confirm Hostname Change"))
3040                {
3041                        ProcesstContainerVars(entries,x);
3042                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
3043                        {
3044                                unsigned uHostnameLen=0;
3045                                unsigned uLabelLen=0;
3046
3047                                guMode=0;
3048                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
3049                                if(uModDate!=uActualModDate)
3050                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
3051                                guMode=5001;
3052                                if(!strcmp(cWizHostname,cHostname) && !strcmp(cWizLabel,cLabel))
3053                                        tContainer("<blink>Error:</blink> cHostname and cLabel are the same!");
3054                                if((uHostnameLen=strlen(cWizHostname))<5)
3055                                        tContainer("<blink>Error:</blink> cHostname too short!");
3056                                if((uLabelLen=strlen(cWizLabel))<2)
3057                                        tContainer("<blink>Error:</blink> cLabel too short!");
3058                                if(strchr(cWizLabel,'.'))
3059                                        tContainer("<blink>Error:</blink> cLabel has at least one '.'!");
3060                                if(strstr(cWizLabel,"-clone"))
3061                                        tContainer("<blink>Error:</blink> cLabel can't have '-clone'");
3062                                if(strstr(cWizHostname,"-clone"))
3063                                        tContainer("<blink>Error:</blink> cHostname can't have '-clone'");
3064                                //New rule: cLabel must be first part (first stop) of cHostname.
3065                                if(strncmp(cWizLabel,cWizHostname,uLabelLen))
3066                                        tContainer("<blink>Error:</blink> cLabel must be first part of cHostname.");
3067                                //DNS sanity check
3068                                if(uCreateDNSJob)
3069                                {
3070                                        cunxsBindARecordJobZone[0]=0;
3071                                        GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
3072                                        if(!cunxsBindARecordJobZone[0])
3073                                                tContainer("<blink>Error:</blink> Create job for unxsBind,"
3074                                                                " but no cunxsBindARecordJobZone");
3075                                       
3076                                        if(!strstr(cWizHostname+(uHostnameLen-strlen(cunxsBindARecordJobZone)-1),cunxsBindARecordJobZone))
3077                                                tContainer("<blink>Error:</blink> cHostname must end with cunxsBindARecordJobZone");
3078                                }
3079                                //No same names or hostnames for same XXXdatacenterXXX -now global restriction- allowed.
3080                                sprintf(gcQuery,"SELECT uContainer,uStatus,uIPv4 FROM tContainer WHERE (cHostname='%s' OR cLabel='%s')"
3081                                                " AND uContainer!=%u",
3082                                                        cWizHostname,cWizLabel,uContainer);
3083                                mysql_query(&gMysql,gcQuery);
3084                                if(mysql_errno(&gMysql))
3085                                                htmlPlainTextError(mysql_error(&gMysql));
3086                                res=mysql_store_result(&gMysql);
3087                                if(mysql_num_rows(res)>0)
3088                                {
3089                                        unsigned uOfflineContainer=0;
3090                                        unsigned uOfflineStatusCheck=0;
3091                                        unsigned uOfflineIPv4=0;
3092                                        MYSQL_ROW field;
3093
3094                                        if((field=mysql_fetch_row(res)))
3095                                        {
3096                                                sscanf(field[0],"%u",&uOfflineContainer);
3097                                                sscanf(field[1],"%u",&uOfflineStatusCheck);
3098                                                sscanf(field[2],"%u",&uOfflineIPv4);
3099                                        }
3100                                        if(uOfflineStatusCheck==uOFFLINE && uOfflineContainer)
3101                                        {
3102                                                //Delete offline container with same name as
3103                                                //the change to name. Only the first one is removed for now.
3104                                                //Release IPs
3105                                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=1"
3106                                                                " WHERE uIP=%u and uAvailable=0",uOfflineIPv4);
3107                                                mysql_query(&gMysql,gcQuery);
3108                                                if(mysql_errno(&gMysql))
3109                                                        htmlPlainTextError(mysql_error(&gMysql));
3110                                                //Now we can remove properties
3111                                                DelProperties(uOfflineContainer,3);
3112                                                //Remove from any groups
3113                                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uContainer=%u",uOfflineContainer);//Ok to remove
3114                                                mysql_query(&gMysql,gcQuery);
3115                                                if(mysql_errno(&gMysql))
3116                                                        htmlPlainTextError(mysql_error(&gMysql));
3117                                                sprintf(gcQuery,"DELETE FROM tContainer WHERE uContainer=%u",uOfflineContainer);
3118                                                mysql_query(&gMysql,gcQuery);
3119                                                if(mysql_errno(&gMysql))
3120                                                        htmlPlainTextError(mysql_error(&gMysql));
3121                                        }
3122                                        else
3123                                        {
3124                                                mysql_free_result(res);
3125                                                tContainer("<blink>Error:</blink> cHostname or cLabel already used"
3126                                                        " in this unxsVZ system!");
3127                                        }
3128                                }
3129                                mysql_free_result(res);
3130
3131                                guMode=0;
3132                                //Optional change group.
3133                                if(uGroup)
3134                                        ChangeGroup(uContainer,uGroup);
3135
3136                                sprintf(gcQuery,"UPDATE tContainer SET cLabel='%s',cHostname='%s'"
3137                                                " WHERE uContainer=%u",cWizLabel,cWizHostname,uContainer);
3138                                mysql_query(&gMysql,gcQuery);
3139                                if(mysql_errno(&gMysql))
3140                                        htmlPlainTextError(mysql_error(&gMysql));
3141                                sprintf(cLabel,"%.31s",cWizLabel);
3142                                char cPrevHostname[100]={""};
3143                                sprintf(cPrevHostname,"%.99s",cHostname);
3144                                sprintf(cHostname,"%.99s",cWizHostname);
3145                                if(uCreateDNSJob)
3146                                        CreateDNSJob(uIPv4,uOwner,NULL,cHostname,uDatacenter,guLoginClient);
3147                                if(HostnameContainerJob(uDatacenter,uNode,uContainer,cPrevHostname,uOwner,guLoginClient))
3148                                {
3149                                        uStatus=uAWAITHOST;
3150                                        SetContainerStatus(uContainer,61);
3151                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
3152                                        tContainer("HostnameContainerJob() Done");
3153                                }
3154                                else
3155                                {
3156                                        tContainer("<blink>Error:</blink> No jobs created!");
3157                                }
3158                        }
3159                        else
3160                        {
3161                                tContainer("<blink>Error:</blink> Denied by permissions settings");
3162                        }
3163                }
3164                else if(!strcmp(gcCommand,"IP Change Wizard"))
3165                {
3166                        ProcesstContainerVars(entries,x);
3167                        if(uStatus==uACTIVE && uAllowMod(uOwner,uCreatedBy))
3168                        {
3169                                guMode=0;
3170
3171                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
3172                                if(uModDate!=uActualModDate)
3173                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
3174                                guMode=6001;
3175                                tContainer("Select new IPv4");
3176                        }
3177                        else
3178                        {
3179                                tContainer("<blink>Error:</blink> Denied by permissions settings");
3180                        }
3181                }
3182                else if(!strcmp(gcCommand,"Confirm IP Change"))
3183                {
3184                        ProcesstContainerVars(entries,x);
3185                        if(uStatus==uACTIVE && uAllowMod(uOwner,uCreatedBy))
3186                        {
3187                                guMode=0;
3188                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
3189                                if(uModDate!=uActualModDate)
3190                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
3191                                guMode=6001;
3192
3193                                if(uWizIPv4 && uWizContainer)
3194                                        tContainer("<blink>Error:</blink> You must select either a swap or a new IP not both!");
3195                                if(!uWizIPv4 && !uWizContainer)
3196                                        tContainer("<blink>Error:</blink> You must select an IP or a container to swap with!");
3197                                if(uContainer==uWizContainer)
3198                                        tContainer("<blink>Error:</blink> You can't swap with the same container!");
3199                                if(uWizIPv4)
3200                                {
3201                                        sscanf(ForeignKey("tIP","uDatacenter",uWizIPv4),"%u",&uIPv4Datacenter);
3202                                        if(uDatacenter!=uIPv4Datacenter)
3203                                                tContainer("<blink>Error:</blink> The specified target uIPv4 does not "
3204                                                        "belong to the specified uDatacenter.");
3205                                }
3206                                else if(uWizContainer)
3207                                {
3208                                        if(uVeth)
3209                                                tContainer("<blink>Error:</blink> VETH device network containers"
3210                                                                        " not supported at this time!");
3211                                        sscanf(ForeignKey("tContainer","uDatacenter",uWizContainer),"%u",&uIPv4Datacenter);
3212                                        if(uDatacenter!=uIPv4Datacenter)
3213                                                tContainer("<blink>Error:</blink> The specified swap container does not "
3214                                                        "belong to the same datacenter.");
3215                                        //we reuse uWizIPv4 for swap method
3216                                        uIPv4Datacenter=0;
3217                                        sscanf(ForeignKey("tContainer","uIPv4",uWizContainer),"%u",&uWizIPv4);
3218                                        sscanf(ForeignKey("tIP","uDatacenter",uWizIPv4),"%u",&uIPv4Datacenter);
3219                                        if(uDatacenter!=uIPv4Datacenter)
3220                                                tContainer("<blink>Error:</blink> The specified target uIPv4 does not "
3221                                                        "belong to the specified uDatacenter.");
3222                                }
3223
3224                                //tContainer("This function is not available yet!");
3225
3226                                unsigned uOldIPv4=0;
3227                                char cIPOld[32]={""};
3228
3229                                if(!uWizContainer)
3230                                {
3231                                        unsigned uHostnameLen=0;
3232                                        unsigned uAvailable=0;
3233
3234                                        //Basic direct IP change
3235                                        sscanf(ForeignKey("tIP","uAvailable",uWizIPv4),"%u",&uAvailable);
3236                                        if(!uAvailable)
3237                                                tContainer("<blink>Error:</blink> The uIPv4 selected is not available anymore!");
3238                                        //DNS sanity check
3239                                        if(uCreateDNSJob)
3240                                        {
3241                                                cunxsBindARecordJobZone[0]=0;
3242                                                GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
3243                                                if(!cunxsBindARecordJobZone[0])
3244                                                        tContainer("<blink>Error:</blink> Create job for unxsBind,"
3245                                                                        " but no cunxsBindARecordJobZone");
3246                                       
3247                                                uHostnameLen=strlen(cHostname);
3248                                                if(!strstr(cHostname+(uHostnameLen-strlen(cunxsBindARecordJobZone)-1),
3249                                                        cunxsBindARecordJobZone))
3250                                                        tContainer("<blink>Error:</blink> cHostname must end with cunxsBindARecordJobZone");
3251                                        }
3252                                        guMode=0;
3253                                        //Fatal error section
3254                                        sscanf(ForeignKey("tContainer","uIPv4",uContainer),"%u",&uOldIPv4);
3255                                        if(!uOldIPv4)
3256                                                htmlPlainTextError("Unexpected !uIPv4 and !uOldIPv4");
3257                                        sprintf(cIPOld,"%.31s",ForeignKey("tIP","cLabel",uOldIPv4));
3258                                        if(!cIPOld[0])
3259                                                htmlPlainTextError("Unexpected !cIPOld");
3260       
3261                                        //New uIPv4
3262                                        sprintf(gcQuery,"UPDATE tContainer SET uIPv4=%u"
3263                                                        " WHERE uContainer=%u",uWizIPv4,uContainer);
3264                                        mysql_query(&gMysql,gcQuery);
3265                                        if(mysql_errno(&gMysql))
3266                                                htmlPlainTextError(mysql_error(&gMysql));
3267                                        sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
3268                                                        " WHERE uIP=%u",uWizIPv4);
3269                                        mysql_query(&gMysql,gcQuery);
3270                                        if(mysql_errno(&gMysql))
3271                                                        htmlPlainTextError(mysql_error(&gMysql));
3272                                        //Optional change group.
3273                                        if(uGroup)
3274                                                ChangeGroup(uContainer,uGroup);
3275                                        uIPv4=uWizIPv4;
3276                                        if(IPContainerJob(uDatacenter,uNode,uContainer,uOwner,guLoginClient,cIPOld))
3277                                        {
3278                                                uStatus=uAWAITIP;
3279                                                SetContainerStatus(uContainer,71);
3280                                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
3281                                                if(uCreateDNSJob)
3282                                                        CreateDNSJob(uIPv4,uOwner,cuWizIPv4PullDown,cHostname,uDatacenter,guLoginClient);
3283                                                tContainer("IPContainerJob() Done");
3284                                        }
3285                                        else
3286                                        {
3287                                                tContainer("<blink>Error:</blink> No jobs created!");
3288                                        }
3289                                }
3290                                else
3291                                {
3292                                        //Swap IP with selected uWizContainer
3293                                        unsigned uSwapNode=0;
3294
3295                                        //Modify tContainer
3296                                        //Optional: Create two DNS
3297                                        //Optional: Change group for both containers. Study this.
3298                                        //Create two IP Container jobs
3299
3300                                        //Return to main container tab
3301                                        guMode=0;
3302
3303                                        //Two cases swap same node, swap different nodes
3304                                        sscanf(ForeignKey("tContainer","uNode",uWizContainer),"%u",&uSwapNode);
3305                                        if(uNode!=uSwapNode)
3306                                        {
3307
3308                                                //Fatal error section loaded container
3309                                                sscanf(ForeignKey("tContainer","uIPv4",uContainer),"%u",&uOldIPv4);
3310                                                if(!uOldIPv4)
3311                                                        htmlPlainTextError("Unexpected !uIPv4 and !uOldIPv4");
3312                                                sprintf(cIPOld,"%.31s",ForeignKey("tIP","cLabel",uOldIPv4));
3313                                                if(!cIPOld[0])
3314                                                        htmlPlainTextError("Unexpected !cIPOld");
3315                                                sprintf(cuWizIPv4PullDown,"%.31s",ForeignKey("tIP","cLabel",uWizIPv4));
3316                                                if(!cuWizIPv4PullDown[0])
3317                                                        htmlPlainTextError("Unexpected !cuWizIPv4PullDown");
3318
3319                                                //New uIPv4
3320                                                sprintf(gcQuery,"UPDATE tContainer SET uIPv4=%u"
3321                                                                " WHERE uContainer=%u",uWizIPv4,uContainer);
3322                                                mysql_query(&gMysql,gcQuery);
3323                                                if(mysql_errno(&gMysql))
3324                                                        htmlPlainTextError(mysql_error(&gMysql));
3325                                                //Optional change group.
3326                                                if(uGroup)
3327                                                        ChangeGroup(uContainer,uGroup);
3328
3329
3330                                                if(IPContainerJob(uDatacenter,uNode,uContainer,uOwner,guLoginClient,cIPOld))
3331                                                {
3332                                                        uStatus=uAWAITIP;
3333                                                        SetContainerStatus(uContainer,71);
3334                                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
3335                                                        if(uCreateDNSJob)
3336                                                                CreateDNSJob(uWizIPv4,uOwner,cuWizIPv4PullDown,
3337                                                                        cHostname,uDatacenter,guLoginClient);
3338                                                }
3339                                                else
3340                                                {
3341                                                        tContainer("<blink>Error:</blink> No jobs created!");
3342                                                }
3343       
3344                                                //Fatal error section swap container
3345                                                sscanf(ForeignKey("tContainer","uIPv4",uWizContainer),"%u",&uOldIPv4);
3346                                                if(!uOldIPv4)
3347                                                        htmlPlainTextError("Unexpected !uIPv4 and !uOldIPv4");
3348                                                sprintf(cIPOld,"%.31s",ForeignKey("tIP","cLabel",uOldIPv4));
3349                                                if(!cIPOld[0])
3350                                                        htmlPlainTextError("Unexpected !cIPOld");
3351                                                sprintf(cuWizIPv4PullDown,"%.31s",ForeignKey("tIP","cLabel",uIPv4));
3352                                                if(!cuWizIPv4PullDown[0])
3353                                                        htmlPlainTextError("Unexpected !cuWizIPv4PullDown");
3354       
3355               
3356                                                //New uIPv4 for swap container
3357                                                sprintf(gcQuery,"UPDATE tContainer SET uIPv4=%u"
3358                                                                " WHERE uContainer=%u",uIPv4,uWizContainer);
3359                                                mysql_query(&gMysql,gcQuery);
3360                                                if(mysql_errno(&gMysql))
3361                                                        htmlPlainTextError(mysql_error(&gMysql));
3362                                                //Optional change group.
3363                                                if(uGroup)
3364                                                        ChangeGroup(uWizContainer,uGroup);
3365                                                uIPv4=uWizIPv4;
3366                                                if(IPContainerJob(uDatacenter,uSwapNode,uWizContainer,uOwner,guLoginClient,cIPOld))
3367                                                {
3368                                                        uStatus=uAWAITIP;
3369                                                        SetContainerStatus(uWizContainer,71);
3370                                                        if(uCreateDNSJob)
3371                                                        {
3372                                                                CreateDNSJob(uIPv4,uOwner,cuWizIPv4PullDown,
3373                                                                                ForeignKey("tContainer","cHostname",uWizContainer),
3374                                                                                        uDatacenter,guLoginClient);
3375                                                        }
3376                                                        tContainer("IPContainerJob() Done.");
3377                                                }
3378                                                else
3379                                                {
3380                                                        tContainer("<blink>Error:</blink> No swap container jobs created! Check tJob.");
3381                                                }
3382       
3383                                        }
3384                                        else
3385                                        {
3386                                                unsigned uWizOldIPv4=0;
3387                                                char cWizIPOld[32]={""};
3388
3389                                                //Fatal error section
3390                                                //Return to main container tab
3391                                                guMode=0;
3392
3393                                                sscanf(ForeignKey("tContainer","uIPv4",uContainer),"%u",&uOldIPv4);
3394                                                if(!uOldIPv4)
3395                                                        htmlPlainTextError("Unexpected !uOldIPv4");
3396                                                sprintf(cIPOld,"%.31s",ForeignKey("tIP","cLabel",uOldIPv4));
3397                                                if(!cIPOld[0])
3398                                                        htmlPlainTextError("Unexpected !cIPOld");
3399                                                sscanf(ForeignKey("tContainer","uIPv4",uWizContainer),"%u",&uWizOldIPv4);
3400                                                if(!uWizOldIPv4)
3401                                                        htmlPlainTextError("Unexpected !uWizOldIPv4");
3402                                                sprintf(cWizIPOld,"%.31s",ForeignKey("tIP","cLabel",uWizOldIPv4));
3403                                                if(!cWizIPOld[0])
3404                                                        htmlPlainTextError("Unexpected !cWizIPOld");
3405                                                sprintf(cuWizIPv4PullDown,"%.31s",ForeignKey("tIP","cLabel",uWizIPv4));
3406                                                if(!cuWizIPv4PullDown[0])
3407                                                        htmlPlainTextError("Unexpected !cuWizIPv4PullDown");
3408
3409                                                //tContainer(cIPOld);
3410                                                //tContainer(cWizIPOld);
3411                                                //tContainer(cuWizIPv4PullDown);
3412
3413                                                //Swap IPs in tContainer
3414                                                sprintf(gcQuery,"UPDATE tContainer SET uIPv4=%u"
3415                                                                " WHERE uContainer=%u",uWizIPv4,uContainer);
3416                                                mysql_query(&gMysql,gcQuery);
3417                                                if(mysql_errno(&gMysql))
3418                                                        htmlPlainTextError(mysql_error(&gMysql));
3419                                                sprintf(gcQuery,"UPDATE tContainer SET uIPv4=%u"
3420                                                                " WHERE uContainer=%u",uIPv4,uWizContainer);
3421                                                mysql_query(&gMysql,gcQuery);
3422                                                if(mysql_errno(&gMysql))
3423                                                        htmlPlainTextError(mysql_error(&gMysql));
3424                                                //Optional change group.
3425                                                if(uGroup)
3426                                                {
3427                                                        ChangeGroup(uContainer,uGroup);
3428                                                        ChangeGroup(uWizContainer,uGroup);
3429                                                }
3430
3431                                                if(IPSameNodeContainerJob(uDatacenter,uNode,uContainer,uWizContainer,
3432                                                                                        uOwner,guLoginClient,cIPOld,cWizIPOld))
3433                                                {
3434                                                        //Update displayed data
3435                                                        uStatus=uAWAITIP;
3436                                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
3437
3438                                                        SetContainerStatus(uContainer,uAWAITIP);
3439                                                        SetContainerStatus(uWizContainer,uAWAITIP);
3440                                                        if(uCreateDNSJob)
3441                                                        {
3442                                                                CreateDNSJob(uWizIPv4,uOwner,cuWizIPv4PullDown,
3443                                                                        cHostname,uDatacenter,guLoginClient);
3444                                                                CreateDNSJob(uIPv4,uOwner,
3445                                                                                ForeignKey("tIP","cLabel",uIPv4),
3446                                                                                ForeignKey("tContainer","cHostname",uWizContainer),
3447                                                                                        uDatacenter,guLoginClient);
3448                                                        }
3449                                                        tContainer("SwapIPContainer job created");
3450                                                }
3451                                                else
3452                                                {
3453                                                        tContainer("<blink>Error:</blink> No jobs created!");
3454                                                }
3455                                        }
3456                                }
3457                        }
3458                        else
3459                        {
3460                                tContainer("<blink>Error:</blink> Denied by permissions settings");
3461                        }
3462                }
3463                else if(!strncmp(gcCommand,"Switchover",10))
3464                {
3465                        ProcesstContainerVars(entries,x);
3466                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
3467                        {
3468                                guMode=0;
3469
3470                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
3471                                if(uModDate!=uActualModDate)
3472                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
3473                                if(!uDatacenter)
3474                                        tContainer("<blink>Error:</blink> Unexpected lack of uDatacenter.");
3475                                if(!uNode)
3476                                        tContainer("<blink>Error:</blink> Unexpected lack of uNode.");
3477                                if(!uSource)
3478                                        tContainer("<blink>Error:</blink> Unexpected lack of uSource.");
3479                                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE uContainer=%u AND"
3480                                                " (uStatus=1 OR uStatus=31 OR uStatus=41)",uSource);
3481                                mysql_query(&gMysql,gcQuery);
3482                                if(mysql_errno(&gMysql))
3483                                                htmlPlainTextError(mysql_error(&gMysql));
3484                                res=mysql_store_result(&gMysql);
3485                                if(mysql_num_rows(res)==0)
3486                                        tContainer("<blink>Error:</blink> Unexpected source container status!");
3487                                guMode=8001;
3488                                tContainer("Review and confirm");
3489                        }
3490                        else
3491                        {
3492                                tContainer("<blink>Error:</blink> Denied by permissions settings");
3493                        }
3494                }
3495                else if(!strncmp(gcCommand,"Confirm Switchover",18))
3496                {
3497                        ProcesstContainerVars(entries,x);
3498                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowMod(uOwner,uCreatedBy))
3499                        {
3500                                unsigned uDebug=0;
3501                                if(strstr(gcCommand+18,"Debug")) uDebug=1;
3502
3503                                guMode=0;
3504                                sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uActualModDate);
3505                                if(uModDate!=uActualModDate)
3506                                        tContainer("<blink>Error:</blink> This record was modified. Reload it.");
3507                                guMode=8001;
3508                                if(!uSource)
3509                                        tContainer("<blink>Error:</blink> Unexpected lack of uSource!");
3510                                if(!uDatacenter)
3511                                        tContainer("<blink>Error:</blink> Unexpected lack of uDatacenter.");
3512                                if(!uNode)
3513                                        tContainer("<blink>Error:</blink> Unexpected lack of uNode.");
3514                                if(!cLabel[0])
3515                                        tContainer("<blink>Error:</blink> Unexpected lack of cLabel.");
3516                                if(!cHostname[0])
3517                                        tContainer("<blink>Error:</blink> Unexpected lack of cHostname.");
3518                                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE uContainer=%u AND"
3519                                                " (uStatus=1 OR uStatus=31 OR uStatus=41)",uSource);
3520                                mysql_query(&gMysql,gcQuery);
3521                                if(mysql_errno(&gMysql))
3522                                                htmlPlainTextError(mysql_error(&gMysql));
3523                                res=mysql_store_result(&gMysql);
3524                                if(mysql_num_rows(res)==0)
3525                                        tContainer("<blink>Error:</blink> Unexpected source container status!");
3526                                guMode=0;
3527
3528                                unsigned uFailToJob=0;
3529                                if((uFailToJob=FailoverToJob(uDatacenter,uNode,uContainer,uOwner,guLoginClient,uDebug)))
3530                                {
3531                                        unsigned uSourceDatacenter=0;
3532                                        unsigned uSourceNode=0;
3533
3534                                        sscanf(ForeignKey("tContainer","uDatacenter",uSource),"%u",&uSourceDatacenter);
3535                                        sscanf(ForeignKey("tContainer","uNode",uSource),"%u",&uSourceNode);
3536
3537//These two jobs are always done in pairs. Even though the second may run much later
3538//for example after hardware failure has been fixed.
3539                                        if(FailoverFromJob(uSourceDatacenter,uSourceNode,uSource,uIPv4,
3540                                                        cLabel,cHostname,uContainer,uStatus,uFailToJob,uOwner,guLoginClient,uDebug))
3541                                        {
3542                                                if(!uDebug)
3543                                                {
3544                                                        uStatus=uAWAITFAIL;
3545                                                        SetContainerStatus(uContainer,uAWAITFAIL);
3546                                                        SetContainerStatus(uSource,uAWAITFAIL);
3547                                                        sscanf(ForeignKey("tContainer","uModDate",uContainer),"%lu",&uModDate);
3548                                                        //Make sure group is the same as source
3549                                                        unsigned uGroup=uGetGroup(0,uSource);
3550                                                        if(uGroup)
3551                                                                ChangeGroup(uContainer,uGroup);
3552                                                        tContainer("FailoverJob() Done");
3553                                                }
3554                                                else
3555                                                {
3556                                                        tContainer("Debug FailoverJob() Done");
3557                                                }
3558                                        }
3559                                        else
3560                                        {
3561                                                tContainer("<blink>Error:</blink> No FailoverFromJob() created!");
3562                                        }
3563                                }
3564                                else
3565                                {
3566                                        tContainer("<blink>Error:</blink> No FailoverToJob created!");
3567                                }
3568                        }
3569                        else
3570                        {
3571                                tContainer("<blink>Error:</blink> Denied by permissions settings");
3572                        }
3573                }
3574                else if(!strncmp(gcCommand,"Set ",4) || !strncmp(gcCommand,"Group ",6) || !strncmp(gcCommand,"Delete Checked",14))
3575                {
3576                        ProcesstContainerVars(entries,x);
3577                        guMode=12002;
3578                        tContainer(gcCommand);
3579                }
3580        }
3581
3582}//void ExttContainerCommands(pentry entries[], int x)
3583
3584
3585void ExttContainerButtons(void)
3586{
3587
3588        OpenFieldSet("tContainer Aux Panel",100);
3589        switch(guMode)
3590        {
3591                case 6001:
3592                        printf("<p><u>IP Change Wizard</u><br>");
3593                        printf("Here you will can change the container's IPv4 number."
3594                                " <p>Container services may be affected or need reconfiguration for new IP.\n");
3595                        printf("<p>Select new IPv4<br>");
3596                        tTablePullDownOwnerAvailDatacenter("tIP;cuWizIPv4PullDown","cLabel","cLabel",uWizIPv4,1,
3597                                uDatacenter,uOwner);
3598                        printf("<p>Or swap IPs with this container<br>");
3599                        tTablePullDownDatacenter("tContainer;cuWizContainerPullDown","cLabel","cLabel",uWizContainer,1,
3600                                        cuWizContainerPullDown,0,uDatacenter);
3601                        printf("<p><input title='Create an IP change job for the current container'"
3602                                        " type=submit class=lwarnButton"
3603                                        " name=gcCommand value='Confirm IP Change'>\n");
3604                        printf("<p>Optional primary group change (if swap changes for both)<br>");
3605                        //uGroup=uGetGroup(0,uContainer);//0=not for node
3606                        tContainerGroupPullDown(uChangeGroup,1);
3607                        GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
3608                        if(cunxsBindARecordJobZone[0])
3609                        {
3610                                printf("<p>Create job(s) for unxsBind A record(s)<br>");
3611                                printf("<input type=checkbox name=uCreateDNSJob >");
3612                        }
3613                break;
3614
3615                case 5001:
3616                        printf("<p><u>Hostname Change Wizard</u><br>");
3617                        printf("Here you will change the container label (name) and hostname."
3618                                " The container will not be stopped. Only operations depending on the /etc/hosts file"
3619                                " and the hostname may be affected. It is required that cLabel be the first part"
3620                                " of the cHostname. If an offline container with same target name exists it will be"
3621                                " deleted, to help with multi node system migration. <p>\n");
3622                        printf("<p>New cLabel<br>");
3623                        printf("<input title='Short container name, almost always the first part of cHostname'"
3624                                        " type=text name=cWizLabel maxlength=31 value='%s'>\n",cLabel);
3625                        printf("<p>New cHostname<br>");
3626                        printf("<input title='FQDN container hostname, usually a DNS resolvable host.'"
3627                                        " type=text name=cWizHostname maxlength=99 value='%.99s'>\n",cHostname);
3628                        printf("<p><input title='Create a hostname change job for the current container'"
3629                                        " type=submit class=lwarnButton"
3630                                        " name=gcCommand value='Confirm Hostname Change'>\n");
3631                        printf("<p>Optional primary group change<br>");
3632                        uGroup=uGetGroup(0,uContainer);//0=not for node
3633                        tContainerGroupPullDown(uChangeGroup,1);
3634                        GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
3635                        if(cunxsBindARecordJobZone[0])
3636                        {
3637                                printf("<p>Create job for unxsBind A record<br>");
3638                                printf("<input type=checkbox name=uCreateDNSJob >");
3639                        }
3640                break;
3641
3642                case 4001:
3643                        printf("<p><u>Template Wizard</u><br>");
3644                        printf("Here you will select the tConfig.cLabel. This label will be"
3645                                " be used to create a new OS template based on the source container's OS template"
3646                                " and the tConfig.cLabel as a dash suffix. This label will also be used for a new"
3647                                " VZ conf file.<p>If you are not using LVM: <font color=red>!The container"
3648                                " will be stopped for several minutes!</font>"
3649                                "<p>When the job is finished the tOSTemplate.cLabel and it's associated base conf file"
3650                                " (tConfig.cLabel) will be available on every hardware node for immediate use"
3651                                " (the /usr/sbin/allnodescp.sh has to be installed and configured correctly.)"
3652                                " The all node /vz/template/cache/ file that is created can also be likened"
3653                                " to a snapshot backup of the running container.<p>\n");
3654                        printf("<p>tConfig.cLabel<br>");
3655                        printf("<input title='tOSTemplate tail and tConfig label will be set to"
3656                                        " the name provided.' type=text name=cConfigLabel maxlength=32>\n");
3657                        printf("<p><input title='Create a template job for the current container'"
3658                                        " type=submit class=lwarnButton"
3659                                        " name=gcCommand value='Confirm Template'>\n");
3660                break;
3661
3662                case 3001:
3663                        printf("<p><u>Migration Wizard</u><br>");
3664                        printf("Here you will select the hardware node target (must be different from the current one.)"
3665                                " If the selected node is"
3666                                " oversubscribed, not available, or scheduled for maintenance. You will"
3667                                " be informed at the next step\n<p>\n");
3668                        printf("<p>Target node<br>");
3669                        tTablePullDown("tNode;cuTargetNodePullDown","cLabel","cLabel",uTargetNode,1);
3670                        printf("<p>Optional primary group change<br>");
3671                        uGroup=uGetGroup(0,uContainer);//0=not for node
3672                        tContainerGroupPullDown(uChangeGroup,1);
3673                        printf("<p><input title='Create a migration job for the current container'"
3674                                        " type=submit class=largeButton"
3675                                        " name=gcCommand value='Confirm Migration'>\n");
3676                break;
3677
3678                case 10001:
3679                        printf("<p><u>Remote Migration</u><br>");
3680                        printf("Here you will select the hardware node target (must be on a different datacenter.)"
3681                                " If the selected node is"
3682                                " oversubscribed, not available, or scheduled for maintenance. You will"
3683                                " be informed at the next step\n<p>\n");
3684                        printf("<p>Target node<br>");
3685                        tTablePullDown("tNode;cuTargetNodePullDown","cLabel","cLabel",uTargetNode,1);
3686                        printf("<p>Select new IPv4<br>");
3687                        tTablePullDownAvail("tIP;cuWizIPv4PullDown","cLabel","cLabel",uWizIPv4,1);
3688                        printf("<p>Optional primary group change<br>");
3689                        uGroup=uGetGroup(0,uContainer);//0=not for node
3690                        tContainerGroupPullDown(uChangeGroup,1);
3691                        printf("<p><input title='Create a migration job for the current container'"
3692                                        " type=submit class=largeButton"
3693                                        " name=gcCommand value='Confirm Remote Migration'>\n");
3694                break;
3695
3696                case 7001:
3697                        printf("<p><u>Clone Wizard</u><br>");
3698                        printf("Here you will select the hardware node target. If the selected node is"
3699                                " oversubscribed, not available, or scheduled for maintenance. You will"
3700                                " be informed at the next step.\n<p>\n"
3701                                "You must also select a uIPv4 for the cloned container, and set the initial"
3702                                " state of the clone."
3703                                " Usually clones should be kept stopped to conserve resources and facilitate rsync."
3704                                " Use the checkbox to change this default behavior."
3705                                " Any mount/umount files of the source container will NOT be used"
3706                                " by the new cloned container. This issue will be left for manual"
3707                                " or automated failover to the cloned container.<p>If you wish to"
3708                                " keep the source and clone container sync'ed you can specify a non zero"
3709                                " value via the 'cuSyncPeriod' entry below.");
3710                        printf("<p>Select target node<br>");
3711                        tTablePullDownDatacenter("tNode;cuTargetNodePullDown","cLabel","cLabel",uTargetNode,1,
3712                                cuTargetNodePullDown,0,uDatacenter);//0 does not use tProperty, uses uDatacenter
3713                        printf("<p>Select new IPv4<br>");
3714                        tTablePullDownOwnerAvailDatacenter("tIP;cuWizIPv4PullDown","cLabel","cLabel",uWizIPv4,1,
3715                                uDatacenter,uOwner);
3716
3717                        printf("<p>Select clone state<br>");
3718                        printf("<input type=radio name=uCloneStop value=%u",WARM_CLONE);
3719                        if(uCloneStop==WARM_CLONE)
3720                                printf(" checked");
3721                        printf("> Stopped/Warm");
3722                        printf("<input type=radio name=uCloneStop value=%u",HOT_CLONE);
3723                        if(uCloneStop==HOT_CLONE)
3724                                printf(" checked");
3725                        printf("> Active/Hot");
3726
3727                        printf("<p>cuSyncPeriod<br>");
3728                        printf("<input title='Keep clone in sync every cuSyncPeriod seconds"
3729                                        ". You can change this at any time via the property panel.'"
3730                                        " type=text size=10 maxlength=7"
3731                                        " name=uSyncPeriod value='%u'>\n",uSyncPeriod);
3732                        printf("<p>Optional primary group change<br>");
3733                        uGroup=uGetGroup(0,uContainer);//0=not for node
3734                        tContainerGroupPullDown(uChangeGroup,1);
3735                        if(uGroup)
3736                                printf("<input type=hidden name=uGroup value='%u'>",uGroup);
3737                        printf("<p><input title='Create a clone job for the current container'"
3738                                        " type=submit class=largeButton"
3739                                        " name=gcCommand value='Confirm Clone'>\n");
3740                break;
3741
3742                case 11001:
3743                        printf("<p><u>Remote Clone Wizard (Step 1/2)</u><br>");
3744                        printf("Here you will select the remote datacenter. If it is oversubscribed or not"
3745                                " configured for use, or otherwise unavailable you will have to select another.");
3746                        printf("<p>Select remote datacenter<br>");
3747                        tTablePullDown("tDatacenter;cuTargetDatacenterPullDown","cLabel","cLabel",uTargetDatacenter,1);
3748                        if(uGroup)
3749                                printf("<input type=hidden name=uGroup value='%u'>",uGroup);
3750                        printf("<p><input title='Step one of remote clone wizard'"
3751                                        " type=submit class=largeButton"
3752                                        " name=gcCommand value='Select Clone Datacenter'>\n");
3753                break;
3754
3755                case 11002:
3756                        printf("<p><u>Remote Clone Wizard (Step 2/2)</u><br>");
3757                        printf("Here you will select the hardware node target. If the selected node is"
3758                                " oversubscribed, not available, or scheduled for maintenance. You will"
3759                                " be informed at the next step.\n<p>\n"
3760                                "You must also select a uIPv4 for the cloned container, and set the initial"
3761                                " state of the clone."
3762                                " Usually clones should be kept stopped to conserve resources and facilitate rsync."
3763                                " Use the checkbox to change this default behavior."
3764                                " Any mount/umount files of the source container will NOT be used"
3765                                " by the new cloned container. This issue will be left for manual"
3766                                " or automated failover to the cloned container.<p>If you wish to"
3767                                " keep the source and clone container sync'ed you can specify a non zero"
3768                                " value via the 'cuSyncPeriod' entry below.");
3769                        printf("<p>Selected datacenter<br>");
3770                        tTablePullDown("tDatacenter;cuTargetDatacenterPullDown","cLabel","cLabel",uTargetDatacenter,0);
3771                        printf("<p>Select target node<br>");
3772                        tTablePullDownDatacenter("tNode;cuTargetNodePullDown","cLabel","cLabel",uTargetNode,1,
3773                                cuTargetNodePullDown,0,uTargetDatacenter);//0 does not use tProperty, uses uDatacenter
3774                        printf("<p>Select new IPv4<br>");
3775                        tTablePullDownOwnerAvailDatacenter("tIP;cuWizIPv4PullDown","cLabel","cLabel",uWizIPv4,1,
3776                                uTargetDatacenter,uOwner);
3777
3778                        printf("<p>Select clone state<br>");
3779                        printf("<input type=radio name=uCloneStop value=%u",WARM_CLONE);
3780                        if(uCloneStop==WARM_CLONE)
3781                                printf(" checked");
3782                        printf("> Stopped/Warm");
3783                        printf("<input type=radio name=uCloneStop value=%u",COLD_CLONE);
3784                        if(uCloneStop==COLD_CLONE)
3785                                printf(" checked");
3786                        printf("> Initial Setup/Cold");
3787                        printf("<input type=radio name=uCloneStop value=%u",HOT_CLONE);
3788                        if(uCloneStop==HOT_CLONE)
3789                                printf(" checked");
3790                        printf("> Active/Hot");
3791
3792                        printf("<p>cuSyncPeriod<br>");
3793                        printf("<input title='Keep clone in sync every cuSyncPeriod seconds"
3794                                        ". You can change this at any time via the property panel.'"
3795                                        " type=text size=10 maxlength=7"
3796                                        " name=uSyncPeriod value='%u'>\n",uSyncPeriod);
3797                        printf("<p>Optional primary group change<br>");
3798                        uGroup=uGetGroup(0,uContainer);//0=not for node
3799                        tContainerGroupPullDown(uChangeGroup,1);
3800                        if(uGroup)
3801                                printf("<input type=hidden name=uGroup value='%u'>",uGroup);
3802                        printf("<p><input title='Create a clone job for the current container'"
3803                                        " type=submit class=largeButton"
3804                                        " name=gcCommand value='Confirm Remote Clone'>\n");
3805                break;
3806
3807                case 8001:
3808                        printf("<p><u>Switchover Container Pair</u><br>");
3809                        printf("Confirm all the information presented for a manual failover to take place."
3810                                "<p>Jobs will be created for the source and this container. If jobs run successfully,"
3811                                " everything but the container VEIDs will be switched.<p>This clone (renamed to the"
3812                                " source names) will be the new production container and the source container will"
3813                                " be the clone container and kept in sync if cuSyncPeriod is changed to a non 0 value."
3814                                " This should only be done after confirmation that switchover container works fine.");
3815                        printf("<p><u>Switchover Data</u>");
3816                        if(uSource)
3817                        {
3818                                printf("<br>%s will replace ",cLabel);
3819                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction=tContainer&uContainer=%u>"
3820                                        "%s</a>",uSource,ForeignKey("tContainer","cLabel",uSource));
3821                        }
3822                        printf("<p><input title='Creates manual failover jobs for the current container'"
3823                                        " type=submit class=lwarnButton"
3824                                        " name=gcCommand value='Confirm Switchover'>\n");
3825                break;
3826
3827                case 2001:
3828                        printf("<p><u>Think twice</u>");
3829                        printf("<br>Container and it's properties will be removed from unxsVZ database for good.<br>Any jobs"
3830                                " pending for this container or it's clone will be canceled. Any clone in <i>Awaiting clone</i>"
3831                                " status, will also be deleted.<p>");
3832                        printf(LANG_NBB_CONFIRMDEL);
3833                break;
3834
3835                case 2002:
3836                        printf("<p><u>Review changes</u><br>");
3837                        printf("If you change uIPv4 you will need to modify tIP<br>");
3838                        printf(LANG_NBB_CONFIRMMOD);
3839                        printf("<p>Optional primary group change<br>");
3840                        uGroup=uGetGroup(0,uContainer);//0=not for node
3841                        tContainerGroupPullDown(uChangeGroup,1);
3842                break;
3843
3844                case 12001:
3845                case 12002:
3846                        printf("<u>Create or refine your user search set</u><br>");
3847                        printf("In the right panel you can select your search criteria. When refining you do not need"
3848                                " to reuse your initial search critieria. Your search set is persistent even across unxsVZ sessions.<p>");
3849                        printf("<input type=submit class=largeButton title='Create an initial or replace an existing search set'"
3850                                " name=gcCommand value='Create Search Set'>");
3851                        printf("<input type=submit class=largeButton title='Add the results to your current search set. Do not add the same search"
3852                                " over and over again it will not result in any change but may slow down processing.'"
3853                                " name=gcCommand value='Add to Search Set'>");
3854                        printf("<p><input type=submit class=largeButton title='Apply the right panel filter to refine your existing search set"
3855                                " by removing set elements that match the filter settings.'"
3856                                " name=gcCommand value='Remove from Search Set'>\n");
3857                        printf("<p><input type=submit class=largeButton title='Reload current search set. Good for checking for any new status updates'"
3858                                " name=gcCommand value='Reload Search Set'>");
3859                        printf("<input type=submit class=largeButton title='Return to main tContainer tab page'"
3860                                " name=gcCommand value='Cancel'>");
3861                        printf("<p><u>Set Operation Options</u>");
3862                        printf("<br>Target node");
3863                        tTablePullDown("tNode;cuTargetNodePullDown","cLabel","cLabel",uTargetNode,1);
3864                        printf(" Clone target node");
3865                        tTablePullDown("tNode;cuCloneTargetNodePullDown","cLabel","cLabel",guCloneTargetNode,1);
3866                        printf("<br><input title='For supported set operations (like Group Delete, Destroy or Migration)"
3867                                " apply same to their clone containers.'"
3868                                " type=checkbox name=guOpOnClonesNoCA");
3869                        if(guOpOnClones)
3870                                printf(" checked");
3871                        printf("> guOpOnClones");
3872
3873                break;
3874
3875                case 9001:
3876                        printf("<u>New Container Datacenter and Organization</u><br>");
3877                        printf("In conjunction with your master plan; review datacenter location, usage, traffic"
3878                                " and problem stats, in order to make an optimal datacenter selection."
3879                                " You must also chose the organization (a company, NGO or similar) that will own this"
3880                                " resource.<p>");
3881                        printf("<input type=submit class=largeButton title='Select datacenter and organization'"
3882                                " name=gcCommand value='Select Datacenter/Org'>\n");
3883                        printf("<p><input type=submit class=largeButton title='Cancel this operation'"
3884                                " name=gcCommand value='Cancel'>\n");
3885                        //if(!uOwner && uForClient)
3886                        //      printf("<input type=hidden name=uOwner value='%u'>\n",uForClient);
3887                break;
3888
3889                case 9002:
3890                        printf("<u>New Container Node</u><br>");
3891                        printf("In conjunction with your master plan; review node usage, traffic"
3892                                " and problem stats, in order to make an optimal node selection. Only nodes that belong"
3893                                " to the previously chosen datacenter are shown. Other factors may also limit the "
3894                                "available node list, such as autonomic or configuration imposed restrictions.<p>");
3895                        printf("<input type=submit class=largeButton title='Select hardware node'"
3896                                " name=gcCommand value='Select Node'>\n");
3897                        printf("<p><input type=submit class=largeButton title='Cancel this operation'"
3898                                " name=gcCommand value='Cancel'>\n");
3899                break;
3900
3901                case 9003:
3902                        printf("<u>New Container Setup</u><br>");
3903                        printf("Set container creation parameters. Choices are limited based on selected datacenter, node,"
3904                                " and the organization that the container is being created for. We now require that the cLabel"
3905                                " be the first part (first stop) of the cHostname (for multiple container creation this is automatic.)<p>");
3906                        printf("The appliance container is a place holder container for an actual container (or non virtual server)"
3907                                " than runs on a remote node (or appliance) not part of this unxsVZ system. The clone is kept sync'd,"
3908                                " and it's uSource is, as usual, the uContainer of the container created."
3909                                " This new type of container is identified, for now, via a special uStatus.");
3910                        GetConfiguration("cAutoCloneNode",cAutoCloneNode,uDatacenter,0,0,0);
3911                        if(cAutoCloneNode[0])
3912                                printf("<p>Auto-clone subsystem is enabled for selected datacenter: Clone target node"
3913                                        " must not match selected node. Similarly, clone start uIPv4"
3914                                        " must not match uIPv4 or fall in same range -as defined per number of containers.");
3915                        GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
3916                        if(cunxsBindARecordJobZone[0])
3917                                printf("<p>unxsBind interface is configured for selected datacenter and <i>%s</i> zone: DNS will be setup"
3918                                        " automatically for you, unless you opt-out by un-checking the <i>Create job...</i>"
3919                                        " checkbox in the right data panel.",cunxsBindARecordJobZone);
3920                        printf("<p><input type=submit class=largeButton"
3921                                " title='Configure container and create a single container'"
3922                                " name=gcCommand value='Single Container Creation'>\n");
3923                        printf("<p><input type=submit class=largeButton"
3924                                " title='Configure base container and continue to create multiple containers'"
3925                                " name=gcCommand value='Multiple Container Creation'>\n");
3926                        printf("<p><input type=submit class=largeButton"
3927                                " title='Configure and create special remote appliance container set'"
3928                                " name=gcCommand value='Appliance Creation'>\n");
3929                        printf("<br><input type=text"
3930                                " title='Appliance creation requires a valid IPv4 IP number be entered."
3931                                " This IP is the IP of the remote appliance it may already exist in tIP"
3932                                " but belong to special CustomerPremise datacenter'"
3933                                " name=gcIPv4 value='%s'> Appliance gcIPv4\n",gcIPv4);
3934                        printf("<p><input type=submit class=largeButton title='Cancel this operation'"
3935                                " name=gcCommand value='Cancel'>\n");
3936                break;
3937
3938                case 9004:
3939                        printf("<u>Multiple Container Setup</u><br>");
3940                        printf("Set special multiple container creation parameters. Choices are limited based on selected"
3941                                " datacenter, node,"
3942                                " and the organization that the container is being created for. We recommend that the cLabel"
3943                                " be the short cHostname, in DNS terms.<p>");
3944                        printf("When you create multiple containers you specify a special <i>cLabel</i>"
3945                                " and <i>cHostname</i> that will be used to generate the multiple containers."
3946                                " <p>For example, given <i>cLabel=ct</i> and <i>cHostname=.yourdomain.tld</i>,"
3947                                " your containers will be <i>cLabel=ct0</i> and <i>cHostname=ct0.yourdomain.tld</i>"
3948                                " through <i>cLabel=ctN</i> and <i>cHostname=ctN.yourdomain.tld</i>,"
3949                                " where N is the number of containers specfied minus 1.<p>");
3950                        GetConfiguration("cAutoCloneNode",cAutoCloneNode,uDatacenter,0,0,0);
3951                        if(cAutoCloneNode[0])
3952                                printf("Auto-clone subsystem is enabled for selected datacenter: Clone target node"
3953                                        " must not match selected node. Similarly, clone start uIPv4"
3954                                        " must not match uIPv4 or fall in same range -as defined per number of containers.<p>");
3955                        GetConfiguration("cunxsBindARecordJobZone",cunxsBindARecordJobZone,uDatacenter,0,0,0);
3956                        if(cunxsBindARecordJobZone[0])
3957                                printf("unxsBind interface is configured for selected datacenter and <i>%s</i> zone: DNS will be setup"
3958                                        " automatically for you, unless you opt-out by un-checking the <i>Create job...</i>"
3959                                        " checkbox in the right data panel.<p>",cunxsBindARecordJobZone);
3960                        printf("<input type=submit class=largeButton"
3961                                " title='Commit to creating multiple containers'"
3962                                " name=gcCommand value='Create Multiple Containers'>\n");
3963                        printf("<p><input type=submit class=largeButton title='Cancel this operation'"
3964                                " name=gcCommand value='Cancel'>\n");
3965                break;
3966
3967                default:
3968                        printf("<u>Table Tips</u><br>");
3969                        printf("Setup or modify a container by selecting a meaningful cLabel,"
3970                                " a correct datacenter and hardware node. You usually should start with"
3971                                " a similar container. Most properties are created by data collection agents"
3972                                ", others like <i>Notes</i> are user created and maintained.<p>"
3973                                "Special properties cVEID.mount, cVEID.umount, cVEID.start and cVEID.stop are used via"
3974                                " their tTemplate matching values (see tTemplate for more info)"
3975                                " to create /etc/vz/conf/VEID.x OpenVZ action scripts (on new container creation you will"
3976                                " be able to optionally select a mount/umount template set for this feature, or VETH"
3977                                " device based containers will have default action scripts installed for you.)");
3978               
3979                        //Some buttons should be easier to get to than others.
3980                        if(uContainer)
3981                        {
3982                                if( uStatus==uINITSETUP)
3983                                {
3984                                        printf("<p><input title='Creates a job for deploying this new container."
3985                                        " Make sure you configure the properties you want beforehand!'"
3986                                        " type=submit class=lalertButton"
3987                                        " name=gcCommand value='Deploy %.25s'>\n",cLabel);
3988                                }
3989                                else if( uStatus==uAWAITACT || uStatus==uAWAITDEL ||
3990                                                        uStatus==uAWAITSTOP || uStatus==uAWAITFAIL)
3991                                {
3992                                        printf("<p><input title='Cancel all waiting jobs for this container.'"
3993                                        " type=submit class=largeButton"
3994                                        " name=gcCommand value='Cancel Job'>\n");
3995                                }
3996                        }
3997
3998                        if(uContainer && uNode)
3999                        {
4000                                printf("<p><u>Record Context Info</u>");
4001                                if(uSource)
4002                                {
4003                                        printf("<br>%s is a clone of ",cLabel);
4004                                        printf("<a class=darkLink href=unxsVZ.cgi?gcFunction=tContainer&uContainer=%u>"
4005                                                "%s</a>",uSource,ForeignKey("tContainer","cLabel",uSource));
4006                                }
4007                                htmlCloneInfo(uContainer);
4008                                htmlContainerNotes(uContainer);
4009                                htmlContainerMount(uContainer);
4010                                htmlGroups(0,uContainer);
4011                        }
4012                        printf("<p><u>Container Search by cLabel</u><br>");
4013                        printf("<input title='Enter cLabel start or MySQL LIKE pattern (%% or _ allowed)' type=text"
4014                                        " name=cSearch value='%s'>",cSearch);
4015
4016                        printf("<input title='Remove clones from search nav list' type=checkbox name=guNoClones");
4017                        if(guNoClones)
4018                                printf(" checked");
4019                        printf("> guNoClones");
4020
4021                        printf("<input title='Remove all but initial setup status containers from nav list."
4022                                " Mutually exclusive with guNoClones option.' type=checkbox name=guInitOnly");
4023                        if(guInitOnly)
4024                                printf(" checked");
4025                        printf("> guInitOnly");
4026
4027                        tContainerNavList(0,cSearch);//0 means container mode or tContainer tab mode.
4028                        printf("<p><input type=submit class=largeButton title='Open user search set page. There you can create search sets and operate"
4029                                " on selected containers of the loaded container set.'"
4030                                " name=gcCommand value='Search Set Operations'>\n");
4031                        if(uContainer && uAllowMod(uOwner,uCreatedBy) && guPermLevel>7)
4032                        {
4033                                if(uStatus==uACTIVE)
4034                                {
4035                                        htmlHealth(uContainer,3);
4036                                        if(!strstr(cLabel,"-clone") && uSource==0)
4037                                        printf("<p><input title='Clone a container to this or another hardware node."
4038                                        " The clone will be an online container with another IP and hostname."
4039                                        " It will be kept updated via rsync on a configurable basis.'"
4040                                        " type=submit class=largeButton"
4041                                        " name=gcCommand value='Clone Wizard'><br>\n");
4042                                        printf("<input title='Clone container to a remote datacenter hardware node."
4043                                        " The clone will be an online container with another IP and hostname."
4044                                        " It will be kept updated via rsync on a configurable basis.'"
4045                                        " type=submit class=largeButton"
4046                                        " name=gcCommand value='Remote Clone Wizard'><br>\n");
4047                                        printf("<input title='Change current container IPv4'"
4048                                        " type=submit class=largeButton"
4049                                        " name=gcCommand value='IP Change Wizard'><br>\n");
4050                                        printf("<p><input title='Creates a job for stopping an active container.'"
4051                                                " type=submit class=lwarnButton"
4052                                                " name=gcCommand value='Stop %.24s'><br>\n",cLabel);
4053                                        if(uSource)
4054                                                printf("<p><input title='Creates jobs for manual failover.'"
4055                                                " type=submit class=lwarnButton"
4056                                                " name=gcCommand value='Switchover %.25s'><br>\n",cLabel);
4057                                }
4058                                else if( uStatus==uSTOPPED)
4059                                {
4060                                        printf("<p><input title='Creates a job for starting a stopped container.'"
4061                                        " type=submit class=lalertButton"
4062                                        " name=gcCommand value='Start %.25s'><br>\n",cLabel);
4063                                        if(!strstr(cLabel,"-clone") && uSource==0)
4064                                        printf("<input title='Clone a container to this or another hardware node."
4065                                        " The clone will be an online container with another IP and hostname."
4066                                        " It will be kept updated via rsync on a configurable basis.'"
4067                                        " type=submit class=largeButton"
4068                                        " name=gcCommand value='Clone Wizard'><br>\n");
4069                                        printf("<input title='Clone container to a remote datacenter hardware node."
4070                                        " The clone will be an online container with another IP and hostname."
4071                                        " It will be kept updated via rsync on a configurable basis.'"
4072                                        " type=submit class=largeButton"
4073                                        " name=gcCommand value='Remote Clone Wizard'><br>\n");
4074                                        if(uSource)
4075                                                printf("<p><input title='Creates jobs for manual failover.'"
4076                                                " type=submit class=lwarnButton"
4077                                                " name=gcCommand value='Switchover %.25s'><br>\n",cLabel);
4078                                }
4079
4080                                if( uStatus==uSTOPPED || uStatus==uACTIVE )
4081                                {
4082                                        printf("<input title='Migrate container to another hardware node'"
4083                                        " type=submit class=largeButton"
4084                                        " name=gcCommand value='Migration Wizard'><br>\n");
4085                                        printf("<input title='Migrate container to another datacenter node'"
4086                                        " type=submit class=largeButton"
4087                                        " name=gcCommand value='Remote Migration'><br>\n");
4088                                        printf("<input title='Change current container name and hostname'"
4089                                        " type=submit class=largeButton"
4090                                        " name=gcCommand value='Hostname Change Wizard'><br>\n");
4091                                        printf("<input title='Template a container."
4092                                        " Creates and installs OS and VZ conf templates on all nodes.'"
4093                                        " type=submit class=largeButton"
4094                                        " name=gcCommand value='Template Wizard'><br>\n");
4095                                }
4096
4097                                char cVEIDMount[256]={""};
4098                                GetContainerProp(uContainer,"cVEID.mount",cVEIDMount);
4099                                if( cVEIDMount[0] && (uStatus==uSTOPPED || uStatus==uINITSETUP) && !strstr(cLabel,"-clone"))
4100                                        printf("<br><input title='If container mount,umount,start or stop files do not"
4101                                        " exist they will be created from tProperty data items: cVEID.mount"
4102                                        " ,cVEID.umount, cVEID.start and cVEID.stop'"
4103                                        " type=submit class=largeButton"
4104                                        " name=gcCommand value='Create Action Scripts'>\n");
4105                        }
4106        }
4107        CloseFieldSet();
4108
4109}//void ExttContainerButtons(void)
4110
4111
4112
4113
4114void ExttContainerAuxTable(void)
4115{
4116        MYSQL_RES *res;
4117        MYSQL_ROW field;
4118        unsigned uGroup=0;
4119        unsigned uNumRows=0;
4120
4121        switch(guMode)
4122        {
4123                case 12001:
4124                case 12002:
4125                        //Set operation buttons
4126                        OpenFieldSet("Set Operations",100);
4127                        printf("<input title='Delete checked containers from your search set. They will still be visible but will"
4128                                " marked deleted and will not be used in any subsequent set operation'"
4129                                " type=submit class=largeButton name=gcCommand value='Delete Checked'>\n");
4130                        printf("&nbsp; <input title='Cancels job(s) for container(s) waiting for activation, deletion or stop.'"
4131                                " type=submit class=largeButton"
4132                                " name=gcCommand value='Group Cancel'>\n");
4133                        printf("&nbsp; <input title='Creates job(s) for starting stopped or initial setup container(s).'"
4134                                " type=submit class=largeButton"
4135                                " name=gcCommand value='Group Start'>\n");
4136                        printf("&nbsp; <input title='Creates job(s) for templating stopped or active container(s)."
4137                                " Uses the container label for new tOSTemplate and tConfig entries."
4138                                " If active, containers may be stopped for several minutes if not setup for vzdump snapshot.'"
4139                                " type=submit class=largeButton"
4140                                " name=gcCommand value='Group Template'>\n");
4141                        printf("&nbsp; <input title='Deletes initial setup or awaiting intial setup clone container(s) and optionally their clones.'"
4142                                " type=submit class=largeButton"
4143                                " name=gcCommand value='Group Delete'>\n");
4144                        printf("&nbsp; <input title='Deletes any existing group association then adds selected group to selected containers. Requires"
4145                                        " that you select the new group with the select tool above.'"
4146                                " type=submit class=largeButton"
4147                                " name=gcCommand value='Group Change'>\n");
4148                        printf("<p><input title='Creates job(s) for cloning active or stopped container(s) that"
4149                                " are not clones themselves.'"
4150                                " type=submit class=lwarnButton"
4151                                " name=gcCommand value='Group Clone'>\n");
4152                        printf("&nbsp; <input title='Creates job(s) for stopping active container(s).'"
4153                                " type=submit class=lwarnButton"
4154                                " name=gcCommand value='Group Stop'>\n");
4155                        printf("&nbsp; <input title='Creates job(s) for switching over cloned container(s) of same datacenter.'"
4156                                " type=submit class=lwarnButton"
4157                                " name=gcCommand value='Group Switchover'>\n");
4158                        printf("&nbsp; <input title='Creates job(s) for migrating container(s) and optionally their clones."
4159                                " Uses target and clone node selects above'"
4160                                " type=submit class=lwarnButton"
4161                                " name=gcCommand value='Group Migration'>\n");
4162                        printf("&nbsp; <input title='Creates job(s) for destroying active or stopped container(s) and optionally their clones.'"
4163                                " type=submit class=lwarnButton"
4164                                " name=gcCommand value='Group Destroy'>\n");
4165                        printf("&nbsp; <input title='Creates job(s) with given commands to run via vzctl exec2'"
4166                                " type=submit class=lwarnButton"
4167                                " name=gcCommand value='Group Execute'>\n");
4168                        CloseFieldSet();
4169
4170                        sprintf(gcQuery,"Search Set Contents");
4171                        OpenFieldSet(gcQuery,100);
4172                        uGroup=uGetSearchGroup(gcUser);
4173                        sprintf(gcQuery,"SELECT"
4174                                        " tContainer.uContainer,tContainer.cLabel,tContainer.cHostname,tStatus.cLabel,"
4175                                        " tIP.cLabel,tNode.cLabel,tDatacenter.cLabel,tContainer.uSource,"
4176                                        " tClient.cLabel,tOSTemplate.cLabel,"
4177                                        " FROM_UNIXTIME(tContainer.uCreatedDate,'%%a %%b %%d %%T %%Y')"
4178                                        " FROM tContainer"
4179                                        " LEFT JOIN tIP ON tContainer.uIPv4=tIP.uIP"
4180                                        " LEFT JOIN tNode ON tContainer.uNode=tNode.uNode"
4181                                        " LEFT JOIN tDatacenter ON tContainer.uDatacenter=tDatacenter.uDatacenter"
4182                                        " LEFT JOIN tStatus ON tContainer.uStatus=tStatus.uStatus"
4183                                        " LEFT JOIN tClient ON tContainer.uOwner=tClient.uClient"
4184                                        " LEFT JOIN tOSTemplate ON tContainer.uOSTemplate=tOSTemplate.uOSTemplate"
4185                                        " WHERE uContainer IN (SELECT uContainer FROM tGroupGlue WHERE uGroup=%u)",uGroup);
4186                        mysql_query(&gMysql,gcQuery);
4187                        if(mysql_errno(&gMysql))
4188                                htmlPlainTextError(mysql_error(&gMysql));
4189                        res=mysql_store_result(&gMysql);
4190                        if((uNumRows=mysql_num_rows(res)))
4191                        {
4192                                char cResult[100]={""};
4193                                char cCtLabel[100]={""};
4194
4195                                printf("<table>");
4196                                printf("<tr>");
4197                                printf("<td><u>cLabel</u></td>"
4198                                        "<td><u>cHostname</u></td>"
4199                                        "<td><u>Status</u></td>"
4200                                        "<td><u>IPv4</u></td>"
4201                                        "<td><u>Node</u></td>"
4202                                        "<td><u>Datacenter</u></td>"
4203                                        "<td><u>uSource</u></td>"
4204                                        "<td><u>Owner</u></td>"
4205                                        "<td><u>OSTemplate</u></td>"
4206                                        "<td><u>uCreatedDate</u></td>"
4207                                        "<td><u>Set operation result</u></td></tr>");
4208//Reset margin start
4209while((field=mysql_fetch_row(res)))
4210{
4211        if(guMode==12002)
4212        {
4213                register int i;
4214                unsigned uCtContainer=0;
4215
4216                cResult[0]=0;
4217                sscanf(field[0],"%u",&uCtContainer);
4218                sprintf(cCtLabel,"Ct%u",uCtContainer);
4219                for(i=0;i<x;i++)
4220                {
4221                        //insider xss protection
4222                        if(guPermLevel<10)
4223                                continue;
4224
4225                        if(!strcmp(entries[i].name,cCtLabel))
4226                        {
4227                                if(!strcmp(gcCommand,"Delete Checked"))
4228                                {
4229                                        sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uGroup=%u AND uContainer=%u",uGroup,uCtContainer);
4230                                        mysql_query(&gMysql,gcQuery);
4231                                        if(mysql_errno(&gMysql))
4232                                        {
4233                                                sprintf(cResult,mysql_error(&gMysql));
4234                                                break;
4235                                        }
4236                                        if(mysql_affected_rows(&gMysql)>0)
4237                                                sprintf(cResult,"Deleted from set");
4238                                        else
4239                                                sprintf(cResult,"Unexpected non deletion");
4240                                        break;
4241                                }//Delete Checked
4242
4243                                else if(!strcmp(gcCommand,"Group Cancel"))
4244                                {
4245                                        struct structContainer sContainer;
4246
4247                                        InitContainerProps(&sContainer);
4248                                        GetContainerProps(uCtContainer,&sContainer);
4249
4250                                        if((sContainer.uStatus==uAWAITDEL || sContainer.uStatus==uAWAITACT ||
4251                                                sContainer.uStatus==uAWAITSTOP)
4252                                                && (sContainer.uOwner==guCompany || guCompany==1))
4253                                        {
4254                                                if(!CancelContainerJob(sContainer.uDatacenter,
4255                                                                sContainer.uNode,uCtContainer,1))
4256                                                {
4257                                                        if(sContainer.uStatus==uAWAITDEL ||
4258                                                                        sContainer.uStatus==uAWAITSTOP)
4259                                                                SetContainerStatus(uCtContainer,uACTIVE);
4260                                                        else if(sContainer.uStatus==uAWAITACT)
4261                                                                SetContainerStatus(uCtContainer,uINITSETUP);
4262                                                        sprintf(cResult,"group cancel job created");
4263                                                }
4264                                                else
4265                                                {
4266                                                        sprintf(cResult,"group cancel job not created!");
4267                                                }
4268                                        }
4269                                        else
4270                                        {
4271                                                sprintf(cResult,"group cancel request ignored");
4272                                        }
4273                                        break;
4274                                }//Group Cancel
4275
4276                                else if(!strcmp(gcCommand,"Group Stop"))
4277                                {
4278                                        struct structContainer sContainer;
4279
4280                                        InitContainerProps(&sContainer);
4281                                        GetContainerProps(uCtContainer,&sContainer);
4282                                        if( (sContainer.uStatus==uACTIVE)
4283                                                && (sContainer.uOwner==guCompany || guCompany==1))
4284                                        {
4285                                                if(StopContainerJob(sContainer.uDatacenter,
4286                                                                sContainer.uNode,uCtContainer,guCompany))
4287                                                {
4288                                                        SetContainerStatus(uCtContainer,uAWAITSTOP);
4289                                                        sprintf(cResult,"group stop job created");
4290                                                }
4291                                                else
4292                                                {
4293                                                        sprintf(cResult,"group stop job not created!");
4294                                                }
4295                                        }
4296                                        else
4297                                        {
4298                                                sprintf(cResult,"group stop request ignored");
4299                                        }
4300                                        break;
4301                                }//Group Stop
4302
4303                                //Group Destroy Uses guOpOnClones
4304                                else if(!strcmp(gcCommand,"Group Destroy"))
4305                                {
4306                                        struct structContainer sContainer;
4307
4308                                        InitContainerProps(&sContainer);
4309                                        GetContainerProps(uCtContainer,&sContainer);
4310                                        if( (sContainer.uStatus==uSTOPPED || sContainer.uStatus==uACTIVE)
4311                                                && (sContainer.uOwner==guCompany || guCompany==1))
4312                                        {
4313                                                if(DestroyContainerJob(sContainer.uDatacenter,
4314                                                                sContainer.uNode,uCtContainer,guCompany))
4315                                                {
4316                                                        SetContainerStatus(uCtContainer,uAWAITDEL);
4317                                                        sprintf(cResult,"group destroy job created");
4318                                                }
4319                                                else
4320                                                {
4321                                                        sprintf(cResult,"group destroy job not created!");
4322                                                }
4323                                        }
4324                                        else
4325                                        {
4326                                                sprintf(cResult,"group destroy request ignored");
4327                                        }
4328                                        if(guOpOnClones)
4329                                        {
4330                                                MYSQL_RES *res;
4331                                                MYSQL_ROW field;
4332                                                unsigned uContainer=0;
4333                                                unsigned uNode=0;
4334                                                unsigned uDatacenter=0;
4335                                                unsigned uStatus=0;
4336                                                unsigned uOwner=0;
4337
4338                                                sprintf(gcQuery,"SELECT uDatacenter,uNode,uContainer,uStatus,uOwner FROM tContainer"
4339                                                                " WHERE uSource=%u",uCtContainer);
4340                                                mysql_query(&gMysql,gcQuery);
4341                                                if(mysql_errno(&gMysql))
4342                                                        htmlPlainTextError(mysql_error(&gMysql));
4343                                                res=mysql_store_result(&gMysql);
4344                                                while((field=mysql_fetch_row(res)))
4345                                                {
4346                                                        sscanf(field[0],"%u",&uDatacenter);
4347                                                        sscanf(field[1],"%u",&uNode);
4348                                                        sscanf(field[2],"%u",&uContainer);
4349                                                        sscanf(field[3],"%u",&uStatus);
4350                                                        sscanf(field[4],"%u",&uOwner);
4351                                                        if((uStatus==uSTOPPED || uStatus==uACTIVE)
4352                                                                && (uOwner==guCompany || guCompany==1))
4353                                                        {
4354                                                                if(DestroyContainerJob(uDatacenter,uNode,uContainer,guCompany))
4355                                                                {
4356                                                                        SetContainerStatus(uContainer,uAWAITDEL);
4357                                                                        strcat(cResult," +clone job");
4358                                                                }
4359                                                                else
4360                                                                {
4361                                                                        strcat(cResult," +clone job error!");
4362                                                                }
4363                                                        }
4364                                                        else
4365                                                        {
4366                                                                strcat(cResult," +no clone job");
4367                                                        }
4368                                                }
4369                                                mysql_free_result(res);
4370                                        }//op on clones
4371                                        break;
4372                                }//Group Destroy
4373
4374                                //Requires uGroup
4375                                else if(!strcmp(gcCommand,"Group Change"))
4376                                {
4377                                        struct structContainer sContainer;
4378
4379                                        InitContainerProps(&sContainer);
4380                                        GetContainerProps(uCtContainer,&sContainer);
4381                                        if( (sContainer.uOwner==guCompany || guCompany==1) && uChangeGroup)
4382                                        {
4383                                                //Remove from all container type groups
4384                                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uContainer=%u AND"
4385                                                                " uGroup IN (SELECT uGroup FROM tGroup WHERE uGroupType=1)",//1=container type
4386                                                        uCtContainer);
4387                                                mysql_query(&gMysql,gcQuery);
4388                                                if(mysql_errno(&gMysql))
4389                                                        htmlPlainTextError(mysql_error(&gMysql));
4390                                                sprintf(gcQuery,"INSERT INTO tGroupGlue SET uContainer=%u,uGroup=%u",
4391                                                        uCtContainer,uChangeGroup);
4392                                                mysql_query(&gMysql,gcQuery);
4393                                                if(mysql_errno(&gMysql))
4394                                                        htmlPlainTextError(mysql_error(&gMysql));
4395                                                sprintf(cResult,"group changed");
4396                                        }
4397                                        else
4398                                        {
4399                                                sprintf(cResult,"group change ignored");
4400                                        }
4401                                        break;
4402                                }//Group Change
4403
4404
4405                                //Group Delete Uses guOpOnClones
4406                                else if(!strcmp(gcCommand,"Group Delete"))
4407                                {
4408                                        struct structContainer sContainer;
4409
4410                                        InitContainerProps(&sContainer);
4411                                        GetContainerProps(uCtContainer,&sContainer);
4412                                        if( (sContainer.uStatus==uINITSETUP || sContainer.uStatus==uAWAITCLONE)
4413                                                && (sContainer.uOwner==guCompany || guCompany==1))
4414                                        {
4415                                                //Release IPs
4416                                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=1"
4417                                                        " WHERE uIP=%u and uAvailable=0",sContainer.uIPv4);
4418                                                mysql_query(&gMysql,gcQuery);
4419                                                if(mysql_errno(&gMysql))
4420                                                        htmlPlainTextError(mysql_error(&gMysql));
4421                                                //Node IP if any MySQL5+
4422                                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=1 WHERE cLabel IN"
4423                                                " (SELECT cValue FROM tProperty WHERE uKey=%u"
4424                                                " AND uType=3 AND cName='cNodeIP')",uCtContainer);
4425                                                mysql_query(&gMysql,gcQuery);
4426                                                if(mysql_errno(&gMysql))
4427                                                        htmlPlainTextError(mysql_error(&gMysql));
4428                                                //Now we can remove properties
4429                                                DelProperties(uCtContainer,3);
4430                                                //Remove from any groups
4431                                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uContainer=%u",
4432                                                        uCtContainer);
4433                                                mysql_query(&gMysql,gcQuery);
4434                                                if(mysql_errno(&gMysql))
4435                                                        htmlPlainTextError(mysql_error(&gMysql));
4436                                                CancelContainerJob(sContainer.uDatacenter,sContainer.uNode,
4437                                                        uCtContainer,0);//0 is not specific cancel job attempt
4438                                                //81=Awaiting clone. TODO properties of clones may
4439                                                //exist
4440                                                sprintf(gcQuery,"DELETE FROM tContainer WHERE uStatus=81 AND uSource=%u"
4441                                                                        ,uCtContainer);
4442                                                mysql_query(&gMysql,gcQuery);
4443                                                if(mysql_errno(&gMysql))
4444                                                        htmlPlainTextError(mysql_error(&gMysql));
4445                                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uContainer="
4446                                                "(SELECT uContainer FROM tContainer WHERE uSource=%u AND uStatus=81)",uContainer);
4447                                                mysql_query(&gMysql,gcQuery);
4448                                                if(mysql_errno(&gMysql))
4449                                                        htmlPlainTextError(mysql_error(&gMysql));
4450                                                sprintf(gcQuery,"DELETE FROM tContainer WHERE uContainer=%u",
4451                                                        uCtContainer);
4452                                                mysql_query(&gMysql,gcQuery);
4453                                                if(mysql_errno(&gMysql))
4454                                                        htmlPlainTextError(mysql_error(&gMysql));
4455                                                if(mysql_affected_rows(&gMysql)>0)
4456                                                        sprintf(cResult,"group delete done");
4457                                        }
4458                                        else
4459                                        {
4460                                                sprintf(cResult,"group delete ignored");
4461                                        }
4462                                        if(guOpOnClones)
4463                                        {
4464                                                MYSQL_RES *res;
4465                                                MYSQL_ROW field;
4466                                                unsigned uContainer=0;
4467                                                unsigned uNode=0;
4468                                                unsigned uDatacenter=0;
4469                                                unsigned uStatus=0;
4470                                                unsigned uOwner=0;
4471                                                unsigned uIPv4=0;
4472
4473                                                sprintf(gcQuery,"SELECT uDatacenter,uNode,uContainer,uStatus,uOwner,uIPv4 FROM"
4474                                                                " tContainer WHERE uSource=%u",uCtContainer);
4475                                                mysql_query(&gMysql,gcQuery);
4476                                                if(mysql_errno(&gMysql))
4477                                                        htmlPlainTextError(mysql_error(&gMysql));
4478                                                res=mysql_store_result(&gMysql);
4479                                                while((field=mysql_fetch_row(res)))
4480                                                {
4481                                                        sscanf(field[0],"%u",&uDatacenter);
4482                                                        sscanf(field[1],"%u",&uNode);
4483                                                        sscanf(field[2],"%u",&uContainer);
4484                                                        sscanf(field[3],"%u",&uStatus);
4485                                                        sscanf(field[4],"%u",&uOwner);
4486                                                        sscanf(field[5],"%u",&uIPv4);
4487                                                        if((uStatus==uINITSETUP) && (uOwner==guCompany || guCompany==1))
4488                                                        {
4489                                                                //Release IPs
4490                                                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=1"
4491                                                                        " WHERE uIP=%u and uAvailable=0",uIPv4);
4492                                                                mysql_query(&gMysql,gcQuery);
4493                                                                if(mysql_errno(&gMysql))
4494                                                                        htmlPlainTextError(mysql_error(&gMysql));
4495                                                                //Node IP if any MySQL5+
4496                                                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=1 WHERE cLabel IN"
4497                                                                " (SELECT cValue FROM tProperty WHERE uKey=%u"
4498                                                                " AND uType=3 AND cName='cNodeIP')",uContainer);
4499                                                                mysql_query(&gMysql,gcQuery);
4500                                                                if(mysql_errno(&gMysql))
4501                                                                        htmlPlainTextError(mysql_error(&gMysql));
4502                                                                //Now we can remove properties
4503                                                                DelProperties(uContainer,3);
4504                                                                //Remove from any groups
4505                                                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE uContainer=%u",
4506                                                                        uContainer);
4507                                                                mysql_query(&gMysql,gcQuery);
4508                                                                if(mysql_errno(&gMysql))
4509                                                                        htmlPlainTextError(mysql_error(&gMysql));
4510                                                                //0 is not specific cancel job attempt
4511                                                                CancelContainerJob(uDatacenter,uNode,uContainer,0);
4512                                                                //81=Awaiting clone
4513                                                                sprintf(gcQuery,"DELETE FROM tContainer WHERE"
4514                                                                                " uStatus=81 AND uSource=%u",uContainer);
4515                                                                mysql_query(&gMysql,gcQuery);
4516                                                                if(mysql_errno(&gMysql))
4517                                                                        htmlPlainTextError(mysql_error(&gMysql));
4518                                                                sprintf(gcQuery,"DELETE FROM tGroupGlue WHERE"
4519                                                                                " uContainer=(SELECT uContainer FROM tContainer"
4520                                                                                " WHERE uSource=%u AND uStatus=81)",uContainer);
4521                                                                mysql_query(&gMysql,gcQuery);
4522                                                                if(mysql_errno(&gMysql))
4523                                                                        htmlPlainTextError(mysql_error(&gMysql));
4524                                                                sprintf(gcQuery,"DELETE FROM tContainer WHERE uContainer=%u",
4525                                                                        uContainer);
4526                                                                mysql_query(&gMysql,gcQuery);
4527                                                                if(mysql_errno(&gMysql))
4528                                                                        htmlPlainTextError(mysql_error(&gMysql));
4529                                                                if(mysql_affected_rows(&gMysql)>0)
4530                                                                        strcat(cResult," +clone delete");
4531                                                        }//if clone
4532                                                        else
4533                                                        {
4534                                                                strcat(cResult," +no clone deleted");
4535                                                        }
4536                                                }//while
4537                                                mysql_free_result(res);
4538                                        }//if op on clones
4539                                        break;
4540                                }//Group Delete
4541
4542                                //Clone selected containers
4543                                if(!strcmp(gcCommand,"Group Clone"))
4544                                {
4545                                        struct structContainer sContainer;
4546                                        static unsigned uOnlyOnce=1;
4547                                        char cConfBuffer[256]={""};
4548                                        char cAutoCloneIPClass[256]={""};
4549
4550                                        InitContainerProps(&sContainer);
4551                                        GetContainerProps(uCtContainer,&sContainer);
4552                                        if( (sContainer.uStatus==uACTIVE || sContainer.uStatus==uSTOPPED)
4553                                                && (sContainer.uOwner==guCompany || guCompany==1))
4554                                        {
4555                                                //For complete clone run, these stay constant.
4556                                                if(uOnlyOnce)
4557                                                {
4558
4559                                                //We can only fo this if tConfiguration has been setup
4560                                                //with datacenter wide cAutoCloneNode=node1,cAutoCloneSyncTime=600
4561                                                //for example.
4562                                                GetConfiguration("cAutoCloneNode",cConfBuffer,uDatacenter,0,0,0);
4563                                                if(cConfBuffer[0])
4564                                                        uTargetNode=ReadPullDown("tNode","cLabel",cConfBuffer);
4565                                                //We need the cuSyncPeriod
4566                                                uSyncPeriod=0;//Never rsync
4567                                                GetConfiguration("cAutoCloneSyncTime",cConfBuffer,uDatacenter,0,0,0);
4568                                                if(cConfBuffer[0])
4569                                                        sscanf(cConfBuffer,"%u",&uSyncPeriod);
4570                                                GetConfiguration("cAutoCloneIPClass",cAutoCloneIPClass,uDatacenter,
4571                                                        0,0,0);
4572
4573                                                        uOnlyOnce=0;
4574
4575                                                }
4576                                                //Basic conditions
4577                                                //We do not allow clones of clones yet.
4578                                                if(uTargetNode && !sContainer.uSource && cAutoCloneIPClass[0])
4579                                                {
4580                                                        unsigned uNewVeid=0;
4581                                                        MYSQL_RES *res;
4582                                                        MYSQL_ROW field;
4583
4584                                                        //Get next available IP, set uIPv4
4585                                                        uWizIPv4=0;
4586                                                        //TODO we cant let root just grab anybodys IPs
4587                                                        if(guCompany==1)
4588                                                                sprintf(gcQuery,"SELECT uIP FROM tIP WHERE"
4589                                                                " uAvailable=1 AND cLabel LIKE '%s.%%' LIMIT 1",
4590                                                                        cAutoCloneIPClass);
4591                                                        else
4592                                                                sprintf(gcQuery,"SELECT uIP FROM tIP WHERE"
4593                                                                        " uAvailable=1 AND cLabel LIKE '%s.%%' AND"
4594                                                                " uOwner=%u LIMIT 1",cAutoCloneIPClass,guCompany);
4595                                                        mysql_query(&gMysql,gcQuery);
4596                                                        if(mysql_errno(&gMysql))
4597                                                                htmlPlainTextError(mysql_error(&gMysql));
4598                                                        res=mysql_store_result(&gMysql);
4599                                                        if((field=mysql_fetch_row(res)))
4600                                                                sscanf(field[0],"%u",&uWizIPv4);
4601                                                        mysql_free_result(res);
4602
4603                                                        //
4604                                                        //We impose further abort conditions
4605
4606                                                        //Need valid clone IP
4607                                                        if(!uWizIPv4)
4608                                                        {
4609                                                                sprintf(cResult,"Need valid clone IP");
4610                                                                break;
4611                                                        }
4612                                                        if(uWizIPv4==sContainer.uIPv4)
4613                                                        {
4614                                                                sprintf(cResult,"Invalid clone IP");
4615                                                                break;
4616                                                        }
4617
4618                                                        //Target node can't match source node.
4619                                                        if(uTargetNode==sContainer.uNode)
4620                                                        {
4621                                                                sprintf(cResult,"Target node can't match source node");
4622                                                                break;
4623                                                        }
4624
4625                                                        //Check for sane sync periods
4626                                                        if(!uSyncPeriod && uSyncPeriod<300 && uSyncPeriod>86400*30)
4627                                                        {
4628                                                                sprintf(cResult,"Insane sync periods");
4629                                                                break;
4630                                                        }
4631
4632                                                        //If the container is VETH then target node must support it.
4633                                                        if(sContainer.uVeth)
4634                                                        {
4635                                                                GetNodeProp(uNode,"Container-Type",cConfBuffer);
4636                                                                if(!strstr(cConfBuffer,"VETH"))
4637                                                                {
4638                                                                        sprintf(cResult,"Non VETH target node");
4639                                                                        break;
4640                                                                }
4641                                                        }
4642
4643                                                        //We require group now.
4644                                                        //Get group from source container
4645                                                        uGroup=uGetGroup(0,uCtContainer);
4646                                                        if(!uGroup)
4647                                                        {
4648                                                                sprintf(cResult,"We require group");
4649                                                                break;
4650                                                        }
4651
4652                                                        //Finally we can create the clone container
4653                                                        //and the clone job
4654                                                        uNewVeid=CommonCloneContainer(
4655                                                                        uCtContainer,
4656                                                                        sContainer.uOSTemplate,
4657                                                                        sContainer.uConfig,
4658                                                                        sContainer.uNameserver,
4659                                                                        sContainer.uSearchdomain,
4660                                                                        sContainer.uDatacenter,
4661                                                                        sContainer.uDatacenter,
4662                                                                        sContainer.uOwner,
4663                                                                        sContainer.cLabel,
4664                                                                        sContainer.uNode,
4665                                                                        sContainer.uStatus,
4666                                                                        sContainer.cHostname,
4667                                                                        "",
4668                                                                        uWizIPv4,
4669                                                                        cWizLabel,
4670                                                                        cWizHostname,
4671                                                                        uTargetNode,
4672                                                                        uSyncPeriod,
4673                                                                        guLoginClient,
4674                                                                        uCloneStop,0);
4675                                                        //Now that container exists we can assign group.
4676                                                        if(!uNewVeid)
4677                                                        {
4678                                                                sprintf(cResult,"uNewVeid error");
4679                                                                break;
4680                                                        }
4681                                                        ChangeGroup(uNewVeid,uGroup);
4682                                                        SetContainerStatus(uCtContainer,uAWAITCLONE);
4683                                                        SetContainerStatus(uNewVeid,uAWAITCLONE);
4684                                                        sprintf(cResult,"Clone job created");
4685                                                }
4686                                                else
4687                                                {
4688                                                        sprintf(cResult,"Clones of clones not allowed");
4689                                                }
4690                                        }
4691                                        else
4692                                        {
4693                                                        sprintf(cResult,"Clone job not created");
4694                                        }
4695                                        break;
4696                                }//Group Clone
4697
4698                                //Start or Create
4699                                else if(!strcmp(gcCommand,"Group Start"))
4700                                {
4701                                        struct structContainer sContainer;
4702
4703                                        InitContainerProps(&sContainer);
4704                                        GetContainerProps(uCtContainer,&sContainer);
4705
4706                                        if((sContainer.uStatus==uSTOPPED || sContainer.uStatus==uINITSETUP)
4707                                                && (sContainer.uOwner==guCompany || guCompany==1))
4708                                        {
4709                                                if(sContainer.uStatus==uINITSETUP)
4710                                                {
4711                                                        if(CreateNewContainerJob(sContainer.uDatacenter,
4712                                                                sContainer.uNode,uCtContainer,sContainer.uOwner))
4713                                                        {
4714                                                                SetContainerStatus(uCtContainer,uAWAITACT);
4715                                                                sprintf(cResult,"Start job created for init setup container");
4716                                                        }
4717                                                }
4718                                                else
4719                                                {
4720                                                        uOwner=guCompany;
4721                                                        if(CreateStartContainerJob(sContainer.uDatacenter,
4722                                                                sContainer.uNode,uCtContainer,sContainer.uOwner))
4723                                                        {
4724                                                                SetContainerStatus(uCtContainer,uAWAITACT);
4725                                                                sprintf(cResult,"Start job created for stopped container");
4726                                                        }
4727                                                }
4728                                        }
4729                                        else
4730                                        {
4731                                                sprintf(cResult,"Start job not created");
4732                                        }
4733                                        break;
4734                                }//Group Start
4735
4736                                //execute any commands in container(s)
4737                                else if(!strcmp(gcCommand,"Group Execute"))
4738                                {
4739                                        struct structContainer sContainer;
4740
4741                                        InitContainerProps(&sContainer);
4742                                        GetContainerProps(uCtContainer,&sContainer);
4743
4744                                        if(     sContainer.uStatus==uACTIVE
4745                                                && (sContainer.uOwner==guCompany || guCompany==1) && cCommands[0])
4746                                        {
4747
4748                                                if(strlen(cCommands)>2047)
4749                                                {
4750                                                        sprintf(cResult,"Script too long");
4751                                                        break;
4752                                                }
4753                                                if(CreateExecuteCommandsJob(sContainer.uDatacenter,
4754                                                                sContainer.uNode,uCtContainer,sContainer.uOwner,cCommands))
4755                                                        sprintf(cResult,"Execute job created");
4756                                        }
4757                                        else
4758                                        {
4759                                                sprintf(cResult,"Execute job not created");
4760                                        }
4761                                        break;
4762                                }//Group Execute
4763
4764                                else if(!strcmp(gcCommand,"Group Template"))
4765                                {
4766                                        struct structContainer sContainer;
4767
4768                                        InitContainerProps(&sContainer);
4769                                        GetContainerProps(uCtContainer,&sContainer);
4770
4771                                        if((sContainer.uStatus==uSTOPPED || sContainer.uStatus==uACTIVE)
4772                                                && (sContainer.uOwner==guCompany || guCompany==1))
4773                                        {
4774                                                MYSQL_RES *res;
4775                                                char cOSTLabel[101]={""};
4776                                                char cConfigLabel[33]={""};
4777
4778                                                //Here we set the template to use the source container short name label
4779                                                sprintf(cConfigLabel,"%.31s",ForeignKey("tContainer","cLabel",uCtContainer));
4780                                                sprintf(cOSTLabel,"%.100s",ForeignKey("tOSTemplate","cLabel",sContainer.uOSTemplate));
4781                                                if(!cOSTLabel[0])
4782                                                {
4783                                                        sprintf(cResult,"No tOSTemplate.cLabel");
4784                                                        break;
4785                                                }
4786                                                if(!cConfigLabel[0])
4787                                                {
4788                                                        sprintf(cResult,"No tContainer.cLabel");
4789                                                        break;
4790                                                }
4791                                                sprintf(gcQuery,"SELECT uConfig FROM tConfig WHERE cLabel='%s'",cConfigLabel);
4792                                                mysql_query(&gMysql,gcQuery);
4793                                                if(mysql_errno(&gMysql))
4794                                                        htmlPlainTextError(mysql_error(&gMysql));
4795                                                res=mysql_store_result(&gMysql);
4796                                                if(mysql_num_rows(res)>0)
4797                                                {
4798                                                        sprintf(cResult,"tConfig.cLabel collision");
4799                                                        break;
4800                                                }
4801                                                mysql_free_result(res);
4802                                                sprintf(gcQuery,"SELECT uOSTemplate FROM tOSTemplate WHERE cLabel='%.67s-%.32s'",
4803                                                                cOSTLabel,cConfigLabel);
4804                                                mysql_query(&gMysql,gcQuery);
4805                                                if(mysql_errno(&gMysql))
4806                                                        htmlPlainTextError(mysql_error(&gMysql));
4807                                                res=mysql_store_result(&gMysql);
4808                                                if(mysql_num_rows(res)>0)
4809                                                {
4810                                                        sprintf(cResult,"tOSTemplate.cLabel collision");
4811                                                        break;
4812                                                }
4813
4814                                                if(TemplateContainerJob(sContainer.uDatacenter,
4815                                                        sContainer.uNode,uCtContainer,sContainer.uStatus,
4816                                                        sContainer.uOwner,cConfigLabel))
4817                                                {
4818                                                        SetContainerStatus(uCtContainer,uAWAITTML);
4819                                                        sprintf(cResult,"Template job created");
4820                                                }
4821                                                else
4822                                                {
4823                                                        sprintf(cResult,"Template job creation error");
4824                                                }
4825                                        }
4826                                        else
4827                                        {
4828                                                sprintf(cResult,"Template job ignored");
4829                                        }
4830                                        break;
4831                                }//Group Template
4832
4833                                else if(!strcmp(gcCommand,"Group Switchover"))
4834                                {
4835                                //These two jobs are always done in pairs. Even though the second may run much later
4836                                //for example after hardware failure has been fixed.
4837                                        struct structContainer sContainer;
4838
4839                                        InitContainerProps(&sContainer);
4840                                        GetContainerProps(uCtContainer,&sContainer);
4841                                        if( sContainer.uSource!=0 &&
4842                                                 (sContainer.uStatus==uSTOPPED || sContainer.uStatus==uACTIVE)
4843                                                && (sContainer.uOwner==guCompany || guCompany==1))
4844                                        {
4845                                                unsigned uFailToJob=0;
4846                                                if((uFailToJob=FailoverToJob(sContainer.uDatacenter,sContainer.uNode,
4847                                                        uCtContainer,sContainer.uOwner,guLoginClient,0)))
4848                                                {
4849                                                        unsigned uSourceDatacenter=0;
4850                                                        unsigned uSourceNode=0;
4851                                                        sscanf(ForeignKey("tContainer","uDatacenter",
4852                                                                sContainer.uSource),
4853                                                                "%u",&uSourceDatacenter);
4854                                                        sscanf(ForeignKey("tContainer","uNode",
4855                                                                sContainer.uSource),
4856                                                                "%u",&uSourceNode);
4857
4858                                                        if(FailoverFromJob(uSourceDatacenter,uSourceNode,
4859                                                                sContainer.uSource,sContainer.uIPv4,
4860                                                                sContainer.cLabel,sContainer.cHostname,
4861                                                                        uCtContainer,sContainer.uStatus,
4862                                                                        uFailToJob,sContainer.uOwner,guLoginClient,0))
4863                                                        {
4864                                                                SetContainerStatus(uCtContainer,uAWAITFAIL);
4865                                                                SetContainerStatus(sContainer.uSource,uAWAITFAIL);
4866                                                                sprintf(cResult,"Switchover job created");
4867                                                        }
4868                                                        else
4869                                                        {
4870                                                                sprintf(cResult,"FailoverFromJob() failed");
4871                                                        }
4872                                                }
4873                                                else
4874                                                {
4875                                                        sprintf(cResult,"FailoverToJob() failed");
4876                                                }
4877                                        }
4878                                        else
4879                                        {
4880                                                sprintf(cResult,"Switchover job ignored");
4881                                        }
4882                                        break;
4883                                }//Group Switchover
4884
4885                                //Group Migration Uses guOpOnClones, uTargetNode and guCloneTargetNode
4886                                else if(!strcmp(gcCommand,"Group Migration"))
4887                                {
4888                                //This is a new type of group job that requires a uTargetNode and
4889                                //optionally a guCloneTargetNode that must be set in the left panel
4890                                        struct structContainer sContainer;
4891
4892                                        //debug
4893                                        //sprintf(gcQuery,"d1: target node %u clone target node %u",uTargetNode,guCloneTargetNode);
4894                                        //tContainer(gcQuery);
4895                                        if(uTargetNode==guCloneTargetNode)
4896                                        {
4897                                                sprintf(gcQuery,"<blink>Error</blink> target node (%u) is the same as clone target node!",
4898                                                        uTargetNode);
4899                                                tContainer(gcQuery);
4900                                        }
4901                                        //More validation
4902                                        //Get most specific cAutoCloneNode
4903                                        unsigned uTargetDatacenter=0;
4904                                        sscanf(ForeignKey("tNode","uDatacenter",uTargetNode),"%u",&uTargetDatacenter);
4905                                        if(!uTargetDatacenter)
4906                                        {
4907                                                sprintf(gcQuery,"<blink>Error</blink> target node (%u) has no"
4908                                                                " datacenter configured",uTargetNode);
4909                                                tContainer(gcQuery);
4910                                        }
4911                                        if(guCloneTargetNode && guOpOnClones)
4912                                        {
4913                                                cAutoCloneNode[0]=0;
4914                                                GetConfiguration("cAutoCloneNode",cAutoCloneNode,uTargetDatacenter,uTargetNode,0,0);
4915                                                if(!cAutoCloneNode[0])
4916                                                        GetConfiguration("cAutoCloneNode",cAutoCloneNode,uTargetDatacenter,0,0,0);
4917                                                if(!cAutoCloneNode[0])
4918                                                {
4919                                                        sprintf(gcQuery,"<blink>Error</blink> target node (%u) has no"
4920                                                                        " tConfiguration cAutoCloneNode configured",uTargetNode);
4921                                                        tContainer(gcQuery);
4922                                                }
4923                                                unsigned uCloneTargetNode=0;
4924                                                uCloneTargetNode=ReadPullDown("tNode","cLabel",cAutoCloneNode);
4925                                                if(!uCloneTargetNode)
4926                                                {
4927                                                        sprintf(gcQuery,"<blink>Error</blink> cAutoCloneNode %s has no"
4928                                                                        " tNode entry!",cAutoCloneNode);
4929                                                        tContainer(gcQuery);
4930                                                }
4931                                                if(uCloneTargetNode!=guCloneTargetNode)
4932                                                {
4933                                                        sprintf(gcQuery,"<blink>Error</blink> Target node auto clone target %s (%u)"
4934                                                                        " does not match provided"
4935                                                                        " guCloneTargetNode (%u)!",
4936                                                                                cAutoCloneNode,uCloneTargetNode,guCloneTargetNode);
4937                                                        tContainer(gcQuery);
4938                                                }
4939                                        }
4940
4941                                        InitContainerProps(&sContainer);
4942                                        GetContainerProps(uCtContainer,&sContainer);
4943                                        if( uTargetNode && (sContainer.uStatus==uSTOPPED || sContainer.uStatus==uACTIVE)
4944                                                && (sContainer.uOwner==guCompany || guCompany==1))
4945                                        {
4946
4947                                                if(MigrateContainerJob(sContainer.uDatacenter,
4948                                                                        sContainer.uNode,uCtContainer,uTargetNode,
4949                                                                        sContainer.uOwner,guLoginClient,0,sContainer.uStatus))
4950                                                {
4951                                                        SetContainerStatus(uCtContainer,uAWAITMIG);
4952                                                        sprintf(cResult,"Migration job created");
4953
4954                                                        if(guCloneTargetNode && guOpOnClones)
4955                                                        {
4956                                                                unsigned uCloneDatacenter=0;
4957                                                                unsigned uCloneNode=0;
4958                                                                unsigned uCloneContainer=0;
4959                                                                unsigned uCloneOwner=0;
4960                                                                unsigned uCloneStatus=0;
4961                                                                MYSQL_RES *res;
4962                                                                MYSQL_ROW field;
4963
4964                                                                sprintf(gcQuery,"SELECT uDatacenter,uNode,uContainer,uStatus,uOwner FROM tContainer"
4965                                                                        " WHERE uSource=%u",uCtContainer);
4966                                                                mysql_query(&gMysql,gcQuery);
4967                                                                if(mysql_errno(&gMysql))
4968                                                                        htmlPlainTextError(mysql_error(&gMysql));
4969                                                                res=mysql_store_result(&gMysql);
4970                                                                while((field=mysql_fetch_row(res)))
4971                                                                {
4972                                                                        sscanf(field[0],"%u",&uCloneDatacenter);
4973                                                                        sscanf(field[1],"%u",&uCloneNode);
4974                                                                        sscanf(field[2],"%u",&uCloneContainer);
4975                                                                        sscanf(field[3],"%u",&uCloneStatus);
4976                                                                        sscanf(field[4],"%u",&uCloneOwner);
4977                                                                        if((uCloneStatus==uSTOPPED || uCloneStatus==uACTIVE)
4978                                                                                && (uCloneOwner==guCompany || guCompany==1)
4979                                                                                //Do not create useless job if clone is already on
4980                                                                                //target node
4981                                                                                && (guCloneTargetNode!=uCloneNode) )
4982                                                                        {
4983                                                                                if(MigrateContainerJob(uCloneDatacenter,
4984                                                                                        uCloneNode,uCloneContainer,guCloneTargetNode,
4985                                                                                        uCloneOwner,guLoginClient,0,uCloneStatus))
4986                                                                                {
4987                                                                                        SetContainerStatus(uCloneContainer,uAWAITMIG);
4988                                                                                        strcat(cResult," +clone job");
4989
4990                                                                                }
4991                                                                                else
4992                                                                                {
4993                                                                                        strcat(cResult," +clone job error");
4994                                                                                }
4995                                                                        }
4996                                                                        else
4997                                                                        {
4998                                                                                strcat(cResult," +clone job ignored");
4999                                                                        }
5000                                                                }
5001                                                        }
5002                                                }
5003                                                else
5004                                                {
5005                                                        sprintf(cResult,"Migration job failed");
5006                                                }
5007                                        }
5008                                        else
5009                                        {
5010                                                sprintf(cResult,"Migration job ignored");
5011                                        }
5012                                        break;
5013                                }//Group Migration
5014
5015                                else if(1)
5016                                {
5017                                        sprintf(cResult,"Unexpected gcCommand=%.64s",gcCommand);
5018                                        break;
5019                                }
5020                        }//end if Ct block
5021                }//end for()
5022        }
5023
5024        printf("<tr>");
5025        printf("<td width=200 valign=top>"
5026        "<input type=checkbox name=Ct%s >"
5027        "<a class=darkLink href=unxsVZ.cgi?gcFunction=tContainer&uContainer=%s>%s</a>"
5028        "</td>"
5029        "<td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>\n",
5030                field[0],field[0],field[1],field[2],field[3],field[4],field[5],field[6],field[7],field[8],field[9],field[10],cResult);
5031        printf("</tr>");
5032
5033}//while()
5034//Reset margin end
5035
5036                        printf("<tr><td><input type=checkbox name=all onClick='checkAll(document.formMain,this)'>"
5037                                        "Check all %u containers</td></tr>\n",uNumRows);
5038                        printf("</table>");
5039
5040                        }//If results
5041                        mysql_free_result(res);
5042                        CloseFieldSet();
5043                break;
5044
5045                default:
5046
5047                        if(uHideProps || !uContainer || (guMode!=0 && guMode!=6)) return;
5048
5049                        sprintf(gcQuery,"%s Property Panel",cLabel);
5050                        OpenFieldSet(gcQuery,100);
5051                        sprintf(gcQuery,"SELECT uProperty,cName,cValue FROM tProperty WHERE uKey=%u AND uType=3"
5052                                " AND cName!='Notes' ORDER BY cName",uContainer);
5053                        mysql_query(&gMysql,gcQuery);
5054                        if(mysql_errno(&gMysql))
5055                                htmlPlainTextError(mysql_error(&gMysql));
5056                        res=mysql_store_result(&gMysql);
5057                        if(mysql_num_rows(res))
5058                        {
5059                                printf("<table>");
5060                                while((field=mysql_fetch_row(res)))
5061                                {
5062                                        printf("<tr>");
5063                                        printf("<td width=200 valign=top><a class=darkLink href=unxsVZ.cgi?"
5064                                        "gcFunction=tProperty&uProperty=%s&cReturn=tContainer_%u>"
5065                                        "%s</a></td><td>%s</td>\n",
5066                                                field[0],uContainer,field[1],field[2]);
5067                                        printf("</tr>");
5068                                }
5069                                printf("</table>");
5070                        }
5071                        mysql_free_result(res);
5072
5073                        //Special per container buttons
5074                        if((uStatus==uACTIVE || uStatus==uSTOPPED) && uAllowDel(uOwner,uCreatedBy))
5075                                printf("<p><input title='Creates a job for stopping and destroying an active container."
5076                                        " No backups may be available, the container is gone for good!'"
5077                                        " type=submit class=lwarnButton"
5078                                        " name=gcCommand value='Destroy %.24s'>\n",cLabel);
5079
5080                        CloseFieldSet();
5081
5082        }//switch(guMode)
5083
5084}//void ExttContainerAuxTable(void)
5085
5086
5087void ExttContainerGetHook(entry gentries[], int x)
5088{
5089        register int i;
5090
5091        for(i=0;i<x;i++)
5092        {
5093                if(!strcmp(gentries[i].name,"uContainer"))
5094                {
5095                        sscanf(gentries[i].val,"%u",&uContainer);
5096                        guMode=6;
5097                }
5098                else if(!strcmp(gentries[i].name,"cSearch"))
5099                {
5100                        sprintf(cSearch,"%.31s",gentries[i].val);
5101                }
5102                else if(!strcmp(gentries[i].name,"uGroup"))
5103                {
5104                        sscanf(gentries[i].val,"%u",&uGroup);
5105                }
5106        }
5107        tContainer("");
5108
5109}//void ExttContainerGetHook(entry gentries[], int x)
5110
5111
5112void ExttContainerSelect(void)
5113{
5114        if(cSearch[0])
5115                ExtSelectSearch("tContainer",VAR_LIST_tContainer,"cLabel",cSearch);
5116        else
5117                ExtSelect("tContainer",VAR_LIST_tContainer);
5118
5119}//void ExttContainerSelect(void)
5120
5121
5122void ExttContainerSelectRow(void)
5123{
5124        ExtSelectRow("tContainer",VAR_LIST_tContainer,uContainer);
5125
5126}//void ExttContainerSelectRow(void)
5127
5128
5129void ExttContainerListSelect(void)
5130{
5131        char cCat[512];
5132
5133        if(guLoginClient==1 && guPermLevel>11)//Root can read access all
5134                sprintf(gcQuery,"SELECT %s FROM tContainer",
5135                                VAR_LIST_tContainer);
5136        else
5137                sprintf(gcQuery,"SELECT %1$s FROM tContainer," TCLIENT
5138                                " WHERE tContainer.uOwner=" TCLIENT ".uClient"
5139                                " AND (" TCLIENT ".uClient=%2$u OR " TCLIENT ".uOwner"
5140                                " IN (SELECT uClient FROM " TCLIENT " WHERE uOwner=%2$u OR uClient=%2$u))",
5141                                VAR_LIST_tContainer,guCompany);
5142
5143        //Changes here must be reflected below in ExttContainerListFilter()
5144        if(!strcmp(gcFilter,"uContainer"))
5145        {
5146                sscanf(gcCommand,"%u",&uContainer);
5147                if(guLoginClient==1 && guPermLevel>11)
5148                        strcat(gcQuery," WHERE ");
5149                else
5150                        strcat(gcQuery," AND ");
5151                sprintf(cCat,"tContainer.uContainer=%u ORDER BY uContainer",uContainer);
5152                strcat(gcQuery,cCat);
5153        }
5154        else if(!strcmp(gcFilter,"cLabel"))
5155        {
5156                if(guLoginClient==1 && guPermLevel>11)
5157                        strcat(gcQuery," WHERE ");
5158                else
5159                        strcat(gcQuery," AND ");
5160                sprintf(cCat,"tContainer.cLabel LIKE '%s' ORDER BY cLabel,uContainer",gcCommand);
5161                strcat(gcQuery,cCat);
5162        }
5163        else if(!strcmp(gcFilter,"cHostname"))
5164        {
5165                if(guLoginClient==1 && guPermLevel>11)
5166                        strcat(gcQuery," WHERE ");
5167                else
5168                        strcat(gcQuery," AND ");
5169                sprintf(cCat,"tContainer.cHostname LIKE '%s' ORDER BY cHostname,uContainer",gcCommand);
5170                strcat(gcQuery,cCat);
5171        }
5172        else if(!strcmp(gcFilter,"uDatacenter"))
5173        {
5174                sscanf(gcCommand,"%u",&uDatacenter);
5175                if(guLoginClient==1 && guPermLevel>11)
5176                        strcat(gcQuery," WHERE ");
5177                else
5178                        strcat(gcQuery," AND ");
5179                sprintf(cCat,"tContainer.uDatacenter=%u ORDER BY uDatacenter,uContainer",uDatacenter);
5180                strcat(gcQuery,cCat);
5181        }
5182        else if(!strcmp(gcFilter,"uNode"))
5183        {
5184                sscanf(gcCommand,"%u",&uNode);
5185                if(guLoginClient==1 && guPermLevel>11)
5186                        strcat(gcQuery," WHERE ");
5187                else
5188                        strcat(gcQuery," AND ");
5189                sprintf(cCat,"tContainer.uNode=%u ORDER BY uContainer",uNode);
5190                strcat(gcQuery,cCat);
5191        }
5192        else if(!strcmp(gcFilter,"uStatus"))
5193        {
5194                sscanf(gcCommand,"%u",&uStatus);
5195                if(guLoginClient==1 && guPermLevel>11)
5196                        strcat(gcQuery," WHERE ");
5197                else
5198                        strcat(gcQuery," AND ");
5199                sprintf(cCat,"tContainer.uStatus=%u ORDER BY uStatus,uContainer",uStatus);
5200                strcat(gcQuery,cCat);
5201        }
5202        else if(!strcmp(gcFilter,"uOwner"))
5203        {
5204                sscanf(gcCommand,"%u",&uOwner);
5205                if(guLoginClient==1 && guPermLevel>11)
5206                        strcat(gcQuery," WHERE ");
5207                else
5208                        strcat(gcQuery," AND ");
5209                sprintf(cCat,"tContainer.uOwner=%u ORDER BY uOwner,uContainer",uOwner);
5210                strcat(gcQuery,cCat);
5211        }
5212        else if(!strcmp(gcFilter,"uGroup"))
5213        {
5214                unsigned uGroup=0;
5215
5216                sscanf(gcCommand,"%u",&uGroup);
5217                if(guLoginClient==1 && guPermLevel>11)
5218                        strcat(gcQuery," WHERE ");
5219                else
5220                        strcat(gcQuery," AND ");
5221                sprintf(cCat,"tContainer.uContainer IN (SELECT uContainer FROM tGroupGlue WHERE uGroup=%u) ORDER BY uOwner,uContainer",uGroup);
5222                strcat(gcQuery,cCat);
5223        }
5224        else if(1)
5225        {
5226                //None NO FILTER
5227                strcpy(gcFilter,"None");
5228                strcat(gcQuery," ORDER BY uContainer");
5229        }
5230
5231}//void ExttContainerListSelect(void)
5232
5233
5234void ExttContainerListFilter(void)
5235{
5236        //Filter
5237        printf("&nbsp;&nbsp;&nbsp;Filter on ");
5238        printf("<select name=gcFilter>");
5239        if(strcmp(gcFilter,"uGroup"))
5240                printf("<option>uGroup</option>");
5241        else
5242                printf("<option selected>uGroup</option>");
5243        if(strcmp(gcFilter,"uContainer"))
5244                printf("<option>uContainer</option>");
5245        else
5246                printf("<option selected>uContainer</option>");
5247        if(strcmp(gcFilter,"cLabel"))
5248                printf("<option>cLabel</option>");
5249        else
5250                printf("<option selected>cLabel</option>");
5251        if(strcmp(gcFilter,"cHostname"))
5252                printf("<option>cHostname</option>");
5253        else
5254                printf("<option selected>cHostname</option>");
5255        if(strcmp(gcFilter,"uDatacenter"))
5256                printf("<option>uDatacenter</option>");
5257        else
5258                printf("<option selected>uDatacenter</option>");
5259        if(strcmp(gcFilter,"uNode"))
5260                printf("<option>uNode</option>");
5261        else
5262                printf("<option selected>uNode</option>");
5263        if(strcmp(gcFilter,"uStatus"))
5264                printf("<option>uStatus</option>");
5265        else
5266                printf("<option selected>uStatus</option>");
5267        if(strcmp(gcFilter,"uOwner"))
5268                printf("<option>uOwner</option>");
5269        else
5270                printf("<option selected>uOwner</option>");
5271        if(strcmp(gcFilter,"None"))
5272                printf("<option>None</option>");
5273        else
5274                printf("<option selected>None</option>");
5275        printf("</select>");
5276
5277}//void ExttContainerListFilter(void)
5278
5279
5280void ExttContainerNavBar(void)
5281{
5282        if(guMode<9000)
5283        {
5284                printf(LANG_NBB_SKIPFIRST);
5285                printf(LANG_NBB_SKIPBACK);
5286                printf(LANG_NBB_SEARCH);
5287        }
5288
5289        if(guPermLevel>7 && !guListMode && guMode<9000)
5290                printf(LANG_NBB_NEW);
5291
5292        //11 Initial setup 31 Stopped
5293        if( (uStatus==uINITSETUP) && uAllowMod(uOwner,uCreatedBy) && guMode<9000)
5294                printf(LANG_NBB_MODIFY);
5295
5296        if( (uStatus==uINITSETUP && uAllowDel(uOwner,uCreatedBy) && guMode<9000) ||
5297                (uStatus==uOFFLINE && guPermLevel>11) ||
5298                (uStatus==uAWAITCLONE && guPermLevel>11) )
5299                printf(LANG_NBB_DELETE);
5300
5301        if(uOwner && guMode<9000)
5302                printf(LANG_NBB_LIST);
5303
5304        if(guMode<9000)
5305        {
5306                printf(LANG_NBB_SKIPNEXT);
5307                printf(LANG_NBB_SKIPLAST);
5308        }
5309        printf("&nbsp;&nbsp;&nbsp;\n");
5310
5311}//void ExttContainerNavBar(void)
5312
5313//uNode=0 means container mode or tContainer tab mode.
5314//uNode!=0 is used for a nav list of containers from same node.
5315void tContainerNavList(unsigned uNode, char *cSearch)
5316{
5317        MYSQL_RES *res;
5318        MYSQL_ROW field;
5319        unsigned uNumRows=0;
5320        unsigned uMySQLNumRows=0;
5321#define uLIMIT 64
5322
5323        if(!uNode)
5324        {
5325                if(!cSearch[0])
5326                        return;
5327
5328            if(guNoClones)
5329            {
5330                        if(cSearch[0])
5331                        {
5332                                if(guLoginClient==1 && guPermLevel>11)//Root can read access all
5333                                        sprintf(gcQuery,"SELECT tContainer.uContainer,tContainer.cLabel,"
5334                                                "tNode.cLabel,tStatus.cLabel FROM tContainer,tNode,tStatus"
5335                                                " WHERE tContainer.uNode=tNode.uNode"
5336                                                " AND tContainer.uStatus=tStatus.uStatus"
5337                                                " AND tContainer.uSource=0"
5338                                                " AND tContainer.cLabel LIKE '%s%%'"
5339                                                " ORDER BY tContainer.cLabel",cSearch);
5340                                else
5341                                        sprintf(gcQuery,"SELECT tContainer.uContainer"
5342                                                ",tContainer.cLabel,tNode.cLabel,tStatus.cLabel"
5343                                                " FROM tContainer," TCLIENT ",tNode,tStatus"
5344                                                " WHERE tContainer.uOwner=" TCLIENT ".uClient"
5345                                                " AND (" TCLIENT ".uClient=%1$u OR " TCLIENT ".uOwner"
5346                                                " IN (SELECT uClient FROM " TCLIENT " WHERE uOwner=%1$u OR uClient=%1$u))"
5347                                                " AND tContainer.uNode=tNode.uNode"
5348                                                " AND tContainer.uStatus=tStatus.uStatus"
5349                                                " AND tContainer.uSource=0"
5350                                                " AND tContainer.cLabel LIKE '%2$s%%'"
5351                                                " ORDER BY tContainer.cLabel",guCompany,cSearch);
5352                        }
5353           }
5354           else if(guInitOnly)
5355           {
5356                if(cSearch[0])
5357                {
5358                        if(guLoginClient==1 && guPermLevel>11)//Root can read access all
5359                                sprintf(gcQuery,"SELECT tContainer.uContainer,tContainer.cLabel,"
5360                                        "tNode.cLabel,tStatus.cLabel FROM tContainer,tNode,tStatus"
5361                                        " WHERE tContainer.uNode=tNode.uNode"
5362                                        " AND tContainer.uStatus=tStatus.uStatus"
5363                                        " AND tContainer.uStatus=11"
5364                                        " AND tContainer.cLabel LIKE '%s%%'"
5365                                        " ORDER BY tContainer.cLabel",cSearch);
5366                        else
5367                                sprintf(gcQuery,"SELECT tContainer.uContainer"
5368                                        ",tContainer.cLabel,tNode.cLabel,tStatus.cLabel"
5369                                        " FROM tContainer," TCLIENT ",tNode,tStatus"
5370                                        " WHERE tContainer.uOwner=" TCLIENT ".uClient"
5371                                        " AND (" TCLIENT ".uClient=%1$u OR " TCLIENT ".uOwner"
5372                                        " IN (SELECT uClient FROM " TCLIENT " WHERE uOwner=%1$u OR uClient=%1$u))"
5373                                        " AND tContainer.uNode=tNode.uNode"
5374                                        " AND tContainer.uStatus=tStatus.uStatus"
5375                                        " AND tContainer.uStatus=11"
5376                                        " AND tContainer.cLabel LIKE '%2$s%%'"
5377                                        " ORDER BY tContainer.cLabel",guCompany,cSearch);
5378                }
5379           }
5380           else //guNoClones==0 and guInitOnly==0
5381           {
5382                        if(cSearch[0])
5383                        {
5384                                if(guLoginClient==1 && guPermLevel>11)//Root can read access all
5385                                        sprintf(gcQuery,"SELECT tContainer.uContainer,tContainer.cLabel,"
5386                                                "tNode.cLabel,tStatus.cLabel FROM tContainer,tNode,tStatus"
5387                                                " WHERE tContainer.uNode=tNode.uNode"
5388                                                " AND tContainer.uStatus=tStatus.uStatus"
5389                                                " AND tContainer.cLabel LIKE '%s%%'"
5390                                                " ORDER BY tContainer.cLabel",cSearch);
5391                                else
5392                                        sprintf(gcQuery,"SELECT tContainer.uContainer"
5393                                                ",tContainer.cLabel,tNode.cLabel,tStatus.cLabel"
5394                                                " FROM tContainer," TCLIENT ",tNode,tStatus"
5395                                                " WHERE tContainer.uOwner=" TCLIENT ".uClient"
5396                                                " AND (" TCLIENT ".uClient=%1$u OR " TCLIENT ".uOwner"
5397                                                " IN (SELECT uClient FROM " TCLIENT " WHERE uOwner=%1$u OR uClient=%1$u))"
5398                                                " AND tContainer.uNode=tNode.uNode"
5399                                                " AND tContainer.uStatus=tStatus.uStatus"
5400                                                " AND tContainer.cLabel LIKE '%2$s%%'"
5401                                                " ORDER BY tContainer.cLabel",guCompany,cSearch);
5402                        }
5403           }
5404        }
5405        else
5406        {
5407
5408                //debug only
5409                //printf("<p>(uNode=%u cSearch=%s)",uNode,cSearch);
5410
5411                if(cSearch[0])
5412                {
5413                        if(guLoginClient==1 && guPermLevel>11)//Root can read access all
5414                                sprintf(gcQuery,"SELECT tContainer.uContainer,tContainer.cLabel,"
5415                                        "tNode.cLabel,tStatus.cLabel"
5416                                        " FROM tContainer,tNode,tStatus"
5417                                        " WHERE tContainer.uNode=tNode.uNode"
5418                                        " AND tContainer.uStatus=tStatus.uStatus"
5419                                        " AND tContainer.cLabel LIKE '%s%%'"
5420                                        " AND tContainer.uNode=%u ORDER BY tContainer.cLabel",cSearch,uNode);
5421                        else
5422                                sprintf(gcQuery,"SELECT tContainer.uContainer"
5423                                        ",tContainer.cLabel,tNode.cLabel,tStatus.cLabel"
5424                                        " FROM tContainer," TCLIENT ",tNode,tStatus"
5425                                        " WHERE tContainer.uOwner=" TCLIENT ".uClient"
5426                                        " AND tContainer.uNode=%1$u"
5427                                        " AND (" TCLIENT ".uClient=%2$u OR " TCLIENT ".uOwner"
5428                                        " IN (SELECT uClient FROM " TCLIENT " WHERE uOwner=%2$u OR uClient=%2$u))"
5429                                        " AND tContainer.uNode=tNode.uNode"
5430                                        " AND tContainer.uStatus=tStatus.uStatus"
5431                                        " AND tContainer.cLabel LIKE '%3$s%%'"
5432                                        " ORDER BY tContainer.cLabel",uNode,guCompany,cSearch);
5433                }
5434                else
5435                {
5436                        if(guLoginClient==1 && guPermLevel>11)//Root can read access all
5437                                sprintf(gcQuery,"SELECT tContainer.uContainer,tContainer.cLabel,"
5438                                        "tNode.cLabel,tStatus.cLabel"
5439                                        " FROM tContainer,tNode,tStatus"
5440                                        " WHERE tContainer.uNode=tNode.uNode"
5441                                        " AND tContainer.uStatus=tStatus.uStatus"
5442                                                " AND tContainer.uNode=%u ORDER BY tContainer.cLabel",uNode);
5443                        else
5444                                sprintf(gcQuery,"SELECT DISTINCT tContainer.uContainer"
5445                                        ",tContainer.cLabel,tNode.cLabel,tStatus.cLabel"
5446                                        " FROM tContainer," TCLIENT ",tNode,tStatus"
5447                                        " WHERE tContainer.uOwner=" TCLIENT ".uClient"
5448                                        " AND tContainer.uNode=%1$u"
5449                                        " AND (" TCLIENT ".uClient=%2$u OR " TCLIENT ".uOwner"
5450                                        " IN (SELECT uClient FROM " TCLIENT " WHERE uOwner=%2$u OR uClient=%2$u))"
5451                                        " AND tContainer.uNode=tNode.uNode"
5452                                        " AND tContainer.uStatus=tStatus.uStatus"
5453                                        " ORDER BY tContainer.cLabel",uNode,guCompany);
5454                }
5455                //debug only
5456                //printf("%s",gcQuery);
5457                //return;
5458
5459        }
5460
5461        mysql_query(&gMysql,gcQuery);
5462        if(mysql_errno(&gMysql))
5463        {
5464                printf("<p><u>tContainerNavList</u><br>\n");
5465                printf("%s",mysql_error(&gMysql));
5466                return;
5467        }
5468
5469        res=mysql_store_result(&gMysql);
5470        if((uMySQLNumRows=mysql_num_rows(res)))
5471        {       
5472                printf("<p><u>tContainerNavList(%d)</u><br>\n",uMySQLNumRows);
5473
5474                while((field=mysql_fetch_row(res)))
5475                {
5476                        if(guPermLevel>9 && uNode==0)
5477                        {
5478                                if(cSearch[0] && uGroup)
5479                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction="
5480                                        "tContainer&uContainer=%s&cSearch=%s&uGroup=%u>%s/%s/%s</a><br>\n",
5481                                                field[0],cURLEncode(cSearch),uGroup,field[1],field[2],field[3]);
5482                                else if(cSearch[0])
5483                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction="
5484                                        "tContainer&uContainer=%s&cSearch=%s>%s/%s/%s</a><br>\n",
5485                                                field[0],cURLEncode(cSearch),field[1],field[2],field[3]);
5486                                else if(uGroup)
5487                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction="
5488                                        "tContainer&uContainer=%s&uGroup=%u>%s/%s/%s</a><br>\n",
5489                                                field[0],uGroup,field[1],field[2],field[3]);
5490                                else
5491                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction="
5492                                        "tContainer&uContainer=%s>%s/%s/%s</a><br>\n",
5493                                                field[0],field[1],field[2],field[3]);
5494                        }
5495                        else
5496                        {
5497                                if(cSearch[0])
5498                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction=tContainer"
5499                                        "&uContainer=%s&cSearch=%s>%s/%s/%s</a><br>\n",
5500                                                field[0],cURLEncode(cSearch),field[1],field[2],field[3]);
5501                                else
5502                                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction=tContainer"
5503                                        "&uContainer=%s>%s/%s/%s</a><br>\n",
5504                                                field[0],field[1],field[2],field[3]);
5505                        }
5506                        if(++uNumRows>uLIMIT)
5507                        {
5508                                printf("(Only %u containers shown use search/filters to shorten list.)<br>\n",
5509                                                uLIMIT);
5510                                break;
5511                        }
5512                }
5513        }
5514        mysql_free_result(res);
5515
5516}//void tContainerNavList()
5517
5518
5519unsigned CreateNewContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner)
5520{
5521        unsigned uCount=0;
5522
5523        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='CreateNewContainerJob(%u)',cJobName='NewContainer'"
5524                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5525                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5526                        ",uJobStatus=1"
5527                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5528                                uContainer,
5529                                uDatacenter,uNode,uContainer,
5530                                uOwner,guLoginClient);
5531        mysql_query(&gMysql,gcQuery);
5532        if(mysql_errno(&gMysql))
5533                htmlPlainTextError(mysql_error(&gMysql));
5534        uCount=mysql_insert_id(&gMysql);
5535        return(uCount);
5536
5537}//unsigned CreateNewContainerJob(...)
5538
5539
5540unsigned CreateStartContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner)
5541{
5542        unsigned uCount=0;
5543
5544        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='CreateStartContainerJob(%u)',cJobName='StartContainer'"
5545                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5546                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5547                        ",uJobStatus=1"
5548                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5549                                uContainer,
5550                                uDatacenter,uNode,uContainer,
5551                                uOwner,guLoginClient);
5552        mysql_query(&gMysql,gcQuery);
5553        if(mysql_errno(&gMysql))
5554                htmlPlainTextError(mysql_error(&gMysql));
5555        uCount=mysql_insert_id(&gMysql);
5556        unxsVZLog(uContainer,"tContainer","Start");
5557        return(uCount);
5558
5559}//unsigned CreateStartContainerJob(...)
5560
5561
5562unsigned DestroyContainerJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer, unsigned uOwner)
5563{
5564        unsigned uCount=0;
5565
5566        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='DestroyContainerJob(%u)',cJobName='DestroyContainer'"
5567                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5568                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5569                        ",uJobStatus=1"
5570                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5571                                uContainer,
5572                                uDatacenter,uNode,uContainer,
5573                                uOwner,guLoginClient);
5574        mysql_query(&gMysql,gcQuery);
5575        if(mysql_errno(&gMysql))
5576                htmlPlainTextError(mysql_error(&gMysql));
5577        uCount=mysql_insert_id(&gMysql);
5578        unxsVZLog(uContainer,"tContainer","Destroy");
5579        return(uCount);
5580
5581}//unsigned DestroyContainerJob()
5582
5583
5584unsigned StopContainerJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer, unsigned uOwner)
5585{
5586        unsigned uCount=0;
5587
5588        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='StopContainerJob(%u)',cJobName='StopContainer'"
5589                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5590                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5591                        ",uJobStatus=1"
5592                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5593                                uContainer,
5594                                uDatacenter,uNode,uContainer,
5595                                uOwner,guLoginClient);
5596        mysql_query(&gMysql,gcQuery);
5597        if(mysql_errno(&gMysql))
5598                htmlPlainTextError(mysql_error(&gMysql));
5599        uCount=mysql_insert_id(&gMysql);
5600        unxsVZLog(uContainer,"tContainer","Stop");
5601        return(uCount);
5602
5603}//unsigned StopContainerJob(...)
5604
5605
5606//Keeps job container from staying stuck in an awaiting state,
5607//but is confusing in logs since the function below should be
5608//extended for this case.
5609unsigned CancelContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uCancelMode)
5610{
5611        unsigned uContainerJobsCanceled;
5612        unsigned uContainerCloneJobsCanceled;
5613
5614        //Cancel any jobs for uContainer 1=Waiting 10=RemoteWaiting, 14=Error
5615        sprintf(gcQuery,"UPDATE tJob SET uJobStatus=7 WHERE "
5616                        "uDatacenter=%u AND uNode=%u AND uContainer=%u AND (uJobStatus=1 OR uJobStatus=10 OR uJobStatus=14)"
5617                                ,uDatacenter,uNode,uContainer);
5618        mysql_query(&gMysql,gcQuery);
5619        if(mysql_errno(&gMysql))
5620                htmlPlainTextError(mysql_error(&gMysql));
5621        uContainerJobsCanceled=mysql_affected_rows(&gMysql);
5622
5623        //Also cancel any jobs for uContainer's clones 1=Waiting 10=RemoteWaiting, 14=Error
5624        sprintf(gcQuery,"UPDATE tJob SET uJobStatus=7 WHERE"
5625                        " uContainer=(SELECT uContainer FROM tContainer WHERE uSource=%u) AND"
5626                        " (uJobStatus=1 OR uJobStatus=10 OR uJobStatus=14)",uContainer);
5627        mysql_query(&gMysql,gcQuery);
5628        if(mysql_errno(&gMysql))
5629                htmlPlainTextError(mysql_error(&gMysql));
5630        uContainerCloneJobsCanceled=mysql_affected_rows(&gMysql);
5631
5632        //Also cancel master container clone jobs
5633        sprintf(gcQuery,"UPDATE tJob SET uJobStatus=7 WHERE"
5634                        " uContainer=(SELECT uSource FROM tContainer WHERE uContainer=%u) AND"
5635                        " (uJobStatus=1 OR uJobStatus=10 OR uJobStatus=14) AND cJobName='CloneContainer'",uContainer);
5636        mysql_query(&gMysql,gcQuery);
5637        if(mysql_errno(&gMysql))
5638                htmlPlainTextError(mysql_error(&gMysql));
5639
5640        //This convoluted logic is needed for specifically attempting to cancel container jobs uCancelMode=1
5641        //versus general job queue clean up attempts.
5642        if(uContainerJobsCanceled || uContainerCloneJobsCanceled)
5643        {
5644                unxsVZLog(uContainer,"tContainer","CancelJob");
5645                if(uCancelMode && !uContainerJobsCanceled)
5646                        return(1);
5647                else
5648                        return(0);
5649        }
5650        else if(uCancelMode)
5651        {
5652                unxsVZLog(uContainer,"tContainer","CancelJobLate");
5653                return(1);
5654        }
5655
5656        return(0);
5657
5658}//unsigned CancelContainerJob()
5659
5660
5661void SetContainerStatus(unsigned uContainer,unsigned uStatus)
5662{
5663        sprintf(gcQuery,"UPDATE tContainer SET uStatus=%u,uModBy=%u,uModDate=UNIX_TIMESTAMP(NOW())"
5664                        " WHERE uContainer=%u",
5665                                        uStatus,guLoginClient,uContainer);
5666        mysql_query(&gMysql,gcQuery);
5667        if(mysql_errno(&gMysql))
5668                htmlPlainTextError(mysql_error(&gMysql));
5669
5670}//void SetContainerStatus(unsigned uContainer,unsigned uStatus)
5671
5672
5673void SetContainerNode(unsigned uContainer,unsigned uNode)
5674{
5675        sprintf(gcQuery,"UPDATE tContainer SET uNode=%u,uModBy=%u,uModDate=UNIX_TIMESTAMP(NOW())"
5676                        " WHERE uContainer=%u",
5677                                        uNode,guLoginClient,uContainer);
5678        mysql_query(&gMysql,gcQuery);
5679        if(mysql_errno(&gMysql))
5680                htmlPlainTextError(mysql_error(&gMysql));
5681
5682}//void SetContainerNode(unsigned uContainer,unsigned uNode)
5683
5684
5685void SetContainerDatacenter(unsigned uContainer,unsigned uDatacenter)
5686{
5687        sprintf(gcQuery,"UPDATE tContainer SET uDatacenter=%u,uModBy=%u,uModDate=UNIX_TIMESTAMP(NOW())"
5688                        " WHERE uContainer=%u",
5689                                        uDatacenter,guLoginClient,uContainer);
5690        mysql_query(&gMysql,gcQuery);
5691        if(mysql_errno(&gMysql))
5692                htmlPlainTextError(mysql_error(&gMysql));
5693
5694}//void SetContainerDatacenter(unsigned uContainer,unsigned uDatacenter)
5695
5696
5697void htmlContainerNotes(unsigned uContainer)
5698{
5699        MYSQL_RES *res;
5700        MYSQL_ROW field;
5701
5702        sprintf(gcQuery,"SELECT uProperty,cValue FROM tProperty WHERE uKey=%u AND uType=3"
5703                                " AND cName='Notes' ORDER BY uCreatedDate",uContainer);
5704        mysql_query(&gMysql,gcQuery);
5705        if(mysql_errno(&gMysql))
5706                htmlPlainTextError(mysql_error(&gMysql));
5707        res=mysql_store_result(&gMysql);
5708        if((field=mysql_fetch_row(res)))
5709                printf("<br><a class=darkLink href=unxsVZ.cgi?"
5710                                "gcFunction=tProperty&uProperty=%s&cReturn=tContainer_%u>"
5711                                "Notes</a>:%s\n",field[0],uContainer,field[1]);
5712
5713        mysql_free_result(res);
5714
5715}//void htmlContainerNotes(unsigned uContainer)
5716
5717
5718void htmlContainerMount(unsigned uContainer)
5719{
5720        MYSQL_RES *res;
5721        MYSQL_ROW field;
5722
5723        sprintf(gcQuery,"SELECT uProperty,cValue FROM tProperty WHERE uKey=%u AND uType=3"
5724                                " AND cName LIKE 'cVEID.mount' ORDER BY uCreatedDate",uContainer);
5725        mysql_query(&gMysql,gcQuery);
5726        if(mysql_errno(&gMysql))
5727                htmlPlainTextError(mysql_error(&gMysql));
5728        res=mysql_store_result(&gMysql);
5729        if((field=mysql_fetch_row(res)))
5730                printf("<br><a class=darkLink href=unxsVZ.cgi?"
5731                                "gcFunction=tProperty&uProperty=%s&cReturn=tContainer_%u>"
5732                                "Mount template</a>:%s\n",field[0],uContainer,field[1]);
5733
5734        mysql_free_result(res);
5735
5736}//void htmlContainerMount(unsigned uContainer)
5737
5738
5739void htmlGroups(unsigned uNode, unsigned uContainer)
5740{
5741        MYSQL_RES *res;
5742        MYSQL_ROW field;
5743
5744        if(uNode)
5745        sprintf(gcQuery,"SELECT tGroup.uGroup,tGroup.cLabel FROM tGroupGlue,tGroup WHERE tGroupGlue.uNode=%u"
5746                                " AND tGroupGlue.uGroup=tGroup.uGroup",uNode);
5747        else
5748        sprintf(gcQuery,"SELECT tGroup.uGroup,tGroup.cLabel FROM tGroupGlue,tGroup WHERE tGroupGlue.uContainer=%u"
5749                                " AND tGroupGlue.uGroup=tGroup.uGroup",uContainer);
5750        mysql_query(&gMysql,gcQuery);
5751        if(mysql_errno(&gMysql))
5752                htmlPlainTextError(mysql_error(&gMysql));
5753        res=mysql_store_result(&gMysql);
5754        while((field=mysql_fetch_row(res)))
5755        {
5756                if(uNode)
5757                        printf("<br>Node");
5758                else
5759                        printf("<br>Container");
5760                printf(" is member of the <a class=darkLink");
5761                printf(" href=unxsVZ.cgi?gcFunction=tGroup&uGroup=%s>%s</a> group</a>\n",
5762                                        field[0],field[1]);
5763        }
5764        mysql_free_result(res);
5765
5766}//void htmlGroups(...)
5767
5768
5769unsigned MigrateContainerJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer, unsigned uTargetNode,
5770                        unsigned uOwner, unsigned uLoginClient, unsigned uIPv4,unsigned uPrevStatus)
5771{
5772        unsigned uCount=0;
5773
5774        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='MigrateContainerJob(%u-->%u)',cJobName='MigrateContainer'"
5775                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5776                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5777                        ",uJobStatus=1"
5778                        ",cJobData='uTargetNode=%u;\nuIPv4=%u;\nuPrevStatus=%u;\n'"
5779                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5780                                uContainer,uTargetNode,
5781                                uDatacenter,uNode,uContainer,
5782                                uTargetNode,
5783                                uIPv4,
5784                                uPrevStatus,
5785                                uOwner,uLoginClient);
5786        mysql_query(&gMysql,gcQuery);
5787        if(mysql_errno(&gMysql))
5788                htmlPlainTextError(mysql_error(&gMysql));
5789        uCount=mysql_insert_id(&gMysql);
5790        unxsVZLog(uContainer,"tContainer","Migrate");
5791        return(uCount);
5792
5793}//unsigned MigrateContainerJob(...)
5794
5795
5796void htmlHealth(unsigned uContainer,unsigned uType)
5797{
5798        MYSQL_RES *mysqlRes;
5799        MYSQL_ROW mysqlField;
5800
5801        long unsigned luTotalFailcnt=0;
5802        long unsigned luTotalUsage=0,luTotalSoftLimit=0;
5803        float fRatio;
5804        char *cTable={"tContainer"};
5805
5806        if(uType==3)
5807                printf("<p><u>Container Health</u>");
5808        else if(uType==2)
5809                printf("<p><u>Node and Container(s) Health</u>");
5810        else if(uType==1)
5811                printf("<p><u>Datacenter Health</u>");
5812        printf("<br>");
5813
5814        if(uType==2)
5815        sprintf(gcQuery,"SELECT COUNT(uProperty) FROM tProperty WHERE cName LIKE '%%.luFailcnt'"
5816                                " AND (uKey IN (SELECT uContainer FROM tContainer WHERE uNode=%u)"
5817                                " OR uKey=%u)"
5818                                ,uContainer,uContainer);
5819        else
5820        sprintf(gcQuery,"SELECT COUNT(uProperty) FROM tProperty WHERE cName LIKE '%%.luFailcnt'"
5821                                " AND uKey=%u AND uType=%u",uContainer,uType);
5822        macro_mySQLQueryExitText
5823        if((mysqlField=mysql_fetch_row(mysqlRes)))
5824        {
5825                sscanf(mysqlField[0],"%lu",&luTotalFailcnt);
5826        }
5827        mysql_free_result(mysqlRes);
5828
5829        if(uType==2)
5830        sprintf(gcQuery,"SELECT cName,cValue,uProperty,uKey FROM tProperty,tType WHERE"
5831                                " tProperty.uType=tType.uType AND"
5832                                " cName LIKE '%%.luFail%%' AND cValue!='0'"
5833                                " AND (uKey IN (SELECT uContainer FROM tContainer WHERE uNode=%u)"
5834                                " OR uKey=%u)"
5835                                ,uContainer,uContainer);
5836        else
5837        sprintf(gcQuery,"SELECT cName,cValue,uProperty,uKey FROM tProperty,tType WHERE"
5838                                " tProperty.uType=tType.uType AND"
5839                                " cName LIKE '%%.luFail%%' AND cValue!='0'"
5840                                " AND uKey=%u AND tProperty.uType=%u",uContainer,uType);
5841        macro_mySQLQueryExitText
5842        while((mysqlField=mysql_fetch_row(mysqlRes)))
5843        {
5844                if(strstr(mysqlField[4],"Node")) cTable="tNode";
5845                printf("<a class=darkLink href=unxsVZ.cgi?gcFunction=tProperty&uProperty=%s&cReturn=%s_%s>%s=%s"
5846                                "</a><br>\n",mysqlField[2],cTable,mysqlField[3],mysqlField[0],mysqlField[1]);
5847        }
5848        mysql_free_result(mysqlRes);
5849
5850
5851        if(uType==2)
5852        sprintf(gcQuery,"SELECT SUM(CONVERT(cValue,UNSIGNED)) FROM tProperty WHERE"
5853                                " cName='1k-blocks.luUsage'"
5854                                " AND uType=3"
5855                                " AND uKey IN (SELECT uContainer FROM tContainer WHERE uNode=%u)"
5856                                        ,uContainer);
5857        else if(uType==3)
5858        sprintf(gcQuery,"SELECT SUM(CONVERT(cValue,UNSIGNED)) FROM tProperty WHERE"
5859                                " cName='1k-blocks.luUsage'"
5860                                " AND uKey=%u AND uType=%u",uContainer,uType);
5861        else if(1)
5862                return;
5863        macro_mySQLQueryExitText
5864        if((mysqlField=mysql_fetch_row(mysqlRes)))
5865        {
5866                if(mysqlField[0]==NULL) return;
5867
5868                if(mysqlField[0]==0 || sscanf(mysqlField[0],"%lu",&luTotalUsage)!=1)
5869                        return;
5870        }
5871        mysql_free_result(mysqlRes);
5872
5873        if(uType==2)
5874        sprintf(gcQuery,"SELECT SUM(CONVERT(cValue,UNSIGNED)) FROM tProperty WHERE"
5875                                " cName='1k-blocks.luSoftlimit'"
5876                                " AND uType=3"
5877                                " AND uKey IN (SELECT uContainer FROM tContainer WHERE uNode=%u)"
5878                                        ,uContainer);
5879        else if(uType==3)
5880        sprintf(gcQuery,"SELECT SUM(CONVERT(cValue,UNSIGNED)) FROM tProperty WHERE"
5881                                " cName='1k-blocks.luSoftlimit'"
5882                                " AND uKey=%u AND uType=%u",uContainer,uType);
5883        else if(1)
5884                return;
5885
5886        macro_mySQLQueryExitText
5887        if((mysqlField=mysql_fetch_row(mysqlRes)))
5888        {
5889                if(mysqlField[0]==NULL) return;
5890
5891                if(sscanf(mysqlField[0],"%lu",&luTotalSoftLimit)==0)
5892                        return;
5893        }
5894        mysql_free_result(mysqlRes);
5895        if(luTotalSoftLimit==0) luTotalSoftLimit=1;
5896        fRatio= ((float) luTotalUsage/ (float) luTotalSoftLimit) * 100.00 ;
5897
5898        char *cColor;
5899        cColor=cRatioColor(&fRatio);
5900
5901        printf("Container usage ratio %2.2f%%:"
5902                " <font color=%s>%lu/%lu</font><br>\n",
5903                fRatio,cColor,luTotalUsage,luTotalSoftLimit);
5904
5905}//void htmlHealth(...)
5906
5907
5908unsigned TemplateContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uStatus,unsigned uOwner,char *cConfigLabel)
5909{
5910        unsigned uCount=0;
5911
5912        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='TemplateContainerJob(%u)',cJobName='TemplateContainer'"
5913                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5914                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5915                        ",uJobStatus=1"
5916                        ",cJobData='tConfig.Label=%.31s;\n"
5917                        "uPrevStatus=%u;\n'"
5918                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5919                                uContainer,
5920                                uDatacenter,uNode,uContainer,
5921                                cConfigLabel,
5922                                uStatus,
5923                                uOwner,guLoginClient);
5924        mysql_query(&gMysql,gcQuery);
5925        if(mysql_errno(&gMysql))
5926                htmlPlainTextError(mysql_error(&gMysql));
5927        uCount=mysql_insert_id(&gMysql);
5928        unxsVZLog(uContainer,"tContainer","Template");
5929        return(uCount);
5930
5931}//unsigned TemplateContainerJob()
5932
5933
5934unsigned HostnameContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,char *cPrevHostname,unsigned uOwner,unsigned uLoginClient)
5935{
5936        unsigned uCount=0;
5937
5938        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='ChangeHostnameContainer(%u)',cJobName='ChangeHostnameContainer'"
5939                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5940                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5941                        ",uJobStatus=1"
5942                        ",cJobData='cPrevHostname=%s;'"
5943                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5944                                uContainer,
5945                                uDatacenter,uNode,uContainer,
5946                                cPrevHostname,
5947                                uOwner,uLoginClient);
5948        mysql_query(&gMysql,gcQuery);
5949        if(mysql_errno(&gMysql))
5950                htmlPlainTextError(mysql_error(&gMysql));
5951        uCount=mysql_insert_id(&gMysql);
5952        unxsVZLog(uContainer,"tContainer","Hostname");
5953        return(uCount);
5954
5955}//unsigned HostnameContainerJob()
5956
5957
5958unsigned IPContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,
5959                        unsigned uOwner,unsigned uLoginClient,char const *cIPOld)
5960{
5961        unsigned uCount=0;
5962
5963        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='ChangeIPContainer(%u)',cJobName='ChangeIPContainer'"
5964                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5965                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5966                        ",uJobStatus=1"
5967                        ",cJobData='cIPOld=%.31s;'"
5968                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5969                                uContainer,
5970                                uDatacenter,uNode,uContainer,cIPOld,
5971                                uOwner,uLoginClient);
5972        mysql_query(&gMysql,gcQuery);
5973        if(mysql_errno(&gMysql))
5974                htmlPlainTextError(mysql_error(&gMysql));
5975        uCount=mysql_insert_id(&gMysql);
5976        unxsVZLog(uContainer,"tContainer","ChangeIP");
5977        return(uCount);
5978
5979}//unsigned IPContainerJob()
5980
5981
5982unsigned IPSameNodeContainerJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer1,unsigned uContainer2,
5983                        unsigned uOwner,unsigned uLoginClient,char const *cIPOld1,char const *cIPOld2)
5984{
5985        unsigned uCount=0;
5986
5987        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='SwapIPContainer(%u)',cJobName='SwapIPContainer'"
5988                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
5989                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
5990                        ",uJobStatus=1"
5991                        ",cJobData='uContainer2=%u;\ncIPOld1=%.31s;\ncIPOld2=%.31s;\n'"
5992                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
5993                                uContainer,
5994                                uDatacenter,uNode,uContainer1,uContainer2,cIPOld1,cIPOld2,
5995                                uOwner,uLoginClient);
5996        mysql_query(&gMysql,gcQuery);
5997        if(mysql_errno(&gMysql))
5998                htmlPlainTextError(mysql_error(&gMysql));
5999        uCount=mysql_insert_id(&gMysql);
6000        unxsVZLog(uContainer,"tContainer","SwapIPContainer");
6001        return(uCount);
6002
6003}//unsigned IPSameNodeContainerJob()
6004
6005
6006unsigned ActionScriptsJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer)
6007{
6008        unsigned uCount=0;
6009        char cTemplateName[256]={""};
6010
6011        GetContainerProp(uContainer,"cVEID.mount",cTemplateName);
6012        if(!cTemplateName[0]) return(0);
6013        GetContainerProp(uContainer,"cVEID.umount",cTemplateName);
6014        if(!cTemplateName[0]) return(0);
6015
6016        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='ActionScripts(%u)',cJobName='ActionScripts'"
6017                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
6018                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
6019                        ",uJobStatus=1"
6020                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6021                                uContainer,
6022                                uDatacenter,uNode,uContainer,
6023                                uOwner,guLoginClient);
6024        mysql_query(&gMysql,gcQuery);
6025        if(mysql_errno(&gMysql))
6026                htmlPlainTextError(mysql_error(&gMysql));
6027        uCount=mysql_insert_id(&gMysql);
6028        unxsVZLog(uContainer,"tContainer","MountFiles");
6029        return(uCount);
6030
6031}//unsigned ActionScriptsJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer)
6032
6033
6034unsigned CloneContainerJob(unsigned uDatacenter, unsigned uNode, unsigned uContainer,
6035                                unsigned uTargetNode, unsigned uNewVeid, unsigned uPrevStatus,
6036                                unsigned uOwner,unsigned uCreatedBy,unsigned uCloneStop)
6037{
6038        unsigned uCount=0;
6039
6040        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='CloneContainer(%u)',cJobName='CloneContainer'"
6041                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
6042                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
6043                        ",uJobStatus=1"
6044                        ",cJobData='"
6045                        "uTargetNode=%u;\n"
6046                        "uNewVeid=%u;\n"
6047                        "uCloneStop=%u;\n"
6048                        "uPrevStatus=%u;\n'"
6049                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6050                                uContainer,
6051                                uDatacenter,uNode,uContainer,
6052                                uTargetNode,
6053                                uNewVeid,
6054                                uCloneStop,
6055                                uPrevStatus,
6056                                uOwner,uCreatedBy);
6057        mysql_query(&gMysql,gcQuery);
6058        if(mysql_errno(&gMysql))
6059                htmlPlainTextError(mysql_error(&gMysql));
6060        uCount=mysql_insert_id(&gMysql);
6061        unxsVZLog(uContainer,"tContainer","CloneContainer");
6062        return(uCount);
6063
6064}//unsigned CloneContainerJob()
6065
6066
6067
6068
6069char *cRatioColor(float *fRatio)
6070{
6071        char *cColor={"black"};
6072
6073        if(*fRatio<40.00)
6074                return(cColor);
6075        else if(*fRatio<70.00)
6076                cColor="#DAA520";
6077        else if(*fRatio<80.00)
6078                cColor="fuchsia";
6079        else if(*fRatio>=80.00)
6080                cColor="red";
6081
6082        return(cColor);
6083
6084}//char *cRatioColor(float *fRatio)
6085
6086
6087void htmlMountTemplateSelect(unsigned uSelector)
6088{
6089        register int i,n;
6090        MYSQL_RES *mysqlRes;         
6091        MYSQL_ROW mysqlField;
6092
6093        sprintf(gcQuery,"SELECT uTemplate,cLabel FROM tTemplate WHERE cLabel LIKE '%%.mount' ORDER BY cLabel");
6094        MYSQL_RUN_STORE_TEXT_RET_VOID(mysqlRes);
6095        i=mysql_num_rows(mysqlRes);
6096        if(i>0)
6097        {
6098                printf("<select name=MountTemplateSelect>\n");
6099                //Default no selection
6100                printf("<option title='No selection'>---</option>\n");
6101                for(n=0;n<i;n++)
6102                {
6103                        int unsigned field0=0;
6104
6105                        mysqlField=mysql_fetch_row(mysqlRes);
6106                        sscanf(mysqlField[0],"%u",&field0);
6107
6108                        if(uSelector != field0)
6109                             printf("<option>%s</option>\n",mysqlField[1]);
6110                        else
6111                             printf("<option selected>%s</option>\n",mysqlField[1]);
6112                }
6113        }
6114        else
6115        {
6116                printf("<select name=MountTemplateSelect>"
6117                                "<option title='No selection'>---</option></select>\n");
6118        }
6119        printf("</select>\n");
6120
6121}//void htmlMountTemplateSelect(unsigned uSelector)
6122
6123
6124void AddMountProps(unsigned uContainer)
6125{
6126        if(cService1[0])
6127        {
6128                sprintf(gcQuery,"DELETE FROM tProperty WHERE uKey=%u AND uType=3"
6129                                " AND cName='cService1'",uContainer);
6130                mysql_query(&gMysql,gcQuery);
6131                if(mysql_errno(&gMysql))
6132                        htmlPlainTextError(mysql_error(&gMysql));
6133
6134                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6135                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6136                        ",cName='cService1',cValue='%s'",
6137                                uContainer,guCompany,guLoginClient,cService1);
6138                mysql_query(&gMysql,gcQuery);
6139                if(mysql_errno(&gMysql))
6140                        htmlPlainTextError(mysql_error(&gMysql));
6141        }
6142
6143        if(cService2[0])
6144        {
6145                sprintf(gcQuery,"DELETE FROM tProperty WHERE uKey=%u AND uType=3"
6146                                " AND cName='cService2'",uContainer);
6147                mysql_query(&gMysql,gcQuery);
6148                if(mysql_errno(&gMysql))
6149                        htmlPlainTextError(mysql_error(&gMysql));
6150
6151                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6152                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6153                        ",cName='cService2',cValue='%s'",
6154                                uContainer,guCompany,guLoginClient,cService2);
6155                mysql_query(&gMysql,gcQuery);
6156                if(mysql_errno(&gMysql))
6157                        htmlPlainTextError(mysql_error(&gMysql));
6158        }
6159
6160        if(cService3[0])
6161        {
6162                sprintf(gcQuery,"DELETE FROM tProperty WHERE uKey=%u AND uType=3"
6163                                " AND cName='cService3'",uContainer);
6164                mysql_query(&gMysql,gcQuery);
6165                if(mysql_errno(&gMysql))
6166                        htmlPlainTextError(mysql_error(&gMysql));
6167
6168                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6169                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6170                        ",cName='cService3',cValue='%s'",
6171                                uContainer,guCompany,guLoginClient,cService3);
6172                mysql_query(&gMysql,gcQuery);
6173                if(mysql_errno(&gMysql))
6174                        htmlPlainTextError(mysql_error(&gMysql));
6175        }
6176
6177        if(cService4[0])
6178        {
6179                sprintf(gcQuery,"DELETE FROM tProperty WHERE uKey=%u AND uType=3"
6180                                " AND cName='cService4'",uContainer);
6181                mysql_query(&gMysql,gcQuery);
6182                if(mysql_errno(&gMysql))
6183                        htmlPlainTextError(mysql_error(&gMysql));
6184
6185                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6186                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6187                        ",cName='cService4',cValue='%s'",
6188                                uContainer,guCompany,guLoginClient,cService4);
6189                mysql_query(&gMysql,gcQuery);
6190                if(mysql_errno(&gMysql))
6191                        htmlPlainTextError(mysql_error(&gMysql));
6192        }
6193
6194        if(cNetmask[0])
6195        {
6196                sprintf(gcQuery,"DELETE FROM tProperty WHERE uKey=%u AND uType=3"
6197                                " AND cName='cNetmask'",uContainer);
6198                mysql_query(&gMysql,gcQuery);
6199                if(mysql_errno(&gMysql))
6200                        htmlPlainTextError(mysql_error(&gMysql));
6201
6202                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6203                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6204                        ",cName='cNetmask',cValue='%s'",
6205                                uContainer,guCompany,guLoginClient,cNetmask);
6206                mysql_query(&gMysql,gcQuery);
6207                if(mysql_errno(&gMysql))
6208                        htmlPlainTextError(mysql_error(&gMysql));
6209        }
6210
6211        if(cPrivateIPs[0])
6212        {
6213                sprintf(gcQuery,"DELETE FROM tProperty WHERE uKey=%u AND uType=3"
6214                                " AND cName='cPrivateIPs'",uContainer);
6215                mysql_query(&gMysql,gcQuery);
6216                if(mysql_errno(&gMysql))
6217                        htmlPlainTextError(mysql_error(&gMysql));
6218
6219                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6220                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6221                        ",cName='cPrivateIPs',cValue='%s'",
6222                                uContainer,guCompany,guLoginClient,cPrivateIPs);
6223                mysql_query(&gMysql,gcQuery);
6224                if(mysql_errno(&gMysql))
6225                        htmlPlainTextError(mysql_error(&gMysql));
6226        }
6227
6228        if(cuWizIPv4PullDown[0])
6229        {
6230                sprintf(gcQuery,"DELETE FROM tProperty WHERE uKey=%u AND uType=3"
6231                                " AND cName='cNodeIP'",uContainer);
6232                mysql_query(&gMysql,gcQuery);
6233                if(mysql_errno(&gMysql))
6234                        htmlPlainTextError(mysql_error(&gMysql));
6235
6236                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6237                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6238                        ",cName='cNodeIP',cValue='%s'",
6239                                uContainer,guCompany,guLoginClient,cuWizIPv4PullDown);
6240                mysql_query(&gMysql,gcQuery);
6241                if(mysql_errno(&gMysql))
6242                        htmlPlainTextError(mysql_error(&gMysql));
6243
6244                //This needs the corresponding release code on delete/mod and delete container
6245                //ops
6246                sprintf(gcQuery,"UPDATE tIP SET uAvailable=0 WHERE cLabel='%s'",cuWizIPv4PullDown);
6247                mysql_query(&gMysql,gcQuery);
6248                if(mysql_errno(&gMysql))
6249                        htmlPlainTextError(mysql_error(&gMysql));
6250        }
6251
6252        if(cuTemplateDropDown[0])
6253        {
6254                char *cp;
6255
6256                sprintf(gcQuery,"DELETE FROM tProperty WHERE uKey=%u AND uType=3"
6257                                " AND (cName='cVEID.mount' OR cName='cVEID.umount')",uContainer);
6258                mysql_query(&gMysql,gcQuery);
6259                if(mysql_errno(&gMysql))
6260                        htmlPlainTextError(mysql_error(&gMysql));
6261
6262                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6263                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6264                        ",cName='cVEID.mount',cValue='%s'",
6265                                uContainer,guCompany,guLoginClient,cuTemplateDropDown);
6266                mysql_query(&gMysql,gcQuery);
6267                if(mysql_errno(&gMysql))
6268                        htmlPlainTextError(mysql_error(&gMysql));
6269
6270                if((cp=strchr(cuTemplateDropDown,'.')))
6271                        sprintf(cp,".umount");
6272                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6273                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6274                        ",cName='cVEID.umount',cValue='%s'",
6275                                uContainer,guCompany,guLoginClient,cuTemplateDropDown);
6276                mysql_query(&gMysql,gcQuery);
6277                if(mysql_errno(&gMysql))
6278                        htmlPlainTextError(mysql_error(&gMysql));
6279        }
6280
6281
6282}//void AddMountProps(unsigned uContainer)
6283
6284
6285void CopyContainerProps(unsigned uSource, unsigned uTarget)
6286{
6287        if(!uSource || !uTarget) return;
6288
6289        MYSQL_RES *res;
6290        MYSQL_ROW field;
6291
6292        sprintf(gcQuery,"SELECT cName,cValue FROM tProperty WHERE uKey=%u AND uType=3",uSource);
6293        mysql_query(&gMysql,gcQuery);
6294        if(mysql_errno(&gMysql))
6295                htmlPlainTextError(mysql_error(&gMysql));
6296        res=mysql_store_result(&gMysql);
6297        while((field=mysql_fetch_row(res)))
6298        {
6299                sprintf(gcQuery,"INSERT INTO tProperty SET cName='%s',cValue='%s',uKey=%u,uType=3,uOwner=%u,"
6300                                "uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6301                                        field[0],
6302                                        field[1],
6303                                        uTarget,guCompany,guLoginClient);
6304                mysql_query(&gMysql,gcQuery);
6305                if(mysql_errno(&gMysql))
6306                        htmlPlainTextError(mysql_error(&gMysql));
6307        }
6308        mysql_free_result(res);
6309
6310}//void CopyContainerProps(unsigned uSource, unsigned uTarget)
6311
6312
6313//Both these failover jobs must in some sense check each other's status it seems at first blush.
6314unsigned FailoverToJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner,unsigned uLoginClient,unsigned uDebug)
6315{
6316        unsigned uCount=0;
6317
6318        if(!uDatacenter || !uNode || !uContainer) return(0);
6319
6320        //This job should try to stop the uSource container if possible. Or at least
6321        //make sure it's IP is down. There are many failover scenarios it seems at first glance
6322        //we will try to handle all of them.
6323        //Remote datacenter failover seems to involve DNS changes. Since we can't use the VIP
6324        //method that should be available in a correctly configured unxsVZ datacenter.
6325        if(uDebug)
6326                sprintf(gcQuery,"INSERT INTO tJob SET cLabel='FailoverToJob(%u)',cJobName='FailoverToDEBUG'"
6327                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
6328                        ",uJobDate=UNIX_TIMESTAMP(NOW())"
6329                        ",uJobStatus=1"
6330                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6331                                uContainer,
6332                                uDatacenter,uNode,uContainer,
6333                                uOwner,uLoginClient);
6334        else
6335                sprintf(gcQuery,"INSERT INTO tJob SET cLabel='FailoverToJob(%u)',cJobName='FailoverTo'"
6336                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
6337                        ",uJobDate=UNIX_TIMESTAMP(NOW())"
6338                        ",uJobStatus=1"
6339                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6340                                uContainer,
6341                                uDatacenter,uNode,uContainer,
6342                                uOwner,uLoginClient);
6343        mysql_query(&gMysql,gcQuery);
6344        if(mysql_errno(&gMysql))
6345                htmlPlainTextError(mysql_error(&gMysql));
6346        uCount=mysql_insert_id(&gMysql);
6347        return(uCount);
6348
6349}//unsigned FailoverToJob()
6350
6351
6352unsigned FailoverFromJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,
6353                                unsigned uIPv4,char *cLabel,char *cHostname,unsigned uSource,
6354                                unsigned uStatus,unsigned uFailToJob,unsigned uOwner,unsigned uLoginClient,unsigned uDebug)
6355{
6356        unsigned uCount=0;
6357
6358        if(!uDatacenter || !uNode || !uContainer) return(0);
6359
6360        //If the source node is down this job will be stuck
6361        //When node is fixed and boots we must avoid the source continater coming up with same IP
6362        //as the new production container (the FailoverToJob container.)
6363        if(uDebug)
6364                sprintf(gcQuery,"INSERT INTO tJob SET cLabel='FailoverFromJob(%u)',cJobName='FailoverFromDEBUG'"
6365                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
6366                        ",uJobDate=UNIX_TIMESTAMP(NOW())"
6367                        ",uJobStatus=1"
6368                        ",cJobData='uIPv4=%u;\ncLabel=%s;\ncHostname=%s;\nuSource=%u;\nuStatus=%u;\n"
6369                        "uFailToJob=%u;'"
6370                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6371                                uContainer,
6372                                uDatacenter,uNode,uContainer,
6373                                uIPv4,cLabel,cHostname,uSource,uStatus,uFailToJob,
6374                                uOwner,uLoginClient);
6375        else
6376                sprintf(gcQuery,"INSERT INTO tJob SET cLabel='FailoverFromJob(%u)',cJobName='FailoverFrom'"
6377                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
6378                        ",uJobDate=UNIX_TIMESTAMP(NOW())"
6379                        ",uJobStatus=1"
6380                        ",cJobData='uIPv4=%u;\ncLabel=%s;\ncHostname=%s;\nuSource=%u;\nuStatus=%u;\n"
6381                        "uFailToJob=%u;'"
6382                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6383                                uContainer,
6384                                uDatacenter,uNode,uContainer,
6385                                uIPv4,cLabel,cHostname,uSource,uStatus,uFailToJob,
6386                                uOwner,uLoginClient);
6387        mysql_query(&gMysql,gcQuery);
6388        if(mysql_errno(&gMysql))
6389                htmlPlainTextError(mysql_error(&gMysql));
6390        uCount=mysql_insert_id(&gMysql);
6391        return(uCount);
6392
6393}//unsigned FailoverFromJob()
6394
6395
6396void htmlCloneInfo(unsigned uContainer)
6397{
6398        MYSQL_RES *res;
6399        MYSQL_ROW field;
6400
6401        sprintf(gcQuery,"SELECT cLabel,uContainer FROM tContainer WHERE uSource=%u",uContainer);
6402        mysql_query(&gMysql,gcQuery);
6403        if(mysql_errno(&gMysql))
6404                htmlPlainTextError(mysql_error(&gMysql));
6405        res=mysql_store_result(&gMysql);
6406        if(mysql_num_rows(res)>0)
6407                printf("<br>Clone(s) of current container:\n");
6408
6409        while((field=mysql_fetch_row(res)))
6410                printf("<br> &nbsp; <a class=darkLink href=unxsVZ.cgi?"
6411                                "gcFunction=tContainer&uContainer=%s>"
6412                                "%s</a>\n",field[1],field[0]);
6413
6414        mysql_free_result(res);
6415
6416}//void htmlCloneInfo(unsigned uContainer)
6417
6418
6419void GetContainerProps(unsigned uContainer,struct structContainer *sContainer)
6420{
6421        MYSQL_RES *res;
6422        MYSQL_ROW field;
6423
6424        if(uContainer==0)
6425                return;
6426
6427        sprintf(gcQuery,"SELECT cLabel,cHostname,uVeth,uSource,uIPv4,uOSTemplate,uConfig,uNameserver,"
6428                        "uSearchdomain,uDatacenter,uNode,uStatus,uOwner,uCreatedBy,uCreatedDate,uModBy,"
6429                        "uModDate FROM tContainer WHERE uContainer=%u",uContainer);
6430        mysql_query(&gMysql,gcQuery);
6431        if(mysql_errno(&gMysql))
6432                htmlPlainTextError(mysql_error(&gMysql));
6433        res=mysql_store_result(&gMysql);
6434        if((field=mysql_fetch_row(res)))
6435        {
6436                sprintf(sContainer->cLabel,"%.31s",field[0]);
6437                sprintf(sContainer->cHostname,"%.63s",field[1]);
6438                sscanf(field[2],"%u",&sContainer->uVeth);
6439                sscanf(field[3],"%u",&sContainer->uSource);
6440                sscanf(field[4],"%u",&sContainer->uIPv4);
6441                sscanf(field[5],"%u",&sContainer->uOSTemplate);
6442                sscanf(field[6],"%u",&sContainer->uConfig);
6443                sscanf(field[7],"%u",&sContainer->uNameserver);
6444                sscanf(field[8],"%u",&sContainer->uSearchdomain);
6445                sscanf(field[9],"%u",&sContainer->uDatacenter);
6446                sscanf(field[10],"%u",&sContainer->uNode);
6447                sscanf(field[11],"%u",&sContainer->uStatus);
6448                sscanf(field[12],"%u",&sContainer->uOwner);
6449                sscanf(field[13],"%u",&sContainer->uCreatedBy);
6450                sscanf(field[14],"%lu",&sContainer->uCreatedDate);
6451                sscanf(field[15],"%u",&sContainer->uModBy);
6452                sscanf(field[16],"%lu",&sContainer->uModDate);
6453        }
6454        mysql_free_result(res);
6455
6456}//void GetContainerProps()
6457
6458
6459void InitContainerProps(struct structContainer *sContainer)
6460{
6461        sContainer->cLabel[0]=0;
6462        sContainer->cHostname[0]=0;
6463        sContainer->uVeth=0;
6464        sContainer->uSource=0;
6465        sContainer->uIPv4=0;
6466        sContainer->uOSTemplate=0;
6467        sContainer->uConfig=0;
6468        sContainer->uNameserver=0;
6469        sContainer->uSearchdomain=0;
6470        sContainer->uDatacenter=0;
6471        sContainer->uNode=0;
6472        sContainer->uStatus=0;
6473        sContainer->uOwner=0;
6474        sContainer->uCreatedBy=0;
6475        sContainer->uCreatedDate=0;
6476        sContainer->uModBy=0;
6477        sContainer->uModDate=0;
6478
6479}//void InitContainerProps(struct structContainer *sContainer)
6480
6481
6482//Lowest uGroup. Which we define here as the primary group
6483//of a node or container. Since a container or node can belong to different groups at the same time.
6484unsigned uGetGroup(unsigned uNode, unsigned uContainer)
6485{
6486        MYSQL_RES *res;
6487        MYSQL_ROW field;
6488        unsigned uGroup=0;
6489
6490        if(uNode)
6491                sprintf(gcQuery,"SELECT MIN(tGroup.uGroup) FROM tGroupGlue,tGroup WHERE tGroupGlue.uNode=%u"
6492                                " AND tGroupGlue.uGroup=tGroup.uGroup AND tGroup.uGroupType=1",uNode);//1 is container type used here temporarily
6493        else
6494                sprintf(gcQuery,"SELECT MIN(tGroup.uGroup) FROM tGroupGlue,tGroup WHERE tGroupGlue.uContainer=%u"
6495                                " AND tGroupGlue.uGroup=tGroup.uGroup AND tGroup.uGroupType=1",uContainer);//1 is container type
6496        mysql_query(&gMysql,gcQuery);
6497        if(mysql_errno(&gMysql))
6498                htmlPlainTextError(mysql_error(&gMysql));
6499        res=mysql_store_result(&gMysql);
6500        if((field=mysql_fetch_row(res)))
6501        {
6502                if(field[0]!=NULL)
6503                        sscanf(field[0],"%u",&uGroup);
6504        }
6505        mysql_free_result(res);
6506
6507        return(uGroup);
6508
6509}//unsigned uGetGroup(unsigned uNode, unsigned uContainer)
6510
6511
6512//Pull job for unxsBind
6513//Sample cJobData
6514/*
6515cName=delme.zone.net.;
6516cuTTL=3600;
6517cRRType=A;
6518cParam1=174.121.136.102;
6519cNSSet=ns1-2.yourdomain.com;
6520cView=external;
6521*/
6522unsigned unxsBindARecordJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,const char *cJobData,
6523        unsigned uOwner,unsigned uCreatedBy)
6524{
6525        unsigned uCount=0;
6526
6527        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='unxsBindARecordJob(%u)',cJobName='unxsVZContainerARR'"
6528                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
6529                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
6530                        ",uJobStatus=%u"
6531                        ",cJobData='%s'"
6532                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6533                                uContainer,
6534                                uDatacenter,uNode,uContainer,
6535                                uREMOTEWAITING,
6536                                cJobData,
6537                                uOwner,uCreatedBy);
6538        mysql_query(&gMysql,gcQuery);
6539        if(mysql_errno(&gMysql))
6540                htmlPlainTextError(mysql_error(&gMysql));
6541        uCount=mysql_insert_id(&gMysql);
6542        unxsVZLog(uContainer,"tContainer","unxsBindARecordJob");
6543        return(uCount);
6544
6545}//unsigned unxsBindARecordJob(...)
6546
6547
6548void ChangeGroup(unsigned uContainer, unsigned uGroup)
6549{
6550        MYSQL_RES *res;
6551        MYSQL_ROW field;
6552
6553        if(uGroup)
6554        {
6555                unsigned uPrimaryGroup=0;
6556
6557                //Get the PK of the primary group of this container.
6558                sprintf(gcQuery,"SELECT tGroupGlue.uGroupGlue,tGroupGlue.uGroup FROM tGroupGlue,tGroup WHERE"
6559                        " tGroupGlue.uGroup=tGroup.uGroup AND tGroupGlue.uContainer=%u"
6560                        " AND tGroup.uGroupType=1 ORDER BY tGroupGlue.uGroup LIMIT 1",uContainer);//1 is container type
6561                mysql_query(&gMysql,gcQuery);
6562                if(mysql_errno(&gMysql))
6563                        htmlPlainTextError(mysql_error(&gMysql));
6564                res=mysql_store_result(&gMysql);
6565                if(mysql_num_rows(res)==0)
6566                {
6567                        //If none insert
6568                        sprintf(gcQuery,"INSERT INTO tGroupGlue SET uContainer=%u,uGroup=%u",
6569                                        uContainer,uGroup);
6570                        mysql_query(&gMysql,gcQuery);
6571                        if(mysql_errno(&gMysql))
6572                                htmlPlainTextError(mysql_error(&gMysql));
6573                }
6574                else if ((field=mysql_fetch_row(res)))
6575                {
6576                        //Conditionally UPDATE save db work.
6577                        sscanf(field[1],"%u",&uPrimaryGroup);
6578                        if(uPrimaryGroup!=uGroup)
6579                        {
6580                                sprintf(gcQuery,"UPDATE tGroupGlue SET uGroup=%u WHERE"
6581                                                " uGroupGlue=%s",uGroup,field[0]);
6582                                mysql_query(&gMysql,gcQuery);
6583                                if(mysql_errno(&gMysql))
6584                                        htmlPlainTextError(mysql_error(&gMysql));
6585                        }
6586                }
6587                mysql_free_result(res);
6588        }
6589}//void ChangeGroup(unsigned uContainer, unsigned uGroup)
6590
6591
6592unsigned CommonCloneContainer(
6593                unsigned uContainer,
6594                unsigned uOSTemplate,
6595                unsigned uConfig,
6596                unsigned uNameserver,
6597                unsigned uSearchdomain,
6598                unsigned uDatacenter,
6599                unsigned uTargetDatacenter,
6600                unsigned uOwner,
6601                const char *cLabel,
6602                unsigned uNode,
6603                unsigned uStatus,
6604                const char *cHostname,
6605                const char *cClassC,
6606                unsigned uWizIPv4,
6607                char *cWizLabel,
6608                char *cWizHostname,
6609                unsigned uTargetNode,
6610                unsigned uSyncPeriod,
6611                unsigned uLoginClient,
6612                unsigned uCloneStop,
6613                unsigned uMode)
6614{       
6615        MYSQL_RES *res;
6616        unsigned uNewVeid=0;
6617        unsigned uWizLabelSuffix=0;
6618        unsigned uWizLabelLoop=1;
6619
6620        //Get first available <cLabel>-clone<uNum>
6621        while(uWizLabelLoop)
6622        {
6623                uWizLabelSuffix++;
6624                sprintf(cWizLabel,"%.25s-clone%u",cLabel,uWizLabelSuffix);
6625                sprintf(gcQuery,"SELECT uContainer FROM tContainer WHERE cLabel='%s'",cWizLabel);
6626                mysql_query(&gMysql,gcQuery);
6627                if(mysql_errno(&gMysql))
6628                        htmlPlainTextError(mysql_error(&gMysql));
6629                res=mysql_store_result(&gMysql);
6630                uWizLabelLoop=mysql_num_rows(res);
6631                mysql_free_result(res);
6632        }
6633        //New clone naming convention
6634        char *cp=NULL;
6635        if((cp=strchr(cHostname,'.')))
6636        {
6637                *cp=0;
6638                sprintf(cWizHostname,"%.32s-clone%u.%.60s",cHostname,uWizLabelSuffix,cp+1);
6639                *cp='.';
6640        }
6641        else
6642        {
6643                sprintf(cWizHostname,"%.93s.clone%u",cHostname,uWizLabelSuffix);
6644        }
6645
6646        sprintf(gcQuery,"INSERT INTO tContainer SET cLabel='%s',"
6647                                "cHostname='%s',"
6648                                "uIPv4=%u,"
6649                                "uOSTemplate=%u,"
6650                                "uConfig=%u,"
6651                                "uNameserver=%u,"
6652                                "uSearchdomain=%u,"
6653                                "uDatacenter=%u,"
6654                                "uNode=%u,"
6655                                "uStatus=%u,"
6656                                "uOwner=%u,"
6657                                "uCreatedBy=%u,"
6658                                "uSource=%u,"
6659                                "uCreatedDate=UNIX_TIMESTAMP(NOW())",
6660                                cWizLabel,
6661                                cWizHostname,
6662                                uWizIPv4,
6663                                uOSTemplate,
6664                                uConfig,
6665                                uNameserver,
6666                                uSearchdomain,
6667                                uTargetDatacenter,
6668                                uTargetNode,
6669                                uAWAITCLONE,
6670                                uOwner,
6671                                uLoginClient,
6672                                uContainer);
6673        mysql_query(&gMysql,gcQuery);
6674        if(mysql_errno(&gMysql))
6675                htmlPlainTextError(mysql_error(&gMysql));
6676        uNewVeid=mysql_insert_id(&gMysql);
6677
6678        if(!uNewVeid)
6679                return(0);
6680
6681        if(CloneContainerJob(uDatacenter,uNode,uContainer,uTargetNode,uNewVeid,uStatus,uOwner,uLoginClient,uCloneStop))
6682        {
6683                //TODO something is wrong here.
6684                //If we specify a class C mask then we check it here. Why?
6685                if(cClassC[0])
6686                {
6687                        if(guCompany==1)
6688                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
6689                                " WHERE uIP=%u AND uAvailable=1 AND cLabel LIKE '%s%%' AND uDatacenter=%u",
6690                                        uWizIPv4,cClassC,uTargetDatacenter);
6691                        else
6692                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
6693                                        " WHERE uIP=%u AND uAvailable=1 AND uOwner=%u AND cLabel LIKE '%s%%'"
6694                                        " AND uDatacenter=%u",
6695                                                uWizIPv4,uOwner,cClassC,uTargetDatacenter);
6696                }
6697                //Here no such class c check
6698                else
6699                {
6700                        if(guCompany==1)
6701                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
6702                                " WHERE uIP=%u AND uAvailable=1 AND uDatacenter=%u",
6703                                        uWizIPv4,uTargetDatacenter);
6704                        else
6705                                sprintf(gcQuery,"UPDATE tIP SET uAvailable=0"
6706                                        " WHERE uIP=%u AND uAvailable=1 AND uOwner=%u AND uDatacenter=%u",
6707                                                uWizIPv4,uOwner,uTargetDatacenter);
6708                }
6709                mysql_query(&gMysql,gcQuery);
6710                if(mysql_errno(&gMysql))
6711                                htmlPlainTextError(mysql_error(&gMysql));
6712                if(mysql_affected_rows(&gMysql)!=1)
6713                {
6714                        sprintf(gcQuery,"DELETE FROM tContainer WHERE uContainer=%u",uNewVeid);
6715                        mysql_query(&gMysql,gcQuery);
6716                        if(mysql_errno(&gMysql))
6717                                htmlPlainTextError(mysql_error(&gMysql));
6718
6719                        sprintf(gcQuery,"DELETE FROM tJob WHERE cLabel='CloneContainer(%u)'"
6720                                        ,uContainer);
6721                        mysql_query(&gMysql,gcQuery);
6722                        if(mysql_errno(&gMysql))
6723                                htmlPlainTextError(mysql_error(&gMysql));
6724
6725                        if(uMode==0)
6726                                tContainer("<blink>Error:</blink> No jobs created. Clone IP gone!");
6727                        else if(uMode==1)
6728                                tNode("<blink>Error:</blink> No jobs created. Clone IP gone!");
6729                        else if(uMode==7)
6730                                printf("CommonCloneContainer() No jobs created. Clone IP gone!\n");
6731                }
6732                CopyContainerProps(uContainer,uNewVeid);
6733                //Update NAME
6734                sprintf(gcQuery,"DELETE FROM tProperty WHERE"
6735                                " cName='Name' AND uKey=%u AND uType=3",uNewVeid);
6736                mysql_query(&gMysql,gcQuery);
6737                if(mysql_errno(&gMysql))
6738                        htmlPlainTextError(mysql_error(&gMysql));
6739                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6740                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6741                                ",cName='Name',cValue='%s'",
6742                                        uNewVeid,uOwner,uLoginClient,cWizLabel);
6743                mysql_query(&gMysql,gcQuery);
6744                if(mysql_errno(&gMysql))
6745                        htmlPlainTextError(mysql_error(&gMysql));
6746                //Default no sync period set
6747                sprintf(gcQuery,"DELETE FROM tProperty WHERE"
6748                                " cName='cuSyncPeriod' AND uKey=%u AND uType=3",uNewVeid);
6749                mysql_query(&gMysql,gcQuery);
6750                if(mysql_errno(&gMysql))
6751                        htmlPlainTextError(mysql_error(&gMysql));
6752                sprintf(gcQuery,"INSERT INTO tProperty SET uKey=%u,uType=3"
6753                                ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())"
6754                                ",cName='cuSyncPeriod',cValue='%u'",
6755                                        uNewVeid,uOwner,uLoginClient,uSyncPeriod);
6756                mysql_query(&gMysql,gcQuery);
6757                if(mysql_errno(&gMysql))
6758                        htmlPlainTextError(mysql_error(&gMysql));
6759                uModBy=uLoginClient;
6760                uStatus=uAWAITCLONE;
6761                SetContainerStatus(uContainer,uAWAITCLONE);
6762        }
6763        else
6764        {
6765                sprintf(gcQuery,"DELETE FROM tContainer WHERE uContainer=%u",uNewVeid);
6766                mysql_query(&gMysql,gcQuery);
6767                if(mysql_errno(&gMysql))
6768                                htmlPlainTextError(mysql_error(&gMysql));
6769                if(uMode==0)
6770                        tContainer("<blink>Error:</blink> No jobs created!");
6771                else if(uMode==1)
6772                        tNode("<blink>Error:</blink> No jobs created!");
6773                else if(uMode==7)
6774                        printf("CommonCloneContainer() No jobs created!\n");
6775        }
6776
6777        return(uNewVeid);
6778
6779}//unsigned CommonCloneContainer()
6780
6781
6782void CreateDNSJob(unsigned uIPv4,unsigned uOwner,char const *cOptionalIPv4,char const *cHostname,unsigned uDatacenter,unsigned uCreatedBy)
6783{
6784        MYSQL_RES *res;
6785        MYSQL_ROW field;
6786        char cJobData[512];
6787        char cIPv4[32]={""};
6788        //char cOwner[32]={"Root"};
6789        //Get all these from tConfiguration once.
6790        static char cView[256]={"external"};
6791        static char cZone[256]={""};
6792        //static char cuTTL[256]={"0"};//for zone default we use 0
6793        //static char cNSSet[256]={""};//not supported yet
6794        static unsigned uOnlyOnce=1;
6795
6796        //Sanity checks
6797        if(!cHostname[0])
6798                return;
6799        if(!uIPv4 && !cOptionalIPv4[0])
6800                return;
6801
6802        //If called in loop be efficient.
6803        if(uOnlyOnce)
6804        {
6805                GetConfiguration("cunxsBindARecordJobZone",cZone,uDatacenter,0,0,0);
6806                GetConfiguration("cunxsBindARecordJobView",cView,uDatacenter,0,0,0);
6807                //GetConfiguration("cunxsBindARecordJobTTL",cuTTL,uDatacenter,0,0,0);//not supported yet
6808                uOnlyOnce=0;
6809        }
6810
6811        //Sanity checks
6812        if(!cZone[0])
6813                return;
6814
6815        if(cOptionalIPv4!=NULL && cOptionalIPv4[0])
6816        {
6817                sprintf(cIPv4,"%.31s",cOptionalIPv4);
6818        }
6819        else if(uIPv4)
6820        {
6821                sprintf(gcQuery,"SELECT cLabel FROM tIP WHERE uIP=%u",uIPv4);
6822                mysql_query(&gMysql,gcQuery);
6823                if(mysql_errno(&gMysql))
6824                        htmlPlainTextError(mysql_error(&gMysql));
6825                res=mysql_store_result(&gMysql);
6826                if((field=mysql_fetch_row(res)))
6827                        sprintf(cIPv4,"%.31s",field[0]);
6828        }
6829
6830        //Sanity checks
6831        if(!cIPv4[0])
6832                return;
6833
6834/*
6835        //not supported yet
6836        if(uOwner)
6837        {
6838                sprintf(gcQuery,"SELECT cLabel FROM tClient WHERE uClient=%u",uOwner);
6839                mysql_query(&gMysql,gcQuery);
6840                if(mysql_errno(&gMysql))
6841                        htmlPlainTextError(mysql_error(&gMysql));
6842                res=mysql_store_result(&gMysql);
6843                if((field=mysql_fetch_row(res)))
6844                        sprintf(cOwner,"%.31s",field[0]);
6845        }
6846*/
6847
6848        mysql_free_result(res);
6849        sprintf(cJobData,"cName=%.99s.;\n"//Note trailing dot
6850                //"cuTTL=%.15s;\n"
6851                "cIPv4=%.99s;\n"
6852                //"cNSSet=%.31s;\n"
6853                "cZone=%.99s;\n"
6854                "cView=%.31s;\n",
6855                //"cOwner=%.31s;\n",
6856                        cHostname,cIPv4,cZone,cView);
6857
6858        unxsBindARecordJob(uDatacenter,uNode,uContainer,cJobData,uOwner,uCreatedBy);
6859
6860}//void CreateDNSJob()
6861
6862
6863unsigned uGetSearchGroup(const char *gcUser)
6864{
6865        MYSQL_RES *res;
6866        MYSQL_ROW field;
6867        unsigned uGroup=0;
6868
6869        sprintf(gcQuery,"SELECT uGroup FROM tGroup WHERE cLabel='%s' AND uGroupType=2",gcUser);//2 is search type
6870        mysql_query(&gMysql,gcQuery);
6871        if(mysql_errno(&gMysql))
6872                htmlPlainTextError(mysql_error(&gMysql));
6873        res=mysql_store_result(&gMysql);
6874        if((field=mysql_fetch_row(res)))
6875        {
6876                if(field[0]!=NULL)
6877                        sscanf(field[0],"%u",&uGroup);
6878        }
6879        mysql_free_result(res);
6880
6881        return(uGroup);
6882
6883}//unsigned uGetSearchGroup(const char *gcUser)
6884
6885
6886void YesNoPullDownTriState(char *cFieldName, unsigned uSelect, unsigned uMode)
6887{
6888        char cHidden[100]={""};
6889        char *cMode="";
6890
6891        if(!uMode)
6892                cMode="disabled";
6893     
6894        printf("<select name=cYesNo%s %s>\n",cFieldName,cMode);
6895
6896        if(uSelect==0)
6897                printf("<option selected>---</option>\n");
6898        else
6899                printf("<option>---</option>\n");
6900
6901        if(uSelect==1)
6902                printf("<option selected>No</option>\n");
6903        else
6904                printf("<option>No</option>\n");
6905
6906        if(uSelect==2)
6907        {
6908                printf("<option selected>Yes</option>\n");
6909                if(!uMode)
6910                        sprintf(cHidden,"<input type=hidden name=cYesNo%s value='Yes'>\n",
6911                                        cFieldName);
6912        }
6913        else
6914        {
6915                printf("<option>Yes</option>\n");
6916        }
6917
6918        printf("</select>\n");
6919        if(cHidden[0])
6920                printf("%s",cHidden);
6921
6922}//YesNoPullDownTriState()
6923
6924
6925int ReadYesNoPullDownTriState(const char *cLabel)
6926{
6927        if(!strcmp(cLabel,"Yes"))
6928                return(2);
6929        else if(!strcmp(cLabel,"No"))
6930                return(1);
6931        else
6932                return(0);
6933
6934}//ReadYesNoPullDownTriState(char *cLabel)
6935
6936
6937unsigned CreateExecuteCommandsJob(unsigned uDatacenter,unsigned uNode,unsigned uContainer,unsigned uOwner,char *cCommands)
6938{
6939        unsigned uCount=0;
6940
6941        sprintf(gcQuery,"INSERT INTO tJob SET cLabel='ExecuteCommandsJob(%u)',cJobName='ExecuteCommands'"
6942                        ",uDatacenter=%u,uNode=%u,uContainer=%u"
6943                        ",uJobDate=UNIX_TIMESTAMP(NOW())+60"
6944                        ",uJobStatus=1"
6945                        ",cJobData='%.2047s'"
6946                        ",uOwner=%u,uCreatedBy=%u,uCreatedDate=UNIX_TIMESTAMP(NOW())",
6947                                uContainer,
6948                                uDatacenter,uNode,uContainer,
6949                                TextAreaSave(cCommands),
6950                                uOwner,guLoginClient);
6951        mysql_query(&gMysql,gcQuery);
6952        if(mysql_errno(&gMysql))
6953                htmlPlainTextError(mysql_error(&gMysql));
6954        uCount=mysql_insert_id(&gMysql);
6955        return(uCount);
6956
6957}//unsigned CreateExecuteCommandsJob()
6958
Note: See TracBrowser for help on using the browser.