LCOV - code coverage report
Current view: top level - src - deployd_cmd.c (source / functions) Hit Total Coverage
Test: deployctl-0.3.15.2.96a2d Code Coverage Lines: 435 910 47.8 %
Date: 2018-06-22 Functions: 3 9 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  deployd_cmd.c
       3             :  Created by Danny Goossen, Gioxa Ltd on 6/2/17.
       4             : 
       5             :  MIT License
       6             : 
       7             :  Copyright (c) 2017 deployctl, Gioxa Ltd.
       8             : 
       9             :  Permission is hereby granted, free of charge, to any person obtaining a copy
      10             :  of this software and associated documentation files (the "Software"), to deal
      11             :  in the Software without restriction, including without limitation the rights
      12             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      13             :  copies of the Software, and to permit persons to whom the Software is
      14             :  furnished to do so, subject to the following conditions:
      15             : 
      16             :  The above copyright notice and this permission notice shall be included in all
      17             :  copies or substantial portions of the Software.
      18             : 
      19             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      20             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      22             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      24             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      25             :  SOFTWARE.
      26             : 
      27             :  */
      28             : 
      29             : #include "deployd.h"
      30             : 
      31             : 
      32           0 : int cmd_tree(void * opaque)
      33             : {
      34           0 :       int exitcode=0;
      35           0 :       struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
      36             :       char command[4096]; // temporary string
      37             : 
      38           0 :       cJSON * env_json=((data_exchange_t *)opaque)->env_json;
      39           0 :       char * dir=cJSON_get_key(env_json, "CI_PROJECT_DIR");
      40             : 
      41           0 :       ((data_exchange_t *)opaque)->needenvp=0;
      42             : 
      43           0 :          int snres=snprintf((char *)command,4096,"cd %s && tree -I '.git' -hCqFax",dir);
      44           0 :          if (snres>=4096)
      45             :          {
      46           0 :             Write_dyn_trace(trace, red,"ERROR: command exeeds max length\n");
      47           0 :             exitcode=1;
      48           0 :             return(exitcode);
      49             :          }
      50           0 :          Write_dyn_trace(trace, none,"+ %s \n",command);
      51           0 :          update_details(trace);
      52           0 :          debug("cmd: %s\n",command);
      53           0 :          ((data_exchange_t *)opaque)->shellcommand=command;
      54           0 :          exitcode=exec_color(opaque);
      55           0 :          if (exitcode) {debug("ERROR: ls -la\n");}
      56             :          // check if certs
      57             : 
      58           0 :       return(exitcode);
      59             : }
      60             : 
      61           0 : int cmd_color_test(void * opaque)
      62             : {
      63           0 :    int exitcode=0;
      64           0 :    struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
      65             :    char command[4096]; // temporary string
      66             :    
      67             :    
      68           0 :    ((data_exchange_t *)opaque)->needenvp=0;
      69             :    // export TERM=xterm-256color && source ~/.bash_profile &&
      70             :    //int snres=snprintf((char *)command,4096,"cd %s && tree -hCqcFx",dir);
      71           0 :    int snres=snprintf((char *)command,4096,"colortest.py");
      72             :    if (snres>=4096)
      73             :    {
      74             :       Write_dyn_trace(trace, red,"ERROR: command exeeds max length\n");
      75             :       exitcode=1;
      76             :       return(exitcode);
      77             :    }
      78           0 :    Write_dyn_trace(trace, none,"+ %s \n",command);
      79           0 :    update_details(trace);
      80           0 :    debug("cmd: %s\n",command);
      81           0 :    ((data_exchange_t *)opaque)->shellcommand=command;
      82           0 :    exitcode=exec_color(opaque);
      83           0 :    if (exitcode) {debug("ERROR: ls -la\n");}
      84             :   
      85             :    return(exitcode);
      86             : }
      87             : 
      88           0 : int cmd_env(void * opaque)
      89             : {
      90           0 :       int exitcode=0;
      91           0 :       struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
      92             :       char command[4096]; // temporary string
      93             : 
      94             :       //cJSON * env_json=((data_exchange_t *)opaque)->env_json;
      95             : 
      96           0 :       ((data_exchange_t *)opaque)->needenvp=1;
      97             : 
      98           0 :          int snres=snprintf((char *)command,4096,"env");
      99             :          if (snres>=4096)
     100             :          {
     101             :             Write_dyn_trace(trace, red,"ERROR: command exeeds max length\n");
     102             :             exitcode=1;
     103             :             return(exitcode);
     104             :          }
     105           0 :          Write_dyn_trace(trace, none,"+ %s \n",command);
     106           0 :          update_details(trace);
     107           0 :          debug("cmd: %s\n",command);
     108           0 :          ((data_exchange_t *)opaque)->shellcommand=command;
     109           0 :          exitcode=exec_color(opaque);
     110           0 :          if (exitcode) {debug("ERROR: ls -la\n");}
     111             :          // check if certs
     112           0 :          update_details(trace);
     113             :       return(exitcode);
     114             : }
     115             : /*------------------------------------------------------------------------
     116             :  * Internal Command : Delete : Delete an environment
     117             :  *------------------------------------------------------------------------*/
     118          13 : int cmd_delete(void * opaque)
     119             : {
     120             :    // feedback buffer
     121          13 :    int exitcode=0;
     122          13 :    struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
     123          13 :     cJSON * env_json=((data_exchange_t *)opaque)->env_json;
     124          13 :    parameter_t * param=((data_exchange_t *)opaque)->parameters;
     125             :     //  just to make sure we're at the right position
     126             :     char * newarg[8];
     127             :     // no need to set environment for individual commands
     128          13 :     ((data_exchange_t *)opaque)->needenvp=0;
     129          13 :     ((data_exchange_t *)opaque)->paramlist=(char **)newarg;
     130             :      char basePATH[1024];
     131          13 :    debug("checking environment\n");
     132             :    //   if (cJSON_GetObjectItem(env_json, "CI_PROJECT_PATH_SLUG") && cJSON_GetObjectItem(env_json, "CI_ENVIRONMENT_SLUG")&& cJSON_GetObjectItem(env_json, "CI_PROJECT_DIR") && cJSON_GetObjectItem(env_json, "CI_ENVIRONMENT_NAME") && cJSON_GetObjectItem(env_json, "CI_COMMIT_SHA"))
     133          13 :       int cnt=0;
     134          13 :    if ((cnt=check_presence(env_json,
     135             :                      (char *[])
     136          13 :                      {"CI_PROJECT_PATH_SLUG","CI_ENVIRONMENT_SLUG","CI_ENVIRONMENT_NAME","CI_PROJECT_PATH","CI_PROJECT_DIR","CI_COMMIT_SHA","CI_PROJECT_URL",NULL}
     137             :                      , trace)))
     138             :    {
     139           1 :       Write_dyn_trace(trace, red,"\nERROR: %d Environment variable(s) Missing\n",cnt);
     140           1 :       debug("\nERROR: %d Environment variable(s) Missing!!!\n",cnt);
     141           1 :       exitcode=1;
     142             :    }
     143             :    else
     144             :    {
     145             :       // inform deployctl of environment deployment
     146          12 :       debug("Deploy environment :%s\n",cJSON_GetObjectItem(env_json, "CI_ENVIRONMENT_NAME")->valuestring);
     147             :       //Write_dyn_trace(trace, none,"Deploy environment :%s\n",cJSON_GetObjectItem(env_json, "CI_ENVIRONMENT_NAME")->valuestring);
     148          12 :       if (validate_key(env_json, "CI_ENVIRONMENT_NAME", "production")==0)
     149             :       {
     150           7 :          if (! cJSON_GetObjectItem(env_json, "DEPLOY_DOMAIN"))
     151             :          { // we got no deploydomain, so make one
     152             :             // as per : $CI_ENVIRONMENT_SLUG.$CI_PROJECT_PATH_SLUG.$DEPLOY_DOMAIN_APP
     153           3 :             debug("PRODUCTION deployment, no deploydomain \n" );
     154           3 :             if(validate_project_path_slug(env_json, trace,1)!=0)
     155             :             {
     156           1 :                Write_dyn_trace(trace, red,"Environment not OK!! \n ** \"DEPLOY_DOMAIN\" and/or \"DEPLOY_APP_DOMAIN\" not defined ** \n");
     157           1 :                exitcode=1;
     158           1 :                return exitcode;
     159             :             }
     160             :             else
     161             :             {
     162           2 :                debug("assemble domain\n");
     163           2 :                char * env_slug=cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG");
     164           2 :                char * project_path_slug=cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG");
     165           2 :                char * deploy_app_domain=cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP");
     166           2 :                   debug("parts%s.%s.%s\n",env_slug,project_path_slug,deploy_app_domain);
     167             : 
     168           2 :                if ((strlen(env_slug)+strlen(project_path_slug)+strlen(deploy_app_domain)+3) > 255)
     169             :                {
     170           1 :                   debug("ENVIRONMENT/PROJECTPATH/DEPLOYAPP to long\n");
     171           1 :                   Write_dyn_trace(trace, red,"ERROR: ENVIRONMENT/PROJECTPATH/DEPLOYAPP to long\n");
     172           1 :                   exitcode=1;
     173           1 :                   return exitcode;
     174             :                }
     175             : 
     176             :                char deploy_domain[256];
     177           1 :                sprintf(deploy_domain, "%s.%s.%s",env_slug,project_path_slug,deploy_app_domain);
     178           1 :                debug("new domain %s\n",deploy_domain);
     179           1 :                cJSON_AddItemToObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
     180             :             }
     181             :          }
     182           5 :          sprintf((char *)basePATH,"%s/deploy/domain/%s",param->prefix,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     183           5 :          debug("basePATH=%s\n",basePATH);
     184             :       }
     185             :       else
     186             :       {
     187           5 :          debug("NOT a production deployment\n");
     188           5 :          if (! cJSON_GetObjectItem(env_json, "DEPLOY_DOMAIN_APP"))
     189             :          {
     190           1 :             debug("DEPLOY_DOMAIN_APP not found\n");
     191           1 :             Write_dyn_trace(trace, none,"ERROR: Environment not OK, $DEPLOY_APP_DOMAIN not defined\n");
     192           1 :             exitcode=1;
     193           1 :             return exitcode;
     194             :          }
     195           4 :          if(validate_project_path_slug(env_json, trace,1)!=0)
     196             :          {
     197           1 :             Write_dyn_trace(trace, red,"ERR: Environment not OK!! \n");
     198           1 :             exitcode=1;
     199           1 :             return exitcode;
     200             :          }
     201           3 :             sprintf((char *)basePATH,"%s/deploy/sites/%s/%s",param->prefix,cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG"),cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG") );
     202             :       }
     203             :         //rm
     204           8 :       if (check_namespace(opaque, basePATH)!=0)
     205             :       {
     206           1 :          Write_dyn_trace(trace, red,"\n ERROR: Namespace belows to another Project!! \n");
     207           1 :          exitcode=1;
     208           1 :          return exitcode;
     209             :       }
     210             : 
     211           7 :         newarg[0]="/bin/rm";
     212           7 :         newarg[1]="-rf";
     213           7 :         newarg[2]=basePATH;
     214           7 :         newarg[3]=NULL;
     215           7 :         Write_dyn_trace(trace, none,"+ rm deployment \n");
     216           7 :         debug("cmd: %s %s %s \n",newarg[0],newarg[1],newarg[2]);
     217           7 :         exitcode=cmd_exec(opaque);
     218           7 :         if (exitcode) {debug("Failed exec rmdir %s\n",newarg[2]);return exitcode;}
     219             :     }
     220             :    // TODO
     221           8 :    return exitcode;
     222             : }
     223             : 
     224             : /*------------------------------------------------------------------------
     225             :  * Internal Command : config https, configures https (letsencrypt)
     226             :  *------------------------------------------------------------------------*/
     227           0 : int cmd_conf_https(void * opaque)
     228             : {
     229             :    // feedback buffer
     230           0 :    int exitcode=0;
     231           0 :    struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
     232             :     // env json
     233           0 :     cJSON * env_json=((data_exchange_t *)opaque)->env_json;
     234           0 :    parameter_t * param=((data_exchange_t *)opaque)->parameters;
     235             :     char * newarg[11];
     236             :     // no need to set environment for individual commands
     237           0 :     ((data_exchange_t *)opaque)->needenvp=0;
     238           0 :     ((data_exchange_t *)opaque)->paramlist=(char **)newarg;
     239             :    char basePATH[1024];
     240             :    char baseHREF[1024];
     241             :     struct stat st;
     242           0 :     debug("checking environment\n");
     243           0 :    int cnt=0;
     244           0 :    if ((cnt=check_presence(env_json,
     245             :                      (char *[])
     246           0 :       {"CI_PROJECT_PATH_SLUG","CI_ENVIRONMENT_SLUG","CI_ENVIRONMENT_NAME","CI_PROJECT_PATH","GITLAB_USER_EMAIL",NULL}
     247             :                      , trace)))
     248             :    {
     249           0 :       Write_dyn_trace(trace, none,"ERROR: %d Environment variable(s) Missing\n",cnt);
     250           0 :       debug("\nERROR: %d Environment variable(s) Missing!!!\n",cnt);
     251           0 :       exitcode=1;
     252             :    }
     253             :    else
     254             :    {
     255             :         // inform deployctl of environment deployment
     256           0 :         debug("Deploy environment :%s\n",cJSON_get_key(env_json, "CI_ENVIRONMENT_NAME"));
     257             :         //Write_dyn_trace(trace, none,"Deploy environment :%s\n",cJSON_get_key(env_json, "CI_ENVIRONMENT_NAME"));
     258           0 :         debug("check CI_ENV\n");
     259           0 :       if (validate_key(env_json, "CI_ENVIRONMENT_NAME", "production")==0)
     260             :         {
     261           0 :             debug("PRODUCTION deployment=> OK\n");
     262           0 :             if (! cJSON_GetObjectItem(env_json, "DEPLOY_DOMAIN"))
     263             :             { // we got no deploydomain, so make one
     264             :             // as per : $CI_ENVIRONMENT_SLUG.$CI_PROJECT_PATH_SLUG.$DEPLOY_DOMAIN_APP
     265           0 :             if(validate_project_path_slug(env_json, trace,1)!=0)
     266             :             {
     267           0 :                Write_dyn_trace(trace, red,"Environment not OK!! \n ** \"DEPLOY_DOMAIN\" and/or \"DEPLOY_APP_DOMAIN\" not defined ** \n");
     268           0 :                exitcode=1;
     269           0 :                return exitcode;
     270             :             }
     271             :             else
     272             :             {
     273           0 :                char * env_slug=cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG");
     274           0 :                 char * project_path_slug=cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG");
     275           0 :                char * deploy_app_domain=cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP");
     276           0 :                char * deploy_domain=calloc(1,strlen(env_slug)+strlen(project_path_slug)+strlen(deploy_app_domain)+3);
     277           0 :                sprintf(deploy_domain, "%s.%s.%s",env_slug,project_path_slug,deploy_app_domain);
     278           0 :                cJSON_AddItemToObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
     279             :             }
     280             :             }
     281           0 :          sprintf(baseHREF,"http://%s",cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     282           0 :          sprintf((char *)basePATH,"%s/deploy/domain/%s",param->prefix,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     283             :         }
     284             :         else
     285             :         {
     286           0 :                 debug("config-https only for production environment\n");
     287           0 :                 Write_dyn_trace(trace, red,"\n ERROR: config-https only for production environment\n");
     288           0 :                 exitcode=1;
     289           0 :                 return exitcode;
     290             :         }
     291             :         // check domaindir
     292           0 :         if(stat(basePATH,&st) != 0)
     293             :         {
     294             :          // deploydir not present no point to continue
     295           0 :             debug("ERROR: Deploy dir %s not present\n",basePATH);
     296           0 :             Write_dyn_trace(trace, red,"\n ERROR: no deployment present\n");
     297           0 :             exitcode=1;
     298           0 :             return exitcode;
     299             :         }
     300             :       //Write_dyn_trace(trace, none,"Deploy environment :%s\n",cJSON_get_key(env_json, "CI_ENVIRONMENT_NAME"));
     301             :       // now check if dir exist, if so check the "CI_PROJECT_URL" !!!
     302           0 :       if (check_namespace(opaque, basePATH)!=0)
     303             :       {
     304           0 :          Write_dyn_trace(trace, red,"\n ERROR: Namespace belows to another Project!! \n");
     305           0 :          exitcode=1;
     306           0 :          return exitcode;
     307             :       }
     308             :       // check if dns points to this instance for this url
     309           0 :       exitcode= url_check(opaque, basePATH,baseHREF);
     310           0 :       if (exitcode)
     311             :       {
     312           0 :          debug("ERR: url check\n");
     313           0 :          return exitcode;
     314             :       }
     315           0 :       update_details(trace);
     316           0 :       debug("start letsencript\n");
     317             :         // check if letsencript config exists, if not create new cert
     318           0 :         exitcode=letsencrypt(opaque,cJSON_get_key(env_json, "DEPLOY_DOMAIN"),cJSON_get_key(env_json, "GITLAB_USER_EMAIL"));
     319             :       // write https
     320           0 :       if (!exitcode)
     321             :       {
     322           0 :          exitcode= write_http_config(opaque,1,basePATH,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     323           0 :          if (exitcode){debug("Failed create http config\n");return exitcode;}
     324           0 :          exitcode=  verify_http_config(opaque);
     325           0 :          if (exitcode)
     326             :          {
     327           0 :             debug("Failed nginx -t \n");
     328           0 :             delete_http_config(opaque,basePATH);
     329             : 
     330           0 :             return exitcode;
     331             :          }
     332           0 :          else exitcode=reload_http_config(opaque);
     333             :       }
     334           0 :       else debug("ERR: let's encrypt failed\n");
     335           0 :        update_details(trace);
     336             :     }
     337           0 :     return exitcode;
     338             : }
     339             : 
     340             : /*------------------------------------------------------------------------
     341             :  * Internal Command : static : filter the env and rsync project/public to public
     342             :  *------------------------------------------------------------------------*/
     343          16 : int cmd_static(void * opaque)
     344             : {
     345             :    // feedback buffer
     346          16 :    int exitcode=0;
     347          16 :    struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
     348             :    // env json
     349          16 :    cJSON * env_json=((data_exchange_t *)opaque)->env_json;
     350             :     char * newarg[8];
     351             :     // no need to set environment for individual commands
     352          16 :     ((data_exchange_t *)opaque)->needenvp=0;
     353          16 :    ((data_exchange_t *)opaque)->paramlist=(char **)newarg;
     354          16 :    parameter_t * param=((data_exchange_t *)opaque)->parameters;
     355             :     char var_arg1_string[1024];
     356             :    // char * var_dest_dir_string[1024];
     357             :    char basePATH[1024];
     358             :    char baseHREF[1024];
     359             :    char pubPATH[1024];
     360          16 :     int deploy_production=0;
     361             :   // setdebug();
     362          16 :    debug("checking environment\n");
     363          16 :    int cnt=0;
     364          16 :    if ((cnt=check_presence(env_json,
     365             :                      (char *[])
     366          16 :                      {"CI_PROJECT_PATH_SLUG","CI_ENVIRONMENT_SLUG","CI_ENVIRONMENT_NAME","CI_PROJECT_PATH","CI_PROJECT_DIR","CI_COMMIT_SHA","CI_PROJECT_URL",NULL}
     367             :                      , trace)))
     368             :    {
     369           1 :       Write_dyn_trace(trace, red,"ERROR: %d Environment variable(s) Missing\n",cnt);
     370           1 :       debug("\nERROR: %d Environment variable(s) Missing!!!\n",cnt);
     371           1 :       exitcode=1;
     372             :    }
     373             :    else
     374             :    {
     375             :       // inform deployctl of environment deployment
     376          15 :       debug("Deploy environment :%s\n",cJSON_get_key(env_json,  "CI_ENVIRONMENT_NAME"));
     377             : 
     378          15 :       debug("wrote env\n");
     379          15 :       if (validate_key(env_json, "CI_ENVIRONMENT_NAME", "production")==0)
     380             :       {
     381          10 :         debug("validate_key\n");
     382          10 :          if (! cJSON_GetObjectItem(env_json, "DEPLOY_DOMAIN"))
     383             :          { // we got no deploydomain, so make one
     384             :             // as per : $CI_ENVIRONMENT_SLUG.$CI_PROJECT_PATH_SLUG.$DEPLOY_DOMAIN_APP
     385             :             //debug("PRODUCTION deployment, no deploydomain and slugok=%d \n",(validate_project_path_slug(opaque, trace)!=0) );
     386           4 :             if(validate_project_path_slug(env_json, trace,1)!=0)
     387             :             {
     388           1 :                Write_dyn_trace(trace, none,"Environment not OK!! \n ** \"DEPLOY_DOMAIN\" and/or \"DEPLOY_APP_DOMAIN\" not defined ** \n");
     389           1 :                exitcode=1;
     390           1 :                return exitcode;
     391             :             }
     392             :             else
     393             :             {
     394           3 :                debug("assemble domain\n");
     395           3 :                char * env_slug=cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG");
     396           3 :                char * project_path_slug=cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG");
     397           3 :                char * deploy_app_domain=cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP");
     398           3 :                debug("parts%s.%s.%s\n",env_slug,project_path_slug,deploy_app_domain);
     399             :                // TODO change to one function
     400           3 :                if ((strlen(env_slug)+strlen(project_path_slug)+strlen(deploy_app_domain)+3) > 255)
     401             :                {
     402           1 :                   debug("ENVIRONMENT/PROJECTPATH/DEPLOYAPP to long\n");
     403           1 :                   Write_dyn_trace(trace, none,"ERR: ENVIRONMENT/PROJECTPATH/DEPLOYAPP to long\n");
     404           1 :                   exitcode=1;
     405           1 :                   return exitcode;
     406             :                }
     407             :                // TODO check others, need to be static, no malloc => mem leaks
     408             :                char deploy_domain[256];
     409           2 :                sprintf(deploy_domain, "%s.%s.%s",env_slug,project_path_slug,deploy_app_domain);
     410           2 :                debug("new domain %s\n",deploy_domain);
     411           2 :                cJSON_AddItemToObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
     412             :             }
     413             :          }
     414           8 :          deploy_production=1;
     415           8 :          sprintf((char *)basePATH,"%s/deploy/domain/%s",param->prefix,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     416           8 :          sprintf(baseHREF,"http://%s",cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     417             :       }
     418             :       else
     419             :       {
     420           5 :          debug("NOT a production deployment\n");
     421           5 :          deploy_production=0;
     422           5 :          if (! cJSON_GetObjectItem(env_json, "DEPLOY_DOMAIN_APP"))
     423             :          {
     424           1 :             debug("DEPLOY_DOMAIN_APP not found\n");
     425           1 :             Write_dyn_trace(trace, none,"ERR: Environment not OK, $DEPLOY_APP_DOMAIN not defined\n");
     426           1 :             exitcode=1;
     427           1 :             return exitcode;
     428             :          }
     429           4 :          if(validate_project_path_slug(env_json, trace,1)!=0)
     430             :          {
     431           1 :             Write_dyn_trace(trace, none,"ERR: Environment not OK!! \n");
     432           1 :             exitcode=1;
     433           1 :             return exitcode;
     434             :          }
     435           3 :          debug("assemble domain\n");
     436           3 :          char * env_slug=cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG");
     437           3 :          char * project_path_slug=cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG");
     438           3 :          char * deploy_app_domain=cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP");
     439           3 :          debug("parts%s.%s.%s\n",env_slug,project_path_slug,deploy_app_domain);
     440           3 :          debug("paramprefix=%s\n",param->prefix);
     441           3 :          sprintf((char *)basePATH,"%s/deploy/sites/%s/%s",param->prefix,cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG"),cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG") );
     442           3 :          sprintf(baseHREF,"http://%s.%s.%s",cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG"),cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG"), cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP"));
     443             :          char deploy_domain[256];
     444           3 :          sprintf(deploy_domain, "%s.%s.%s",env_slug,project_path_slug,deploy_app_domain);
     445           3 :          debug("new domain %s\n",deploy_domain);
     446           3 :          if (cJSON_get_key(env_json,"DEPLOY_DOMAIN"))
     447           2 :          cJSON_ReplaceItemInObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
     448             :          else
     449           1 :          cJSON_AddItemToObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
     450           3 :         debug("basepath=%s\n",basePATH);
     451             :       }
     452             :       // now check if dir exist, if so check the "CI_PROJECT_URL" !!!
     453          11 :       if (check_namespace(opaque, basePATH)!=0)
     454             :       {
     455           2 :          Write_dyn_trace(trace, none,"ERR: Namespace belows to another Project!! \n");
     456           2 :          exitcode=1;
     457           2 :          return exitcode;
     458             :       }
     459             : 
     460             :       // need pubdir
     461           9 :       sprintf(pubPATH,"%s/public",basePATH);
     462           9 :       debug("pubpath=%s, %d\n",pubPATH,exitcode);
     463             : 
     464           9 :       _mkdir(NULL,pubPATH);
     465             : 
     466           9 :         Write_dyn_trace(trace, none,"+ mkdir public \n");
     467             :       //if (deploy_production)
     468             :       {
     469           9 :          exitcode= write_http_config(opaque,0,basePATH,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     470           9 :          if (exitcode){debug("Failed create http config\n");return exitcode;}
     471           8 :          exitcode=  verify_http_config(opaque);
     472           8 :          if (exitcode)
     473             :          {
     474           1 :             debug("Failed nginx -t \n");
     475           1 :             delete_http_config(opaque,basePATH);
     476             : 
     477           1 :             return exitcode;
     478             :          }
     479           7 :          else exitcode=reload_http_config(opaque);
     480             :       }
     481             : 
     482             :       // check if dns points to this instance for this url
     483           7 :       if (!exitcode) exitcode= url_check(opaque, basePATH,baseHREF);
     484             :       // remove pubdir
     485           7 :       _rmdir(NULL ,pubPATH );
     486           7 :       debug("starting with publish paths, exitcode %d\n",exitcode);
     487             :       // replace with our wishes
     488           7 :       if (!exitcode)
     489             :       {
     490             :          cJSON * dep_path;
     491           8 :          cJSON_ArrayForEach(dep_path, cJSON_GetObjectItem(env_json, "DEPLOY_PUBLISH_PATH"))
     492             :          {
     493           4 :             char * source=dep_path->child->valuestring;
     494           4 :             char * target=dep_path->child->string;
     495           4 :             char * dir=NULL;
     496           4 :             split_path_file_2_path(&dir,target);
     497           4 :             _mkdir(dir,pubPATH);
     498           4 :             debug("s=%s, t=%s,tdir=%s\n",source,target,dir);
     499           4 :             if (dir) free(dir);
     500           4 :             if (!exitcode)
     501             :             {
     502             :               // rsync
     503           4 :                newarg[0]="/bin/sh";
     504           4 :                newarg[1]="-c";
     505           4 :                newarg[2]=(char *)var_arg1_string;
     506           4 :                sprintf((char *)newarg[2],"/usr/bin/rsync -r %s%s %s%s",cJSON_get_key(env_json, "CI_PROJECT_DIR"),source,pubPATH,target);
     507           4 :                newarg[3]=NULL;
     508           4 :                Write_dyn_trace(trace, none,"+ rsync ");
     509           4 :                Write_dyn_trace_pad(trace, cyan,75-8,"%s -> %s", source,target);
     510           4 :                debug("cmd: %s %s %s\n",newarg[0],newarg[1],newarg[2]);
     511           4 :                exitcode=cmd_exec(opaque);
     512           4 :                if (exitcode)
     513             :                {
     514           0 :                  debug("Failed exec rsync %s: %s\n",newarg[2],trace);
     515           0 :                  Write_dyn_trace(trace, red,"\n  [FAILED]\n");
     516           0 :                  return exitcode;
     517             :              }
     518           4 :                         else Write_dyn_trace(trace, green,"[OK]\n");
     519             :             }
     520             :          }
     521             :       }
     522           7 :       if (!exitcode)
     523             :       {
     524           4 :          exitcode=write_namespace(opaque, basePATH);
     525           4 :          if (exitcode) debug("Failed to write_namespace\n");
     526             :       }
     527           7 :       if (!exitcode && deploy_production && validate_key(env_json, "DEPLOY_CONFIG_HTTPS","True" )==0)
     528             :       {
     529             :          //config https
     530             : 
     531           0 :          debug("start letsencript\n");
     532             :          // check if letsencript config exists, if not create new cert
     533           0 :          exitcode=letsencrypt(opaque,cJSON_get_key(env_json, "DEPLOY_DOMAIN"),cJSON_get_key(env_json, "GITLAB_USER_EMAIL"));
     534             :          // write https
     535           0 :          if (!exitcode)
     536             :          {
     537           0 :             exitcode= write_http_config(opaque,1,basePATH,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     538           0 :             if (exitcode){debug("Failed create http config\n");return exitcode;}
     539           0 :             exitcode=  verify_http_config(opaque);
     540           0 :             if (exitcode)
     541             :             {
     542           0 :                debug("Failed nginx -t \n");
     543           0 :                delete_http_config(opaque,basePATH);
     544             : 
     545           0 :                return exitcode;
     546             :             }
     547           0 :             else exitcode=reload_http_config(opaque);
     548             :          }
     549           0 :          else debug("ERR: let's encrypt failed\n");
     550           0 :          update_details(trace);
     551             :       }
     552             :    }
     553           8 :    return exitcode;
     554             : }
     555             : 
     556             : /*------------------------------------------------------------------------
     557             :  * Internal Command : Release : filter the env, create release and rsync
     558             :  *------------------------------------------------------------------------*/
     559          20 : int cmd_release(void * opaque)
     560             : {
     561             :    // feedback buffer
     562          20 :    int exitcode=0;
     563          20 :    struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
     564             :    // env json
     565          20 :    cJSON * env_json=((data_exchange_t *)opaque)->env_json;
     566             :    char * newarg[8];
     567             :    // no need to set environment for individual commands
     568          20 :    ((data_exchange_t *)opaque)->needenvp=0;
     569          20 :    ((data_exchange_t *)opaque)->paramlist=(char **)newarg;
     570          20 :    parameter_t * param=((data_exchange_t *)opaque)->parameters;
     571             :    char var_arg1_string[1024];
     572             :    char var_arg2_string[1024];
     573             :    // char * var_dest_dir_string[1024];
     574          20 :    int deploy_production=0;
     575          20 :    debug("checking environment\n");
     576             :    char basePATH[1024];
     577             :    char baseHREF[1024];
     578             :    char tagPATH[1024];
     579             :    char tagHREF[1024];
     580             :    char subPATH[1024];
     581          20 :    char * build_ref_slug=NULL;
     582          20 :    int cnt=0;
     583             : 
     584          20 :    if ((cnt=check_presence(env_json,
     585             :                      (char *[])
     586          20 :       {"CI_PROJECT_PATH_SLUG","CI_ENVIRONMENT_SLUG","CI_ENVIRONMENT_NAME","CI_PROJECT_PATH","CI_PROJECT_DIR","CI_COMMIT_SHA","CI_COMMIT_REF_SLUG","CI_PROJECT_URL","CI_JOB_TOKEN","CI_PROJECT_ID",NULL}
     587             :                      , trace)))
     588             :    {
     589           1 :       Write_dyn_trace(trace, red,"ERROR: %d Environment variable(s) Missing\n",cnt);
     590           1 :       debug("\nERROR: %d Environment variable(s) Missing!!!\n",cnt);
     591           1 :       exitcode=1;
     592             :    }
     593             :    else
     594             :    {
     595             :       // inform deployctl of environment deployment
     596          19 :       debug("Deploy environment :%s\n",cJSON_get_key(env_json, "CI_ENVIRONMENT_NAME"));
     597             :       //Write_dyn_trace(trace, none,"Deploy environment :%s\n",cJSON_GetObjectItem(env_json, "CI_ENVIRONMENT_NAME")->valuestring);
     598          19 :       build_ref_slug=cJSON_get_key(env_json, "CI_COMMIT_REF_SLUG");
     599          19 :       if (validate_key(env_json, "CI_ENVIRONMENT_NAME", "production")==0)
     600             :       {
     601          14 :          debug("PRODUCTION deployment\n");
     602          14 :             deploy_production=1;
     603          14 :             if (!cJSON_get_key(env_json,"CI_COMMIT_TAG"))
     604             :          {
     605           1 :             Write_dyn_trace(trace, none,"Production release without a release TAG not OK!! \n");
     606           1 :             exitcode=1;
     607           1 :             return exitcode;
     608             :          }
     609          13 :          if (! cJSON_GetObjectItem(env_json, "DEPLOY_DOMAIN"))
     610             :          { // we got no deploydomain, so make one
     611             :             // as per : $CI_ENVIRONMENT_SLUG.$CI_PROJECT_PATH_SLUG.$DEPLOY_DOMAIN_APP
     612             : 
     613           3 :             debug("\nNo Deploy demain:\n");
     614           3 :             if(validate_project_path_slug(env_json, trace,1)!=0)
     615             :             {
     616           1 :                debug("no valid project path\n");
     617           1 :                Write_dyn_trace(trace, red,"Environment not OK!! \n ** \"DEPLOY_DOMAIN\" and/or \"DEPLOY_APP_DOMAIN\" not defined ** \n");
     618           1 :                exitcode=1;
     619           1 :                return exitcode;
     620             :             }
     621             :             else
     622             :             {
     623           2 :                debug("extracting new domain\n");
     624           2 :                char * env_slug=cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG");
     625           2 :                char * project_path_slug=cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG");
     626           2 :                char * deploy_app_domain=cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP");
     627             :                char deploy_domain[256];
     628           2 :                sprintf(deploy_domain, "%s.%s.%s",env_slug,project_path_slug,deploy_app_domain);
     629           2 :                debug("new domain %s\n",deploy_domain);
     630           2 :                cJSON_AddItemToObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
     631             :             }
     632             :          }
     633          12 :          debug("building paths\n");
     634          12 :             sprintf(baseHREF,"http://%s",cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     635          12 :             sprintf((char *)tagHREF,"%s/%s",baseHREF,build_ref_slug);
     636          12 :             sprintf((char *)basePATH,"%s/deploy/domain/%s",param->prefix,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     637          12 :             sprintf((char *)tagPATH,"%s/public/%s",basePATH,build_ref_slug);
     638             :         // **** read release and udate with new release
     639          12 :          sprintf(subPATH,"/%s/files",build_ref_slug);
     640             :         }
     641             :       else
     642             :       {
     643           5 :          debug("NOT a production deployment\n");
     644           5 :          deploy_production=0;
     645           5 :          if (! cJSON_GetObjectItem(env_json, "DEPLOY_DOMAIN_APP"))
     646             :         {
     647           1 :             debug("DEPLOY_DOMAIN_APP not found\n");
     648           1 :             Write_dyn_trace(trace, none,"ERR: Environment not OK, $DEPLOY_APP_DOMAIN not defined\n");
     649           1 :             exitcode=1;
     650           1 :             return exitcode;
     651             :         }
     652           4 :          if(validate_project_path_slug(env_json, trace,1)!=0)
     653             :          {
     654           1 :             debug("ERR: Project_Path_slug, Environment not OK!! \n");
     655           1 :             Write_dyn_trace(trace, red,"ERR: Environment not OK!! \n");
     656           1 :             exitcode=1;
     657           1 :             return exitcode;
     658             :          }
     659           3 :          debug("assemble domain\n");
     660           3 :          char * env_slug=cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG");
     661           3 :          char * project_path_slug=cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG");
     662           3 :          char * deploy_app_domain=cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP");
     663           3 :          debug("parts%s.%s.%s\n",env_slug,project_path_slug,deploy_app_domain);
     664             : 
     665             : 
     666             :         // set the variables for directory and HREF
     667           3 :          sprintf(baseHREF,"http://%s.%s.%s",cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG"),cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG"), cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP"));
     668           3 :          sprintf((char *)basePATH,"%s/deploy/sites/%s/%s",param->prefix,cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG"),cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG"));
     669             :          // non domain deploys have no tags history
     670           3 :          sprintf((char *)tagPATH,"%s/public",basePATH);
     671           3 :          sprintf((char *)tagHREF,"%s",baseHREF);
     672           3 :          sprintf(subPATH,"/files");
     673             :          char deploy_domain[256];
     674           3 :          sprintf(deploy_domain, "%s.%s.%s",env_slug,project_path_slug,deploy_app_domain);
     675           3 :          debug("new domain %s\n",deploy_domain);
     676           3 :          if (cJSON_get_key(env_json,"DEPLOY_DOMAIN"))
     677           2 :          cJSON_ReplaceItemInObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
     678             :          else
     679           1 :          cJSON_AddItemToObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
     680             : 
     681             :       }
     682             : 
     683          15 :       debug("checking namespace\n");
     684          15 :       if (check_namespace(opaque, basePATH)!=0)
     685             :       {
     686           2 :          Write_dyn_trace(trace, red,"\nERROR: Namespace belongs to another Project!! \n");
     687           2 :          exitcode=1;
     688           2 :          return exitcode;
     689             :       }
     690             : 
     691          13 :       _mkdir("/files",tagPATH);
     692             : 
     693             : 
     694             :        // on deploy production we create a http config file
     695             :       //if (deploy_production)
     696             :       {
     697          13 :          exitcode= write_http_config(opaque,0,basePATH,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
     698          13 :          if (exitcode){debug("Failed create http config\n");return exitcode;}
     699          12 :          exitcode=  verify_http_config(opaque);
     700          12 :          if (exitcode)
     701             :          {
     702           1 :             debug("Failed nginx -t \n");
     703           1 :             delete_http_config(opaque,basePATH);
     704             : 
     705           1 :             return exitcode;
     706             :          }
     707          11 :          else exitcode=reload_http_config(opaque);
     708             :       }
     709             :       // check if dns points to this instance for this url
     710          11 :       if (!exitcode) exitcode= url_check(opaque, basePATH,baseHREF);
     711          11 :       if (!exitcode)
     712             :       {
     713           8 :          exitcode=write_namespace(opaque, basePATH);
     714           8 :          if (!exitcode) debug("Failed to write_namespace\n");
     715             :       }
     716          11 :       _rmdir("/files",tagPATH);
     717          11 :       if (!exitcode)
     718             :       {
     719             :          cJSON * dep_path;
     720           8 :          cJSON_ArrayForEach(dep_path, cJSON_GetObjectItem(env_json, "DEPLOY_RELEASE_PATH"))
     721             :          {
     722           0 :             char * source=dep_path->child->valuestring;
     723           0 :             char * target=dep_path->child->string;
     724           0 :             char * dir=NULL;
     725           0 :             split_path_file_2_path(&dir,target);
     726             :             char files_path[1024];
     727           0 :             sprintf(files_path,"%s/files%s",tagPATH,dir);
     728           0 :             _mkdir(NULL,files_path);
     729           0 :             debug("s=%s, t=%s,tdir=%s, >%s<\n",source,target,dir,files_path);
     730           0 :             if (dir) free(dir);
     731             :             // rsync
     732           0 :             newarg[0]="/usr/bin/rsync";
     733           0 :             newarg[1]="-r";
     734           0 :             newarg[2]=(char *)var_arg1_string;
     735           0 :             sprintf((char *)newarg[2],"%s%s",cJSON_get_key(env_json, "CI_PROJECT_DIR"),source);
     736           0 :             newarg[3]=(char *)var_arg2_string;
     737           0 :             sprintf((char *)newarg[3],"%s%s",files_path,target);
     738           0 :             newarg[4]=NULL;
     739           0 :             Write_dyn_trace(trace, none,"+ rsync release ");
     740           0 :             Write_dyn_trace_pad(trace, cyan,75-16,"%s -> %s",source,target);
     741           0 :             debug("cmd: %s %s %s %s\n",newarg[0],newarg[1],newarg[2],newarg[3]);
     742           0 :             exitcode=cmd_exec(opaque);
     743           0 :             if (!exitcode)
     744           0 :               Write_dyn_trace(trace, green,"[OK]\n");
     745             :             else
     746           0 :               Write_dyn_trace(trace, red,"[FAILED]\n");
     747           0 :             if (exitcode)
     748           0 :                {debug("Failed exec rsync %s\n",newarg[2]);return exitcode;}
     749             :          }
     750             :    }
     751             :    } // environment check ok
     752             : 
     753             : 
     754             :    // get gitlab release info
     755          12 :    cJSON * grelease_tag=NULL;
     756          12 :    if (!exitcode && cJSON_GetObjectItem(env_json, "CI_COMMIT_TAG"))
     757             :    {
     758           8 :       Write_dyn_trace_pad(trace, none,75,"+ get gitlab tag ...");
     759           8 :        update_details(trace);
     760           8 :       debug("getting release from gitlab and put into html buffer\n");
     761           8 :       if (!get_release(opaque, &grelease_tag))
     762             :       {
     763           7 :          char * temp_out=cJSON_get_key(grelease_tag, "message");
     764           7 :          if (temp_out)
     765             :          {
     766           6 :             debug("release info ok \n");
     767           6 :             Write_dyn_trace(trace, green,"[OK]\n");
     768             :          }
     769             :          else
     770             :          {
     771           1 :             debug ("no release info\n");
     772           1 :             Write_dyn_trace(trace, bold_magenta,"\nNO release info\n");
     773             :                         }
     774             :       }
     775             :       else
     776             :       {
     777           1 :          Write_dyn_trace(trace, bold_magenta,"\n API Problem\n");
     778           1 :          debug ("problem getting tag from gitlab\n");
     779             :       }
     780           8 :       update_details(trace);
     781             :    }
     782             :    // create this release=> for all environment
     783             :    char filepath[1024];
     784          12 :    char * last_tag=NULL;
     785          12 :    char * release_print=NULL;
     786          12 :    char * release_json_js_print=NULL;
     787          12 :    cJSON * releases=NULL;
     788          12 :    cJSON * this_release=NULL;
     789          12 :    int clean_tag=0;
     790             : 
     791          12 :    if (!exitcode && deploy_production)
     792             :    {
     793           7 :       clean_tag=is_clean_tag(opaque,cJSON_get_key(env_json, "CI_COMMIT_TAG"),(const char *[]) {"BETA","TEST","RC","PRC","ALPHA",NULL});
     794             :    }
     795          12 :    if (!exitcode && deploy_production && clean_tag)
     796             :    {
     797           5 :       last_tag=strdup(cJSON_get_key(env_json, "CI_COMMIT_TAG"));
     798           7 :    } else if (!exitcode && deploy_production)
     799             :    {
     800           2 :       last_tag=check_last_tag(opaque,basePATH);
     801             :    }
     802             : 
     803          12 :    debug("last_tag: %s\n",last_tag);
     804          12 :    if (!exitcode)
     805             :    {
     806           8 :          this_release= create_thisrelease_json(  opaque , grelease_tag,  deploy_production, basePATH,subPATH);
     807             :    }
     808          12 :    if (!exitcode && this_release)
     809             :    {
     810           8 :       release_print = create_releases_json( opaque , this_release,  &releases, deploy_production);
     811             :    }
     812          12 :    if (!exitcode && release_print)
     813             :    {
     814           8 :         release_json_js_print= create_release_json_js (opaque , baseHREF, release_print,1 , last_tag); // tagHREF?
     815             :    }
     816             :    //
     817             :    //NOW write it!!! in tagPATH
     818          12 :    if (!exitcode && release_json_js_print)
     819             :    {
     820             :       // **** read release and udate with new release
     821           8 :       sprintf(filepath,"%s/deployw_json.js",tagPATH);
     822           8 :       newarg[0]="write_file";
     823           8 :       newarg[1]=(char *)filepath;
     824           8 :       newarg[2]=(char *)release_json_js_print;
     825           8 :       newarg[3]=NULL;
     826           8 :          debug("deployw_json.js:==>\n%s\n\n",newarg[2]);
     827           8 :       if (deploy_production)
     828           7 :          Write_dyn_trace_pad(trace, none,75,"+ write /%s/deployw_json.js",build_ref_slug);
     829             :       else
     830           1 :          Write_dyn_trace_pad(trace, none,75,"+ write /%s/deployw_json.js",build_ref_slug);
     831           8 :          exitcode=cmd_write(opaque);
     832           8 :          if (!exitcode)
     833           8 :            Write_dyn_trace(trace, green,"[OK]\n");
     834             :          else
     835           0 :            Write_dyn_trace(trace, red,"[FAILED]\n");
     836             : 
     837           8 :          if (exitcode)
     838           0 :             error("\nERR: writing deployw_json.js\n");
     839             :          else
     840           8 :             debug ("wrote %s\n", newarg[1]);
     841             :    }
     842             : 
     843             :    // cleanup
     844          12 :    if (releases) { cJSON_Delete(releases);releases=NULL; }
     845          12 :    if (release_print) {free(release_print); release_print=NULL; }
     846          12 :    if (release_json_js_print) {free(release_json_js_print); release_json_js_print=NULL; }
     847          12 :    if (grelease_tag){cJSON_Delete(grelease_tag); grelease_tag=NULL;}
     848          12 :    update_details(trace);
     849             :    // ******************************************************************
     850             :    // now do the things for production env!, this time save to basePATH
     851             :    // ******************************************************************
     852          12 :    if (!exitcode && deploy_production && this_release)
     853             :    {
     854             :       // **** read release and udate with new release
     855           7 :       sprintf(filepath,"%s/public/release.json",basePATH);
     856           7 :       releases=read_release_json(opaque, filepath);
     857           7 :       release_print=create_releases_json(opaque, this_release, &releases, 1);
     858           7 :       newarg[0]="write_file";
     859           7 :       newarg[1]=(char *)filepath;
     860           7 :       newarg[2]=(char *)release_print;
     861           7 :       newarg[3]=NULL;
     862           7 :       if (newarg[2])
     863             :       {
     864           7 :          debug("release.json:==>\n%s\n\n",newarg[2]);
     865           7 :          Write_dyn_trace_pad(trace, none,75,"+ write /release.json");
     866           7 :          exitcode=cmd_write(opaque);
     867           7 :          if (exitcode){
     868           0 :            Write_dyn_trace(trace, red,"[FAIL]\n");
     869           0 :             error("\nERR: writing release.json\n");
     870             :         }
     871             :         else
     872             :         {
     873           7 :           Write_dyn_trace(trace, green,"[OK]\n");
     874           7 :            debug ("wrote %s\n", newarg[1]);
     875             :         }
     876             :       }
     877             :       else
     878           0 :       { Write_dyn_trace(trace, red,"\nERR: preparing release.json \n"); error(" getting print JSONBUFF\n");exitcode=1; }
     879             :    }
     880          12 :    update_details(trace);
     881          12 :    if (!exitcode && release_print) release_json_js_print= create_release_json_js(opaque, baseHREF,release_print,0,last_tag);
     882          12 :    if (release_json_js_print)
     883             :    { // write it
     884           7 :       sprintf(filepath,"%s/public/deployw_json.js",basePATH);
     885           7 :       newarg[0]="write_file";
     886           7 :       newarg[1]=(char *)filepath;
     887           7 :       newarg[2]=(char *)release_json_js_print;
     888           7 :       newarg[3]=NULL;
     889             :       //debug("release.json:==>\n%s\n\n",newarg[2]);
     890           7 :       Write_dyn_trace_pad(trace, none,75,"+ write /deployw_json.js");
     891           7 :       exitcode=cmd_write(opaque);
     892           7 :       if (exitcode){
     893           0 :         Write_dyn_trace(trace, red,"[FAIL]\n");
     894           0 :         error("\nERR: writing deployw_json.js\n");
     895             :      }
     896             :      else
     897             :      {
     898           7 :        Write_dyn_trace(trace, green,"[OK]\n");
     899           7 :         debug ("wrote %s\n", newarg[1]);
     900             :      }
     901             : 
     902           7 :       free(release_json_js_print);
     903             :    }
     904           5 :    else if (deploy_production)
     905             :    {
     906           2 :        Write_dyn_trace(trace, red,"\nERR: preparing deployw_json.js \n");
     907           2 :        error("\nERR: getting data for deployw_json.js\n");
     908           2 :        exitcode=1;
     909             :    }
     910             :    // And clean it up.
     911          12 :    if (release_print) free(release_print);
     912          12 :    if (last_tag) free(last_tag);
     913          12 :    if(this_release)
     914             :    {
     915           8 :       cJSON_Delete(this_release);
     916           8 :       debug ("cJSON_delete releases OK\n");
     917           8 :       this_release=NULL;
     918             :    }
     919          12 :    if(releases)
     920             :    {
     921           7 :       cJSON_Delete(releases);
     922           7 :       debug ("cJSON_delete releases OK\n");
     923           7 :       releases=NULL;
     924             :    }
     925          12 :    update_details(trace);
     926             : 
     927             :    // symlink css/js/fonts/bootstrap etc for baseHREF
     928             :    // TODO should check if no .LAYOUT before symlinking
     929          12 :    if (!exitcode )
     930             :    {
     931           8 :       newarg[0]="/bin/sh";
     932           8 :       newarg[1]="-c";
     933           8 :       newarg[2]=(char *)var_arg1_string;
     934           8 :       sprintf((char *)newarg[2],"/bin/ln -sf %s/deploy/config/html_deploy/* %s/public/",param->prefix,basePATH );
     935           8 :       newarg[3]=NULL;
     936           8 :       Write_dyn_trace_pad(trace, none,75,"+ symlink webapp to /");
     937           8 :       debug("cmd:  %s %s %s \n",newarg[0],newarg[1],newarg[2]);
     938           8 :       exitcode=cmd_exec(opaque);
     939           8 :       if (exitcode){
     940           0 :         Write_dyn_trace(trace, red,"[FAIL]\n");
     941           0 :         debug("Failed create webapp symlink %s",newarg[2]);
     942             :      }
     943             :      else
     944             :      {
     945           8 :        Write_dyn_trace(trace, green,"[OK]\n");
     946             :      }
     947           8 :       update_details(trace);
     948             :         }
     949             :    // symlink index.html for the tag release
     950          12 :    if (!exitcode && deploy_production)
     951             :    {
     952           7 :       newarg[0]="/bin/sh";
     953           7 :       newarg[1]="-c";
     954           7 :       newarg[2]=(char *)var_arg1_string;
     955           7 :       sprintf((char *)newarg[2],"/bin/ln -sf %s/deploy/config/html_deploy/index.html %s/",param->prefix,tagPATH );
     956           7 :       newarg[3]=NULL;
     957           7 :       Write_dyn_trace_pad(trace, none,75,"+ symlink index.html to /%s",build_ref_slug);
     958           7 :       debug("cmd:  %s %s %s \n",newarg[0],newarg[1],newarg[2]);
     959           7 :       exitcode=cmd_exec(opaque);
     960           7 :       if (exitcode){
     961           0 :         Write_dyn_trace(trace, red,"[FAIL]\n");
     962           0 :         debug("Failed create symlink %s\n",newarg[2]);
     963             :      }
     964             :      else
     965             :      {
     966           7 :        Write_dyn_trace(trace, green,"[OK]\n");
     967             :      }
     968           7 :       update_details(trace);
     969             :    }
     970             :   // create release badge on a clean_tag ( no beta or RC or test ...)
     971          12 :    if (!exitcode && deploy_production && clean_tag)
     972             :    {
     973           5 :                 debug("\n create badge\n");
     974             :         // Create the svg badge release on top level
     975           5 :                 char * svg_out=NULL;
     976           5 :       if (cJSON_GetObjectItem(env_json, "CI_COMMIT_TAG"))
     977             :       {
     978           5 :            make_svg_badge("Release", cJSON_get_key(env_json, "CI_COMMIT_TAG"),&svg_out);
     979             :       /* NO deploy release without TAG
     980             :       else
     981             :       {
     982             :          char commit_short[10];
     983             :          sprintf(commit_short,"%.*s",8,cJSON_get_key(env_json, "CI_COMMIT_SHA"));
     984             :           make_svg_badge("Commit", commit_short,&svg_out);
     985             :       } */
     986             : 
     987             :       }
     988           5 :       if (svg_out)
     989             :       {
     990           5 :          newarg[0]="write_file";
     991           5 :          newarg[1]=(char *)var_arg1_string;
     992           5 :          sprintf((char *)newarg[1],"%s/public/tag.svg",basePATH);
     993           5 :          newarg[2]=svg_out;
     994           5 :          newarg[3]=NULL;
     995           5 :          Write_dyn_trace_pad(trace, none,75,"+ write public/tag.svg");
     996             : 
     997           5 :          exitcode=cmd_write(opaque);
     998           5 :          if (!exitcode) { debug("wrote %s, %d bytes\n",newarg[1],strlen(svg_out));}
     999           5 :          if (exitcode){
    1000           0 :            Write_dyn_trace(trace, red,"[FAIL]\n");
    1001             :         }
    1002             :         else
    1003             :         {
    1004           5 :           Write_dyn_trace(trace, green,"[OK]\n");
    1005             :         }
    1006           5 :          free(svg_out);
    1007           5 :          svg_out=NULL;
    1008             :       }
    1009             :       else
    1010           0 :       {Write_dyn_trace(trace, red,"\n- Failed creating svg release tag\n"); debug("Failed making svg release tag\n"); }
    1011           5 :       update_details(trace);
    1012             :    }
    1013             :    // symlink latest to this release, only on clean tag
    1014          12 :    if (!exitcode && deploy_production && clean_tag )
    1015             :    {
    1016             :       // ln -sf tag latest
    1017           5 :       newarg[0]="/bin/ln";
    1018           5 :       newarg[1]="-sf";
    1019           5 :       newarg[2]=(char *)var_arg1_string;
    1020           5 :       sprintf((char *)newarg[2],"%s",tagPATH);
    1021           5 :       newarg[3]=(char *)var_arg2_string;
    1022           5 :       sprintf((char *)newarg[3],"%s/public/latest",basePATH);
    1023           5 :       newarg[4]=NULL;
    1024           5 :       Write_dyn_trace_pad(trace, none,75,"+ symlink latest");
    1025             : 
    1026           5 :       int thiserror=0;
    1027             :       // unlink, only throw error on none existing file
    1028           5 :       if (unlink (newarg[3])!=0 && (thiserror=errno)!=ENOENT) sock_error_no("unlink sysmlink latest",thiserror);
    1029           5 :       exitcode=cmd_exec(opaque);
    1030           5 :       if (exitcode){
    1031           0 :         Write_dyn_trace(trace, red,"[FAIL]\n");
    1032           0 :         debug("Failed ln -sf %s %s\n",newarg[2],newarg[3]);
    1033           0 :         return exitcode;
    1034             :       }
    1035           5 :                 else {debug("ln -sf %s %s\n",newarg[2],newarg[3]);Write_dyn_trace(trace, green,"[OK]\n");}
    1036             :    }
    1037             :    // write public/latest.tag, contains latest tag info
    1038          12 :    if (!exitcode && deploy_production && clean_tag )
    1039             :    {
    1040           5 :       char * tag=cJSON_get_key(env_json, "CI_COMMIT_TAG");
    1041           5 :       newarg[0]="write_file";
    1042           5 :       newarg[1]=(char *)var_arg1_string;
    1043           5 :       sprintf((char *)newarg[1],"%s/public/latest.tag",basePATH);
    1044           5 :       newarg[2]= tag;
    1045           5 :       newarg[3]=NULL;
    1046           5 :       Write_dyn_trace_pad(trace, none,75,"+ write public/latest.tag");
    1047             : 
    1048           5 :       exitcode=cmd_write(opaque);
    1049           5 :       if (!exitcode)
    1050           5 :         Write_dyn_trace(trace, green,"[OK]\n");
    1051             :       else
    1052           0 :         Write_dyn_trace(trace, red,"[FAILED]\n");
    1053             : 
    1054           5 :       if (!exitcode) { debug("wrote %s => %s\n",newarg[1],newarg[2]);}
    1055             :    }
    1056          12 :    update_details(trace);
    1057          12 :    if (!exitcode && deploy_production && validate_key(env_json, "DEPLOY_CONFIG_HTTPS","True" )==0)
    1058             :    {
    1059             :       //config https
    1060             : 
    1061           0 :       debug("start letsencript\n");
    1062             :       // check if letsencript config exists, if not create new cert
    1063           0 :       exitcode=letsencrypt(opaque,cJSON_get_key(env_json, "DEPLOY_DOMAIN"),cJSON_get_key(env_json, "GITLAB_USER_EMAIL"));
    1064             :       // write https
    1065           0 :       if (!exitcode)
    1066             :       {
    1067           0 :          exitcode= write_http_config(opaque,1,basePATH,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
    1068           0 :          if (exitcode){debug("Failed create http config\n");return exitcode;}
    1069           0 :          exitcode=  verify_http_config(opaque);
    1070           0 :          if (exitcode)
    1071             :          {
    1072           0 :             debug("Failed nginx -t \n");
    1073           0 :             delete_http_config(opaque,basePATH);
    1074             : 
    1075           0 :             return exitcode;
    1076             :          }
    1077           0 :          else exitcode=reload_http_config(opaque);
    1078             :       }
    1079           0 :       else debug("ERR: let's encrypt failed\n");
    1080           0 :       update_details(trace);
    1081             : 
    1082             :    }
    1083          12 :    update_details(trace);
    1084          12 :    return exitcode;
    1085             : }
    1086             : 
    1087             : 
    1088             : /*
    1089             :  ---
    1090             :  projects:
    1091             :  - projecturl1
    1092             :  - projecturlb
    1093             : 
    1094             :  repos:
    1095             :    - rpm:
    1096             :      - el7:
    1097             :        - x86_64
    1098             :        - i386
    1099             :  - apt:
    1100             :  - test2: apt-test2
    1101             : 
    1102             :  */
    1103             : 
    1104             : /*------------------------------------------------------------------------
    1105             :  * Internal Command : rpm_init : filter the env, init rpm
    1106             :  *------------------------------------------------------------------------*/
    1107           0 : int cmd_repo_config(void * opaque)
    1108             : {
    1109             :    // feedback buffer
    1110           0 :    int exitcode=0;
    1111           0 :    struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
    1112             : 
    1113             :    // env json
    1114           0 :    cJSON * env_json=((data_exchange_t *)opaque)->env_json;
    1115             :    char * newarg[8];
    1116             :    // no need to set environment for individual commands
    1117           0 :    ((data_exchange_t *)opaque)->needenvp=0;
    1118           0 :    ((data_exchange_t *)opaque)->paramlist=(char **)newarg;
    1119           0 :    parameter_t * param=((data_exchange_t *)opaque)->parameters;
    1120             :    char var_arg1_string[1024];
    1121             :    char var_arg2_string[1024];
    1122             :    // char * var_dest_dir_string[1024];
    1123           0 :    int deploy_production=0;
    1124           0 :    debug("checking environment\n");
    1125             :    char basePATH[1024];
    1126             :    char baseHREF[1024];
    1127             :    char baseHREF_prod[1024];
    1128             : 
    1129             :    char repoNAME[1024];
    1130           0 :    int cnt=0;
    1131             : 
    1132           0 :    if ((cnt=check_presence(env_json,
    1133             :                            (char *[])
    1134           0 :                            {"CI_PROJECT_PATH_SLUG","CI_ENVIRONMENT_SLUG","CI_ENVIRONMENT_NAME","CI_PROJECT_PATH","CI_PROJECT_NAME","CI_PROJECT_DIR","CI_COMMIT_SHA","CI_COMMIT_REF_SLUG","CI_PROJECT_URL","CI_JOB_TOKEN","CI_PROJECT_ID",NULL}
    1135             :                            , trace)))
    1136             :    {
    1137           0 :       Write_dyn_trace(trace, none,"ERROR: %d Environment variable(s) Missing\n",cnt);
    1138           0 :       debug("\nERROR: %d Environment variable(s) Missing!!!\n",cnt);
    1139           0 :       exitcode=1;
    1140             :    }
    1141             :    else
    1142             :    {
    1143             :       // inform deployctl of environment deployment
    1144           0 :       debug("Deploy environment :%s\n",cJSON_get_key(env_json, "CI_ENVIRONMENT_NAME"));
    1145             :       //Write_dyn_trace(trace, none,"Deploy environment :%s\n",cJSON_GetObjectItem(env_json, "CI_ENVIRONMENT_NAME")->valuestring);
    1146           0 :       if (validate_key(env_json, "CI_ENVIRONMENT_NAME", "production")==0)
    1147             :       {
    1148           0 :          debug("RPM _config\n");
    1149           0 :          deploy_production=1;
    1150           0 :                 if (! cJSON_GetObjectItem(env_json, "DEPLOY_DOMAIN"))
    1151             :          { // we got no deploydomain, so make one
    1152             :             // as per : $CI_ENVIRONMENT_SLUG.$CI_PROJECT_PATH_SLUG.$DEPLOY_DOMAIN_APP
    1153             : 
    1154           0 :             debug("\nNo Deploy demain:\n");
    1155           0 :             if(validate_project_path_slug(env_json, trace, 1)!=0)
    1156             :             {
    1157           0 :                debug("no valid project path\n");
    1158           0 :                Write_dyn_trace(trace, none,"Environment not OK!! \n ** \"DEPLOY_DOMAIN\" and/or \"DEPLOY_APP_DOMAIN\" not defined ** \n");
    1159           0 :                exitcode=1;
    1160           0 :                return exitcode;
    1161             :             }
    1162             :             else
    1163             :             {
    1164           0 :                debug("extracting new domain\n");
    1165           0 :                char * env_slug=cJSON_get_key(env_json, "CI_ENVIRONMENT_SLUG");
    1166           0 :                char * project_path_slug=cJSON_get_key(env_json, "CI_PROJECT_PATH_SLUG");
    1167           0 :                char * deploy_app_domain=cJSON_get_key(env_json, "DEPLOY_DOMAIN_APP");
    1168             :                char deploy_domain[256];
    1169           0 :                sprintf(deploy_domain, "%s.%s.%s",env_slug,project_path_slug,deploy_app_domain);
    1170           0 :                debug("new domain %s\n",deploy_domain);
    1171           0 :                cJSON_AddItemToObject(env_json, "DEPLOY_DOMAIN", cJSON_CreateString(deploy_domain));
    1172             :             }
    1173             :          }
    1174           0 :          debug("building paths\n");
    1175           0 :          sprintf(baseHREF,"http://%s",cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
    1176             : 
    1177           0 :                  if (deploy_production && validate_key(env_json, "DEPLOY_CONFIG_HTTPS","True" )==0)
    1178           0 :                      sprintf(baseHREF_prod,"https://%s",cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
    1179             :                   else
    1180           0 :                          sprintf(baseHREF_prod,"http://%s",cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
    1181             : 
    1182             : 
    1183           0 :          sprintf((char *)basePATH,"%s/deploy/domain/%s",param->prefix,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
    1184           0 :          char * tmp=cJSON_get_key(env_json, "DEPLOY_REPO_NAME");
    1185           0 :          if (tmp && strlen(tmp)>0) sprintf(repoNAME,"%s",tmp); else sprintf(repoNAME,"%s",cJSON_get_key(env_json, "CI_PROJECT_NAME"));
    1186             : 
    1187             :       }
    1188             :       else
    1189             :       {
    1190             : 
    1191           0 :          Write_dyn_trace(trace, none,"ERROR: NOT a production deployment\n");
    1192           0 :          debug("\nERROR: NOT a production deployment\n");
    1193           0 :          exitcode=1;
    1194           0 :          return exitcode;
    1195             :       }
    1196             : 
    1197           0 :       debug("checking namespace\n");
    1198           0 :       if (check_namespace(opaque, basePATH)!=0)
    1199             :       {
    1200           0 :          Write_dyn_trace(trace, none,"ERR: Namespace belongs to another Project!! \n");
    1201           0 :          exitcode=1;
    1202           0 :          return exitcode;
    1203             :       }
    1204           0 :       debug("make the directory structure for rpm\n");
    1205             : 
    1206             :       //make the directory structure for rpm
    1207           0 :       newarg[0]="/bin/mkdir";
    1208           0 :       newarg[1]="-p";
    1209           0 :       newarg[2]=(char *)var_arg1_string;
    1210           0 :       sprintf((char *)newarg[2],"%s/public",basePATH);
    1211           0 :       newarg[3]=NULL;
    1212           0 :       Write_dyn_trace_pad(trace, none,75,"+ mkdir repo");
    1213             : 
    1214           0 :       debug("cmd: %s %s %s \n",newarg[0],newarg[1],newarg[2]);
    1215           0 :       exitcode=cmd_exec(opaque);
    1216             : 
    1217           0 :       if (exitcode)
    1218           0 :         Write_dyn_trace(trace, red,"[FAILED]\n");
    1219             :       else
    1220           0 :         Write_dyn_trace(trace, green,"[OK]\n");
    1221             : 
    1222           0 :       if (exitcode) {debug("Failed exec mkdir %s\n",newarg[2]);return exitcode;}
    1223             : 
    1224           0 :       exitcode= write_http_config(opaque,2,basePATH,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
    1225           0 :       if (exitcode){debug("Failed create http config\n");return exitcode;}
    1226           0 :       exitcode=  verify_http_config(opaque);
    1227           0 :       if (exitcode)
    1228             :       {
    1229           0 :          debug("Failed nginx -t \n");
    1230           0 :          delete_http_config(opaque,basePATH);
    1231             : 
    1232           0 :          return exitcode;
    1233             :       }
    1234           0 :       else exitcode=reload_http_config(opaque);
    1235             : 
    1236             :       // check if dns points to this instance for this url
    1237           0 :       if (!exitcode) exitcode= url_check(opaque, basePATH,baseHREF);
    1238           0 :       if (!exitcode)
    1239             :       {
    1240           0 :          exitcode=write_namespace(opaque, basePATH);
    1241           0 :          if (!exitcode) debug("Failed to write_namespace\n");
    1242             :       }
    1243             :       // read yalm_file
    1244           0 :       char * repo_file=NULL;
    1245           0 :       cJSON * repo_json=NULL;
    1246           0 :       repo_file =read_file(cJSON_get_key(env_json, "CI_PROJECT_DIR"), "repo.yaml");
    1247           0 :       if (!repo_file)
    1248             :       {
    1249           0 :          debug("Failed to get repofile \n");
    1250           0 :          exitcode=1;
    1251           0 :          return exitcode;
    1252             :       }
    1253           0 :       else debug("read repo.yaml ok\n");
    1254             :       // convert to json
    1255           0 :       repo_json= yaml_sting_2_cJSON (opaque ,repo_file);
    1256             :       // validate json
    1257           0 :       if (!repo_json)
    1258             :       {
    1259           0 :          debug("Failed to create cJSON from yaml  \n");
    1260           0 :          free(repo_file);
    1261           0 :          exitcode=1;
    1262           0 :          return exitcode;
    1263             :       }
    1264             :       else
    1265             :       {
    1266           0 :          debug(" got repo_json\n");
    1267             :       }
    1268             :       // returns an array of documents
    1269             :       // we only want first one
    1270           0 :       cJSON * temp=repo_json;
    1271           0 :       repo_json=cJSON_DetachItemFromArray(temp, 0);
    1272           0 :       cJSON_Delete(temp);
    1273             : 
    1274             :       // we need a minimun of projects and repos
    1275           0 :       if (check_presence(repo_json,(char *[]){"projects","repos",NULL}, trace)!=0)
    1276             :       {
    1277           0 :          Write_dyn_trace(trace, red,"ERROR: missing yaml entries\n");
    1278           0 :          debug("\nERROR: missing yaml entries\n");
    1279           0 :          if (repo_json) cJSON_Delete(repo_json);
    1280             :          exitcode=1;
    1281             :          return exitcode;
    1282             :       } else
    1283             :       {
    1284           0 :          debug("got correct yaml entries\n");
    1285             :       }
    1286             :             //create directory structure for rpm
    1287           0 :       cJSON * endpoints=NULL;
    1288           0 :       if (!exitcode )
    1289             :       {
    1290           0 :          endpoints = create_repo_dirs(opaque, basePATH , cJSON_GetObjectItem(repo_json, "repos"));
    1291             :       }
    1292             :       else
    1293             :       {
    1294           0 :          Write_dyn_trace(trace, none,"ERR: creating Repodirs\n");
    1295             : 
    1296           0 :          debug("ERR: creating Repodirs\n");
    1297             :       }
    1298           0 :        update_details(trace);
    1299             :       // read description.md, convert to html and add to repo.json
    1300           0 :            if (!exitcode && repo_json)
    1301             :            {
    1302           0 :                    char * tmp = read_file(cJSON_get_key(env_json, "CI_PROJECT_DIR"), "description.md");
    1303           0 :                    if (tmp)
    1304             :                    {
    1305           0 :                            char * tmp_html=NULL;
    1306           0 :                            char * sub_md=substitute_repo_script(tmp,repoNAME, baseHREF_prod, 0,0);
    1307           0 :                            if (sub_md)
    1308             :                            {
    1309           0 :                              tmp_html=html_body_release(sub_md);
    1310           0 :                                    free(sub_md);
    1311             :                            }
    1312             :                            else
    1313             :                            {
    1314           0 :                                         tmp_html=html_body_release(tmp);
    1315             :                            }
    1316           0 :                            free(tmp);
    1317           0 :                            if (tmp_html)
    1318             :                            {
    1319           0 :                                    cJSON_AddItemToObject(repo_json, "description",cJSON_CreateString(tmp_html));
    1320           0 :                                    free(tmp_html);
    1321             :                            }
    1322             :                    }
    1323             :            }
    1324             : 
    1325             :            //
    1326           0 :       if (!exitcode && repo_json )
    1327             :       {
    1328             :          // **** write repo.json and deployw_json.js
    1329           0 :          cJSON_AddItemToObject(repo_json, "endpoints",endpoints);
    1330           0 :          cJSON_AddItemToObject(repo_json, "base_path", cJSON_CreateString(basePATH));
    1331           0 :          cJSON_AddItemToObject(repo_json, "base_href", cJSON_CreateString(baseHREF_prod));
    1332           0 :          add_deploy_info_json(opaque,repo_json);
    1333             :          char filepath[1024];
    1334           0 :          char * repo_print=cJSON_Print(repo_json);
    1335           0 :          if (repo_print)
    1336             :          { // write it out
    1337           0 :            sprintf(filepath,"%s/public/repo.json",basePATH);
    1338           0 :            newarg[0]="write_file";
    1339           0 :            newarg[1]=(char *)filepath;
    1340           0 :            newarg[2]=repo_print;
    1341           0 :            newarg[3]=NULL;
    1342           0 :            debug("repo.json:==>\n%s\n\n",newarg[2]);
    1343           0 :            Write_dyn_trace_pad(trace, none,75,"+ write /repo.json");
    1344             : 
    1345           0 :            exitcode=cmd_write(opaque);
    1346           0 :            if (exitcode)
    1347           0 :              Write_dyn_trace(trace, red,"[FAILED]\n");
    1348             :            else
    1349           0 :              Write_dyn_trace(trace, green,"[OK]\n");
    1350             :          }
    1351           0 :          char * deployw_prt=NULL;
    1352           0 :          if (!exitcode && repo_print)
    1353             :          {
    1354             :             // convert to js variables
    1355           0 :             deployw_prt=create_repo_json_js (opaque, baseHREF_prod, repo_print);
    1356             :          }
    1357           0 :          if (!exitcode && deployw_prt)
    1358             :          { // wrtie deployw_json.js
    1359           0 :             sprintf(filepath,"%s/public/deployw_json.js",basePATH);
    1360           0 :             newarg[0]="write_file";
    1361           0 :             newarg[1]=(char *)filepath;
    1362           0 :             newarg[2]=deployw_prt;
    1363           0 :             newarg[3]=NULL;
    1364           0 :             debug("deployw_json_js:==>\n%s\n\n",newarg[2]);
    1365           0 :             Write_dyn_trace_pad(trace, none,75,"+ write /deployw_json_js");
    1366           0 :             exitcode=cmd_write(opaque);
    1367             :          }
    1368           0 :          if (deployw_prt) free(deployw_prt);
    1369           0 :          if (repo_print) free(repo_print);
    1370             : 
    1371           0 :          if (exitcode)
    1372             :          {
    1373           0 :             error("\nERR: writing json data\n");
    1374           0 :             Write_dyn_trace(trace, red,"[FAILED]\n");
    1375             :           }
    1376           0 :           else   Write_dyn_trace(trace, green,"[OK]\n");
    1377             :       }
    1378           0 :       update_details(trace);
    1379           0 :       if ( endpoints && !exitcode) exitcode=init_repo_dirs(opaque, basePATH, endpoints);
    1380             : 
    1381             :       //if (endpoints) cJSON_Delete(endpoints);
    1382             : 
    1383             : 
    1384             :       // symlink css/js/fonts/bootstrap etc for baseHREF
    1385             :       // TODO should check if no .LAYOUT before symlinking
    1386           0 :       if (!exitcode )
    1387             :       {
    1388           0 :          newarg[0]="/bin/sh";
    1389           0 :          newarg[1]="-c";
    1390           0 :          newarg[2]=(char *)var_arg1_string;
    1391           0 :          sprintf((char *)newarg[2],"/bin/ln -sf %s/deploy/config/html_deploy/* %s/public/",param->prefix,basePATH );
    1392           0 :          newarg[3]=NULL;
    1393           0 :          Write_dyn_trace_pad(trace, none,75,"+ symlink webapp to /");
    1394           0 :          debug("cmd:  %s %s %s \n",newarg[0],newarg[1],newarg[2]);
    1395           0 :          exitcode=cmd_exec(opaque);
    1396           0 :          if (exitcode)
    1397             :          {
    1398           0 :            Write_dyn_trace(trace, red,"[FAILED]\n");
    1399           0 :             debug("Failed create symlink %s",newarg[2]);
    1400             :           }
    1401           0 :          else  Write_dyn_trace(trace, green,"[OK]\n");
    1402             : 
    1403             :       }
    1404           0 :       if (!exitcode )
    1405             :       {
    1406           0 :          sprintf((char *)var_arg1_string,"%s/deploy/config/repo_conf/repo.rpm.sh",param->prefix );
    1407           0 :           sprintf((char *)var_arg2_string,"%s/public/repo.rpm.sh",basePATH );
    1408           0 :          Write_dyn_trace_pad(trace, none,75,"+ setup repo script rpm ... ");
    1409             : 
    1410           0 :          exitcode=copy_script_sh(opaque, var_arg1_string, var_arg2_string, repoNAME, baseHREF, 0,0);
    1411             :       }
    1412           0 :       if (!exitcode )
    1413             :       {
    1414             : 
    1415           0 :          sprintf((char *)var_arg1_string,"%s/deploy/config/repo_conf/repo.deb.sh",param->prefix );
    1416           0 :          sprintf((char *)var_arg2_string,"%s/public/repo.deb.sh",basePATH );
    1417           0 :          Write_dyn_trace_pad(trace, none,75,"+ setup repo script deb ... ");
    1418             : 
    1419           0 :          exitcode=copy_script_sh(opaque, var_arg1_string, var_arg2_string, repoNAME, baseHREF_prod, 0,0);
    1420             :       }
    1421             : 
    1422           0 :       if (repo_json) cJSON_Delete(repo_json);
    1423           0 :       update_details(trace);
    1424             : 
    1425           0 :       if (!exitcode && deploy_production && validate_key(env_json, "DEPLOY_CONFIG_HTTPS","True" )==0)
    1426             :       {
    1427             :          //config https
    1428             : 
    1429           0 :          debug("start letsencript\n");
    1430             :          // check if letsencript config exists, if not create new cert
    1431           0 :          exitcode=letsencrypt(opaque,cJSON_get_key(env_json, "DEPLOY_DOMAIN"),cJSON_get_key(env_json, "GITLAB_USER_EMAIL"));
    1432             :          // write https
    1433           0 :          if (!exitcode)
    1434             :          {
    1435           0 :             exitcode= write_http_config(opaque,3,basePATH,cJSON_get_key(env_json, "DEPLOY_DOMAIN"));
    1436           0 :             if (exitcode){debug("Failed create http config\n");return exitcode;}
    1437           0 :             exitcode=  verify_http_config(opaque);
    1438           0 :             if (exitcode)
    1439             :             {
    1440           0 :                debug("Failed nginx -t \n");
    1441           0 :                delete_http_config(opaque,basePATH);
    1442             : 
    1443           0 :                return exitcode;
    1444             :             }
    1445           0 :             else exitcode=reload_http_config(opaque);
    1446             :          }
    1447           0 :          else debug("ERR: let's encrypt failed\n");
    1448             : 
    1449             :       }
    1450             :    }
    1451           0 :    return exitcode;
    1452             : }
    1453             : 
    1454             : /*------------------------------------------------------------------------
    1455             :  * Internal Command : rpm_repo_add : add packages to the repo (rmp/deb)
    1456             :  *------------------------------------------------------------------------*/
    1457           0 : int cmd_repo_add(void * opaque)
    1458             : {
    1459             :    // feedback buffer
    1460           0 :    int exitcode=0;
    1461           0 :    struct trace_Struct *trace=((data_exchange_t *)opaque)->trace;
    1462             :    // env json
    1463           0 :    cJSON * env_json=((data_exchange_t *)opaque)->env_json;
    1464             :    char * newarg[8];
    1465             : 
    1466           0 :    ((data_exchange_t *)opaque)->needenvp=0;
    1467           0 :    ((data_exchange_t *)opaque)->paramlist=(char **)newarg;
    1468             : 
    1469           0 :    debug("checking environment\n");
    1470             :    char * basePATH;
    1471             :    char * baseHREF;
    1472           0 :    int cnt=0;
    1473             : 
    1474             :         // do we have minimun environment var's ?
    1475           0 :    if ((cnt=check_presence(env_json,
    1476           0 :                            (char *[]){"CI_PROJECT_DIR","CI_PROJECT_URL","DEPLOY_REPO_URL",NULL}
    1477             :                            , trace)))
    1478             :    {
    1479           0 :       Write_dyn_trace(trace, red,"ERROR: %d Environment variable(s) Missing\n",cnt);
    1480           0 :       debug("\nERROR: %d Environment variable(s) Missing!!!\n",cnt);
    1481           0 :       exitcode=1;
    1482           0 :            return exitcode;
    1483             :    }
    1484             : 
    1485           0 :         baseHREF=cJSON_get_key(env_json, "DEPLOY_REPO_URL");
    1486             : 
    1487             :         // get the repository config file
    1488             : 
    1489           0 :         cJSON * repos=NULL;
    1490           0 :         debug(" url repo\n");
    1491           0 :         Write_dyn_trace_pad(trace, none,75,"+ Getting repo config...");
    1492           0 :         exitcode=url_repo_base_path (&basePATH,baseHREF,trace);
    1493           0 :         if (!exitcode)
    1494             :         {
    1495           0 :                 Write_dyn_trace_pad(trace, none,75,"+ Reading repo config...");
    1496           0 :                 repos=read_json(opaque, basePATH,"/public","repo.json");
    1497             : 
    1498           0 :                 if (!repos)
    1499             :                 {
    1500           0 :                         Write_dyn_trace(trace, red,"[FAILED]\n  ERROR: could not read repo config\n");
    1501           0 :                         debug("\nERROR: could not read repo config\n");
    1502           0 :                         exitcode=1;
    1503             :                 }
    1504           0 :                 else Write_dyn_trace(trace, green,"[OK]\n");
    1505             :         }
    1506             :         else
    1507             :         {
    1508           0 :     Write_dyn_trace(trace, red,"[FAILED]\n  ERROR: could not accuire url base_path_url\n");
    1509           0 :                 debug("\nERROR: could get config request\n");
    1510           0 :                 exitcode=1;
    1511             :         }
    1512             : 
    1513             :         // verify the repo configuration
    1514           0 :         if (!exitcode)
    1515             :         {
    1516           0 :                 debug("checking validity of repo config\n");
    1517           0 :                 Write_dyn_trace_pad(trace, none,75,"+ Verify config...");
    1518           0 :                 if ((cnt=check_presence(repos,
    1519             :                                                                 (char *[])
    1520           0 :                                                                 {"projects","endpoints","base_path","base_href","repos",NULL}
    1521             :                                                                 , trace)))
    1522             :                 {
    1523           0 :                         Write_dyn_trace(trace, red,"ERROR: incomplete repo file in repository\n");
    1524           0 :                         debug("\nERROR: incomplete repo file in repository\n");
    1525           0 :                         exitcode=1;
    1526             :                 }
    1527           0 :                 else Write_dyn_trace(trace, green,"[OK]\n");
    1528             :         }
    1529             : 
    1530             :         // check if this project has access to this repository
    1531           0 :         if (!exitcode)
    1532             :         {
    1533           0 :                 debug("checking repo_access\n");
    1534           0 :                 Write_dyn_trace_pad(trace, none,75,"+ Checking access...");
    1535           0 :                 if (in_string_array(cJSON_GetObjectItem(repos, "projects"),cJSON_get_key(env_json, "CI_PROJECT_URL"))!=0)
    1536             :                 {
    1537           0 :                         Write_dyn_trace(trace, red,"\nERROR: access denied to this repo\n");
    1538           0 :                         debug("\nERROR: access denied\n");
    1539           0 :                         exitcode=1;
    1540             :                 }
    1541           0 :                 else Write_dyn_trace(trace, green,"[OK]\n");
    1542             :         }
    1543             : 
    1544             : 
    1545             :         // check if enviroment condition met!
    1546           0 :         debug("checking environment\n");
    1547           0 :         char * env_env=cJSON_get_key(env_json, "CI_ENVIRONMENT_NAME");
    1548           0 :         if ( cJSON_GetObjectItem(repos, "environments"))
    1549             :         {
    1550           0 :                 debug("environment list defined\n");
    1551             :                 //loop allowed environment list
    1552           0 :                 cJSON * pos=NULL;
    1553           0 :                 int found=0;
    1554           0 :                 cJSON_ArrayForEach(pos,cJSON_GetObjectItem(repos, "environments"))
    1555             :                 {
    1556           0 :                         char * test_item=pos->valuestring;
    1557           0 :                         debug("environment list item: %s\n",test_item);
    1558           0 :                         if (test_item && strcmp(test_item,"none")==0) {found=1; break;}
    1559           0 :                         if (test_item && env_env && strcmp(test_item,"all")==0) {found=1; break;}
    1560           0 :                         if (test_item && env_env && strcmp(test_item,"review/*")==0 && strncmp(env_env,"review/*",8)==0) {found=1; break;}
    1561           0 :                         if (test_item && env_env && strcmp(test_item,env_env)==0) {found=1; break;}
    1562             :                 }
    1563           0 :                 if (!found)
    1564             :                 {
    1565           0 :                 Write_dyn_trace(trace, red,"\n  ERROR: defined environment condition not met!\n");
    1566           0 :                 debug("\nERROR: defined environment condition not met!\n");
    1567           0 :                 if (repos) cJSON_Delete(repos);
    1568             :                 exitcode=1;
    1569             :                 return exitcode;
    1570             :                 }
    1571             :         }
    1572             :         else
    1573             :         {
    1574           0 :                 debug("no environment list defined\n");
    1575             :                 // no environment condition defined in repo.yaml, need to have production env
    1576           0 :                 if ( !env_env || strcmp(env_env,"production")!=0 )
    1577             :                 {
    1578           0 :                         Write_dyn_trace(trace, red,"ERROR: default 'production' environment not met!\n");
    1579           0 :                         debug("\nERROR: default 'production' environment not met!\n");
    1580           0 :                         if (repos) cJSON_Delete(repos);
    1581             :                         exitcode=1;
    1582             :                         return exitcode;
    1583             :                 }
    1584             :         }
    1585           0 :         debug("start deployment\n");
    1586             : 
    1587             :         // inform deployctl of environment deployment, if any
    1588           0 :         if (env_env)
    1589             :         {
    1590           0 :     Write_dyn_trace(trace, yellow,"  Deployment repo url:");
    1591           0 :     Write_dyn_trace(trace, cyan," %s\n",baseHREF);
    1592             :         }
    1593             : 
    1594             :         // Start
    1595           0 :         if (!exitcode)
    1596             :         {
    1597             :         // first read repository directories (rpm/deb) and get info on type,distribution and Arch/release (rpm/debian)
    1598           0 :                  cJSON * repo_list=NULL;
    1599             :       char repo_path_full[1024];
    1600           0 :        char * user_path=cJSON_GetArrayItem(cJSON_GetObjectItem(env_json, "DEPLOY_REPO_PATH"),0)->valuestring;
    1601           0 :       sprintf(repo_path_full, "%s%s",cJSON_get_key(env_json, "CI_PROJECT_DIR"),user_path);
    1602             : 
    1603           0 :                  get_repo_list(opaque,repo_path_full, &repo_list);
    1604             : 
    1605           0 :                  cJSON * matches=NULL;
    1606           0 :                  cJSON * skips=NULL;
    1607           0 :                  cJSON * symlinks=NULL;
    1608             : 
    1609             :                  // with the info, create matches and/or symlinks and/or skips
    1610           0 :                  if (repo_list)
    1611             :                  {
    1612           0 :                         match_end_points( opaque, repo_list,cJSON_GetObjectItem(repos, "endpoints"), &matches,&skips,&symlinks);
    1613           0 :                         cJSON_Delete(repo_list);
    1614           0 :                         repo_list=NULL;
    1615             :                  }
    1616           0 :      update_details(trace);
    1617           0 :       if (matches && cJSON_GetArraySize(matches)>0)
    1618             :       {
    1619             :                  // copy the matches in place
    1620           0 :      Write_dyn_trace(trace, yellow,"\n  Copy packages in place from: ");
    1621           0 :       Write_dyn_trace(trace, cyan,"%s/*\n",user_path);
    1622           0 :                  repo_copy_matches(opaque,matches,basePATH);
    1623           0 :      update_details(trace);
    1624             :       }
    1625             :                  // create symlinks for the wildcards
    1626           0 :       if (symlinks && cJSON_GetArraySize(symlinks)>0)
    1627             :       {
    1628           0 :                 Write_dyn_trace(trace, yellow,"\n  symlink wildcards in place...\n");
    1629           0 :                  repo_create_symlinks(opaque,symlinks,basePATH);
    1630           0 :      update_details(trace);
    1631             :       }
    1632             :                  // Inform User of problems
    1633           0 :                  if (skips && cJSON_GetArraySize(skips)>0)
    1634             :        {
    1635           0 :           repo_print_skips(opaque,skips);
    1636           0 :      update_details(trace);
    1637             :        }
    1638             :                  // update repos if something to update
    1639           0 :                  if (matches)
    1640             :      {
    1641           0 :        Write_dyn_trace(trace, yellow,"\n  Update repositories...\n");
    1642           0 :          update_repo_dirs(opaque, basePATH, cJSON_GetObjectItem(repos, "endpoints"));
    1643             :      }
    1644           0 :      update_details(trace);
    1645             :                  // cleanup
    1646           0 :                  if (repos) cJSON_Delete(repos);
    1647           0 :                  if (matches) cJSON_Delete(matches);
    1648           0 :                  if (symlinks) cJSON_Delete(symlinks);
    1649           0 :                  if (skips)  cJSON_Delete(skips);
    1650             :         }
    1651             : 
    1652           0 :    return exitcode;
    1653             : }

Generated by: LCOV version 1.10