<?php
require_once(__DIR__ . '/../events.inc.php');
require_once(__DIR__ . '/core.inc.php');
require_once(__DIR__ . '/amazon.inc.php');
$rg_wh_cloud_functions = array(
'wh_cloud_send' => 'rg_wh_cloud_send',
'rg_wh_cloud_send_one' => 'rg_wh_cloud_send_one', // obsolete
'wh_cloud_send_one' => '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, $ev)
{
rg_prof_start('wh_cloud_send_one');
rg_log_ml('wh_cloud_send_one: event: ' . rg_array2string($ev));
$ret = FALSE;
$wh = &$ev['wh'];
$xid = rg_id(8);
$f = 'wh-' . $ev['ui_login']['uid'] . '-' . $wh['id']
. '-' . $xid . '.zip';
$path = rg_tmp_path($f, 120);
$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($ev['repo_path'], $ev['new_rev'],
$path, 'zip');
if ($r === FALSE) {
$last_output .= rg_git_error();
break;
}
// replace ##tags##
rg_wh_replace_tags($ev);
// 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['errmsg'];
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['errmsg'];
break;
}
$last_output .= $r['answer'];
}
$ret = array();
break;
}
@unlink($path);
rg_wh_set_last_output($db, $ev['ui_login']['uid'], $wh['id'],
substr($last_output, 0, 4096));
if (rg_debug()) {
$k = 'DEBUG::' . $ev['ui_login']['uid']
. '::webhooks::' . $wh['id'];
rg_log_debug('setting key [' . $k . '] to ' . $last_output);
rg_cache_set($k, $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, $ev)
{
rg_prof_start('wh_cloud_send');
rg_log_ml('wh_cloud_send: event: ' . rg_array2string($ev));
$ret = array();
// First, get the list of hooks
$r = rg_wh_list($db, $ev['ui_login']['uid']);
if ($r['ok'] != 1)
return FALSE;
$ev['source'] = 'wh_cloud_send';
// Filter
foreach ($r['list'] as $id => $wh) {
if (strcmp($wh['htype'], 'cloud') != 0)
continue;
if (strchr($wh['flags'], 'D')) {
rg_log_debug('hook is disabled');
continue;
}
// If the web hook does not contain our type, skip it
if (!strchr($wh['idata']['events'], $ev['wh_event'])) {
rg_log_debug($ev['wh_event']
. ' is not present in ['
. $wh['idata']['events'] . ']');
continue;
}
if (!rg_wh_repo_match($wh['repo'], $ev['ri']['name'])) {
rg_log('hook is not for this repo');
continue;
}
if (!rg_repo_compare_refs($wh['refname'], $ev['refname'])) {
rg_log('hook is not for this ref');
continue;
}
$x = $ev;
$x['category'] = 'wh_cloud_send_one';
$x['wh'] = $wh;
$ret[] = $x;
}
rg_prof_end('wh_cloud_send');
return $ret;
}
/*
* Some cosmetics applied to a webhook
*/
function rg_wh_cloud_cosmetic_pre(&$row)
{
rg_wh_amazon_cosmetic($row);
}
/*
* Some cosmetics applied to a webhook
*/
function rg_wh_cloud_cosmetic_post(&$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_pre($db, &$rg)
{
$a = $rg['wh']['idata'];
rg_wh_amazon_default_paras($a);
if (!isset($a['application_name']))
$a['application_name'] = '';
if (!isset($a['deployment_group_name']))
$a['deployment_group_name'] = '';
if (!isset($a['deployment_config_name']))
$a['deployment_config_name'] = '';
if (!isset($a['bucket']))
$a['bucket'] = '';
if (!isset($a['file']))
$a['file'] = '';
$rg['wh']['idata'] = $a;
}
/*
* Transfers to $rg the custom parameters - used when showing the form
*/
function rg_wh_cloud_add_form_post($db, &$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*/);
}
$info = array(
'htype' => 'cloud',
'description' => 'Stores your repo files into Amazon S3 and (optionally) does a CodeDeploy',
'cb' => array(
'cosmetic_pre' => 'rg_wh_cloud_cosmetic_pre',
'cosmetic_post' => 'rg_wh_cloud_cosmetic_post',
'fill_vars' => 'rg_wh_cloud_fill_vars',
'validate_vars' => 'rg_wh_cloud_validate_vars',
'add_form_pre' => 'rg_wh_cloud_add_form_pre',
'add_form_post' => 'rg_wh_cloud_add_form_post',
'fill_hints' => 'rg_wh_cloud_fill_hints',
),
'have_events' => FALSE,
'flags' => array(
'I' => 'Ignore application stop failures',
'c' => 'Skip the CodeDeploy step'
)
);
rg_wh_register_type('cloud', $info);
$cb = array();
rg_wh_register_subtype('cloud', 'generic', 'Generic', $cb);