<?php require_once($INC . "/util.inc.php"); require_once($INC . "/log.inc.php"); require_once($INC . "/sql.inc.php"); require_once($INC . "/prof.inc.php"); require_once($INC . "/events.inc.php"); require_once($INC . "/wh/core.inc.php"); require_once($INC . "/wh/amazon.inc.php"); $rg_wh_cloud_functions = array( 'wh_cloud_send' => 'rg_wh_cloud_send', 20001 => 'rg_wh_cloud_send_one' ); rg_event_register_functions($rg_wh_cloud_functions); /* * Helper for rg_wh_cloud_send */ function rg_wh_cloud_send_one($db, $event) { rg_prof_start('wh_cloud_send_one'); rg_log_ml('wh_cloud_send_one: event: ' . print_r($event, TRUE)); $ret = FALSE; $wh = &$event['wh']; $xid = rg_id(8); $f = 'wh-' . $event['ui']['uid'] . '-' . $wh['id'] . '-' . $xid . '.zip'; $path = rg_tmp_path($f); $last_output = ''; while (1) { // TODO: cache the output? // generate archive (TODO: specify branch) // TODO: the id of the commit should be passed to the hook, else another // push will "destroy" the reference. $r = rg_git_archive($event['repo_path'], $event['new_rev'], $path, 'zip'); if ($r === FALSE) { $last_output .= rg_git_error(); break; } // replace ##tags## rg_wh_replace_tags($event); // store to s3 $wh['idata']['content_type'] = 'application/zip'; // we need to copy 'flags' because we pass idata $wh['idata']['flags'] = $wh['flags']; $c = @file_get_contents($path); if ($c === FALSE) { $last_output .= 'missing archive; very strange!'; break; } $r = rg_amazon_s3_put_object($wh['idata'], $c); if ($r['ok'] != 1) { $last_output .= $r['error']; break; } $last_output .= $r['answer']; // c = skip the CodeDeploy step if (!strchr($wh['flags'], 'c')) { // Do the code deploy $r = rg_amazon_codedeploy_create($wh['idata']); if ($r['ok'] != 1) { $last_output .= $r['error']; break; } $last_output .= $r['answer']; } $ret = array(); break; } @unlink($path); rg_wh_set_last_output($db, $event['ui']['uid'], $wh['id'], substr($last_output, 0, 4096)); if ($wh['idata']['debug'] == 1) rg_cache_set('DEBUG::' . $event['ui']['uid'] . '::webhooks::' . $wh['id'], $last_output, RG_SOCKET_NO_WAIT); rg_prof_end('wh_cloud_send_one'); return $ret; } /* * Generic function which will be called when a webhook must be posted */ function rg_wh_cloud_send($db, $event) { rg_prof_start('wh_cloud_send'); rg_log_ml('wh_cloud_send: event: ' . print_r($event, TRUE)); $ret = array(); // First, get the list of hooks $r = rg_wh_list($db, $event['ui']['uid']); if ($r['ok'] != 1) return FALSE; // Filter foreach ($r['list'] as $id => $wh) { if (strcmp($wh['htype'], 'cloud') != 0) continue; // Diabled? if (strchr($wh['flags'], 'D')) continue; if (!rg_repo_compare_refs($wh['repo'], $event['ri']['name'])) { rg_log('hook is not for this ref'); continue; } if (!rg_repo_compare_refs($wh['refname'], $event['refname'])) { rg_log('hook is not for this ref'); continue; } $x = $event; $x['category'] = 20001; $x['wh'] = $wh; $x['debug'] = $wh['idata']['debug']; $ret[] = $x; } rg_prof_end('wh_cloud_send'); return $ret; } /* * Some cosmetics applied to a webhook */ function rg_wh_cloud_cosmetic(&$row) { rg_wh_amazon_cosmetic($row); $row['idata']['HTML:private'] = rg_template( 'user/settings/wh/cloud/show.html', $row['idata'], TRUE /*xss*/); } /* * Fill private data based on parameters passed */ function rg_wh_cloud_fill_vars(&$rg) { $a = &$rg['wh']['idata']; rg_wh_amazon_fill_vars($a); $a['application_name'] = trim(rg_var_str('wh::idata::application_name')); $a['deployment_group_name'] = trim(rg_var_str('wh::idata::deployment_group_name')); $a['deployment_config_name'] = trim(rg_var_str('wh::idata::deployment_config_name')); $a['bucket'] = trim(rg_var_str('wh::idata::bucket')); $a['file'] = trim(rg_var_str('wh::idata::file')); } /* * Validate parameters passed */ function rg_wh_cloud_validate_vars($rg, &$errmsg) { global $rg_wh_cloud_itypes; $a = $rg['wh']; $ret = FALSE; while (1) { if (!rg_wh_amazon_validate_vars($a['idata'], $errmsg)) break; if (empty($a['idata']['bucket'])) { $errmsg[] = rg_template('user/settings/wh/cloud/inv_bucket.txt', $rg, TRUE /*xss*/); break; } // c = skip the CodeDeploy step if (strchr($a['flags'], 'c')) { $ret = TRUE; break; } if (empty($a['idata']['application_name'])) { $errmsg[] = rg_template('user/settings/wh/cloud/inv_app_name.txt', $rg, TRUE /*xss*/); break; } if (empty($a['idata']['deployment_group_name'])) { $errmsg[] = rg_template('user/settings/wh/cloud/inv_group_name.txt', $rg, TRUE /*xss*/); break; } $ret = TRUE; break; } return $ret; } /* * Transfers to $rg the custom parameters - used when showing the form */ function rg_wh_cloud_add_form(&$rg) { $rg['HTML:custom_form'] = rg_template('user/settings/wh/cloud/form.html', $rg, TRUE /*xss*/); } /* * Add custom hints */ function rg_wh_cloud_fill_hints($rg, &$hints) { $hints[]['HTML:hint'] = rg_template('user/settings/wh/cloud/hints.html', $rg, TRUE /*xss*/); } /* * Loads default paras for a form */ function rg_wh_cloud_default_paras(&$rg) { $a = &$rg['wh']['idata']; rg_wh_amazon_default_paras($a); $a['application_name'] = ''; $a['deployment_group_name'] = ''; $a['deployment_config_name'] = ''; $a['bucket'] = ''; $a['file'] = ''; } $rg_wh_plugins['cloud'] = array( 'htype' => 'cloud', 'description' => 'Stores your repo files into Amazon S3 and (optionally) does a CodeDeploy', 'cosmetic' => 'rg_wh_cloud_cosmetic', 'fill_vars' => 'rg_wh_cloud_fill_vars', 'validate_vars' => 'rg_wh_cloud_validate_vars', 'add_form' => 'rg_wh_cloud_add_form', 'default_paras' => 'rg_wh_cloud_default_paras', 'fill_hints' => 'rg_wh_cloud_fill_hints', 'have_events' => FALSE, 'flags' => array( 'I' => 'Ignore application stop failures', 'c' => 'Skip the CodeDeploy step' ) ); ?>