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