Legoktm has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/328423 )
Change subject: Archive ...................................................................... Archive Change-Id: I79c7cd19a7e5474704396b38fb2236da66a4af3e --- D Gruntfile.js D LICENSE A OBSOLETE D README.md D config.yaml D config.yaml.sample D connections.yaml D fabfile.py D kubernetes-deployment.yaml D log_to_irc.py D package.json D src/colors.js D src/kick.bash D src/preprocess.js D src/relay.js D src/template.txt 16 files changed, 2 insertions(+), 923 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/labs/tools/grrrit refs/changes/23/328423/1 diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index bb08be4..0000000 --- a/Gruntfile.js +++ /dev/null @@ -1,16 +0,0 @@ -/*jshint node:true */ -module.exports = function(grunt) { - grunt.loadNpmTasks('grunt-contrib-jshint'); - - grunt.initConfig({ - jshint: { - options: { - jshintrc: true - }, - files: ['Gruntfile.js', 'src/*.js'] - }, - }); - - grunt.registerTask('test', 'jshint'); - grunt.registerTask('default', 'test'); -}; diff --git a/LICENSE b/LICENSE deleted file mode 100644 index e93da93..0000000 --- a/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - -Copyright (C) 2013 Yuvi Panda <yuvipa...@gmail.com> - -Everyone is permitted to copy and distribute verbatim or modified -copies of this license document, and changing it is allowed as long -as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/OBSOLETE b/OBSOLETE new file mode 100644 index 0000000..1f287d4 --- /dev/null +++ b/OBSOLETE @@ -0,0 +1,2 @@ +grrrit-wm was archived and subsumed by wikibugs. Please contribute to the +labs/tools/wikibugs2 repository on Gerrit instead. diff --git a/README.md b/README.md deleted file mode 100644 index ed312e1..0000000 --- a/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# lolrrit-wm - -lolrrit-wm is a simple IRC bot that listens to events from [gerrit][1] -and reports them on various IRC channels. Which repo changes report -to which channels can be configured in `config.yaml` - -## Config Changes ## - -To add more repo -> channel mappings, please edit `config.yaml`. The -repo names can be matched using regexps. The tool needs to be restarted -on SGE for the changes to take effect. Executing `kick.bash` will kill -the job and start it up again. - -## Logs ## - -There are somewhat comprehensive logs in the `~/logs` folder on toollabs. - -## Dependencies ## - -This is written with NodeJS, and has a few dependencies (which are all -bundled in the repo): - -1. underscore.js -2. node-irc -3. redis -4. swig -5. js-yaml - -## LICENSE ## - -Licensed under WTFPL. See the LICENSE file for more details. - -## CREDITS ## - -- Yuvi Panda -- AzaToth - -[1]: https://gerrit.wikimedia.org -[2]: http://tools.wmflabs.org diff --git a/config.yaml b/config.yaml deleted file mode 100644 index 4849e92..0000000 --- a/config.yaml +++ /dev/null @@ -1,205 +0,0 @@ -nick: grrrit-wm -server: irc.freenode.net -userName: lolrrit -realName: GRRRit the Terrible -default-channel: "#wikimedia-dev" -firehose-channel: "#mediawiki-feed" -blacklist: - L10n-bot - Jenkins-mwext-sync -channels: - "#mediawiki-i18n": - mediawiki/extensions/Babel: - mediawiki/extensions/CLDR: - mediawiki/extensions/ContentTranslation: - mediawiki/extensions/Translate: - mediawiki/extensions/TranslationNotifications: - mediawiki/extensions/TwnMainPage: - mediawiki/extensions/UniversalLanguageSelector: - mediawiki/services/cxserver: - mediawiki/services/cxserver/deploy: - translatewiki.*: - "#mediawiki-parsoid": - mediawiki/services/parsoid: - mediawiki/services/parsoid/deploy: - mediawiki/services/parsoid/node_modules: - mediawiki/extensions/Parsoid: - "#mediawiki-visualeditor": - mediawiki/extensions/Citoid: - mediawiki/extensions/TemplateData: - mediawiki/extensions/VisualEditor: - mediawiki/extensions/WikiEditor: - unicodejs: - VisualEditor/.*: - "#wikimedia-editing": - mediawiki/extensions/Cite$: - mediawiki/extensions/CiteThisPage: - mediawiki/extensions/CodeEditor: - mediawiki/extensions/Graph: - mediawiki/extensions/Kartographer: - mediawiki/extensions/Math: - mediawiki/extensions/ParserFunctions: - mediawiki/skins/apex: - mediawiki/skins/Vector: - oojs/.*: - # Also in #wikimedia-services - mediawiki/services/citoid: - mediawiki/services/graphoid: - mediawiki/services/mathoid: - "#wikimedia-interactive": - mediawiki/extensions/JsonConfig: - mediawiki/extensions/Graph: - mediawiki/extensions/Kartographer: - mediawiki/services/graphoid: - maps/.*: - mapdata: - "#pywikibot": - pywikipediabot.*: - pywikibot.*: - "#semantic-mediawiki": - mediawiki/extensions/PageForms: - mediawiki/extensions/Semantic.*: - mediawiki/extensions/SMW.*: - mediawiki/extensions/Ask: - mediawiki/extensions/Validator: - mediawiki/extensions/Maps: - mediawiki/extensions/RDFIO: - mediawiki/extensions/SolrStore: - "#wikimedia-ai": - mediawiki/extensions/ORES: - "#wikimedia-analytics": - analytics/.*: - "#wikimedia-perf": - performance.*: - "#wikimedia-dev": - # This is also sent to #wikimedia-ai - mediawiki/extensions/ORES: - # These are sent to #wikimedia-collaboration too - mediawiki/extensions/Echo: - mediawiki/extensions/Flow: - mediawiki/extensions/PageTriage: - mediawiki/extensions/Thanks: - # These are sent to #wikimedia-multimedia too - mediawiki/extensions/TimedMediaHandler.*: - mediawiki/extensions/PronunciationRecording: - # These are sent to #wikimedia-labs too - labs/tools/grrrit: - # These are sent to #wikipedia-en-ambassadors too - mediawiki/extensions/Campaigns: - mediawiki/extensions/EducationProgram: - # These are sent to #mediawiki-visualeditor too - mediawiki/extensions/WikiEditor: - # These are sent to #wikimedia-editing too - mediawiki/extensions/Cite$: - mediawiki/extensions/CiteThisPage: - mediawiki/extensions/CodeEditor: - mediawiki/extensions/Math: - mediawiki/extensions/ParserFunctions: - mediawiki/skins/Vector: - # These are sent to #brickimedia too - mediawiki/extensions/MediaWikiChat: - # Sent to #wikimedia-design as well - mediawiki/skins/Blueprint: - mediawiki/extensions/OOUIPlayground: - mediawiki/extensions/Popups: - oojs/oojs-ui: - # Sent to #wikimedia-codereview as well - mediawiki/core: - "#wikimedia-design": - mediawiki/skins/Blueprint: - mediawiki/extensions/OOUIPlayground: - mediawiki/extensions/Popups: - oojs/oojs-ui: - "#wikimedia-fundraising": - mediawiki/extensions/DonationInterface: - mediawiki/extensions/CentralNotice: - mediawiki/extensions/ContributionTracking: - mediawiki/extensions/ContributionReporting: - mediawiki/extensions/FundraiserLandingPage: - mediawiki/extensions/FundraiserStatistics: - mediawiki/extensions/FundraisingChart: - mediawiki/extensions/FundraisingEmailUnsubscribe: - mediawiki/extensions/FundraisingTranslateWorkflow: - mediawiki/extensions/LandingCheck: - wikimedia/fundraising/.*: - mediawiki/core: - branch: ^fundraising - "#wikimedia-collaboration": - mediawiki/extensions/Echo: - mediawiki/extensions/Flow: - mediawiki/extensions/MoodBar: - mediawiki/extensions/PageTriage: - mediawiki/extensions/Thanks: - mediawiki/extensions/WikiLove: - # This is sent to #wikimedia-mobile too. - mediawiki/extensions/Mantle: - "#wikimedia-labs": - labs/.*: - "#wikimedia-operations": - # Do not post betacluster stuff here - operations(?!/debs/wikistats).*: - branch: "^(?!betacluster)" - wikimedia/bugzilla/modifications: - wikimedia/bots/jouncebot: - labs/private: - # This is sent to #wikimedia-releng too. - "#wikimedia-releng": - mediawiki/selenium: - mediawiki/ruby/.*: - integration/.*: - mediawiki/tools/codesniffer: - mediawiki/tools/code-utils: - mediawiki/tools/release: - mediawiki/tools/releng: - mediawiki/tools/scap: - # All commits to a betacluster branch goes here - .*: - branch: "betacluster" - "#wikidata-feed": - purtle: - data-values/.*: - mediawiki/extensions/Wikibase.*: - mediawiki/extensions/Wikidata.*: - mediawiki/extensions/DataTypes: - mediawiki/extensions/DataValues.*: - mediawiki/extensions/DataValueImplementations: - mediawiki/extensions/ValueView: - mediawiki/extensions/Capiunto: - mediawiki/extensions/ArticlePlaceholder: - mediawiki/extensions/WikimediaBadges: - wikidata/.*: - mediawiki/extensions/WikibaseLexeme: - "#wikimedia-de-tech": - analytics/wmde/.*: - mediawiki/extensions/Cognate: - mediawiki/extensions/TwoColConflict: - mediawiki/extensions/ElectronPdfService: - mediawiki/extensions/InterwikiSorting: - mediawiki/extensions/RevisionSlider: - "#wikimedia-multimedia": - mediawiki/extensions/CommonsMetadata.*: - mediawiki/extensions/UploadWizard.*: - mediawiki/extensions/TimedMediaHandler.*: - mediawiki/extensions/PronunciationRecording: - mediawiki/extensions/ImageMetrics: - mediawiki/extensions/FileAnnotations: - analytics/multimedia.*: - "#wikipedia-en-ambassadors": - mediawiki/extensions/Campaigns: - mediawiki/extensions/EducationProgram: - "#brickimedia": - mediawiki/extensions/MediaWikiChat: - "#wikimedia-services": - # Also in #wikimedia-editing - mediawiki/services/citoid: - mediawiki/services/graphoid: - mediawiki/services/mathoid: - mediawiki/services/rashomon: - mediawiki/services/restbase: - mediawiki/services/restbase/deploy: - mediawiki/services/service-runner: - mediawiki/services/service-template-node: - "#wikimedia-codereview": - mediawiki/core: - "##Zppix-Wikipedia": - labs/tools/zppixbot: \ No newline at end of file diff --git a/config.yaml.sample b/config.yaml.sample deleted file mode 100644 index a05ed1e..0000000 --- a/config.yaml.sample +++ /dev/null @@ -1,12 +0,0 @@ -nick: grrrit-wm -server: irc.freenode.net -userName: lolrrit -password: <secret> -realName: GRRRit the Terrible -default-channel: "#wikimedia-dev" -blacklist: - L10n-bot -channels: - "#wikimedia-labs": [ - "labs/.*" - ] diff --git a/connections.yaml b/connections.yaml deleted file mode 100644 index 9b11987..0000000 --- a/connections.yaml +++ /dev/null @@ -1,5 +0,0 @@ -gerrit: - host: gerrit.wikimedia.org - port: 29418 - username: suchabot - keypath: '/secret/ssh-key' diff --git a/fabfile.py b/fabfile.py deleted file mode 100644 index c0db553..0000000 --- a/fabfile.py +++ /dev/null @@ -1,53 +0,0 @@ -from io import StringIO -from fabric.api import * # noqa -from fabric.contrib.console import confirm - -tool_name = 'lolrrit-wm' - -env.hosts = ['tools-login.wmflabs.org'] -env.sudo_user = 'tools.{}'.format(tool_name) -env.sudo_prefix = 'sudo -ni ' -env.use_ssh_config = True - -home_dir = '/data/project/{}'.format(tool_name) -code_dir = '{}/lolrrit-wm'.format(home_dir) - -jsub = '/usr/bin/jsub' - -def irclog_deploy(message): - with cd(code_dir): - sudo('./log_to_irc.py "{}"'.format(message)) - -@task -def pull(): - with cd(code_dir): - sudo('git rev-list HEAD --max-count=1') - sudo('git fetch --all') - sudo('git reset --hard gerrit/master') - sudo('git cherry-pick auth') - sudo('git log --oneline -3') - -@task -def crontab(): - with cd(home_dir): - contents = StringIO(u"""# This crontab was auto-generated by Fabric -#m h dom mon dow cmd -""".format(**globals()) - ) - put(contents, 'crontab', mode=0o664) - sudo('crontab crontab') - -@task -def restart_job(): - sudo('qmod -rj lolrrit-wm') - -@task -def start_job(): - with cd(code_dir): - sudo('src/kick.bash') - -@task -def deploy(): - pull() - restart_job() - irclog_deploy('') diff --git a/kubernetes-deployment.yaml b/kubernetes-deployment.yaml deleted file mode 100644 index 2c4b291..0000000 --- a/kubernetes-deployment.yaml +++ /dev/null @@ -1,43 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - labels: - name: grrrit-wm - name: grrrit-wm - namespace: lolrrit-wm -spec: - replicas: 1 - selector: - matchLabels: - name: grrrit-wm - template: - metadata: - labels: - name: grrrit-wm - spec: - containers: - - command: - - /usr/bin/npm - - start - image: docker-registry.tools.wmflabs.org/toollabs-nodejs-base:latest - imagePullPolicy: Always - name: bot - workingDir: /data/project/lolrrit-wm/lolrrit-wm - env: - - name: HOME - value: /data/project/lolrrit-wm - resources: - limits: - cpu: "1" - memory: 2Gi - requests: - cpu: 125m - memory: 256Mi - volumeMounts: - - mountPath: /data/project/lolrrit-wm/ - name: home - restartPolicy: Always - volumes: - - hostPath: - path: /data/project/lolrrit-wm/ - name: home diff --git a/log_to_irc.py b/log_to_irc.py deleted file mode 100755 index c764d61..0000000 --- a/log_to_irc.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -import sys -import os -import requests -import subprocess -import yaml - -token = yaml.load(open('config.yaml'))['ircnotify-pass'] - -message = '!log {user} {sudo_user}: Deployed {rev} {msg}'.format( - user=os.environ['USER'], - sudo_user=os.environ['SUDO_USER'], - rev=subprocess.check_output(["git", "rev-list", "HEAD^", - "--max-count=1", "--format=oneline"] - ).decode('utf-8').strip(), - msg=' '.join(sys.argv[1:]) -) - -print(message) - -requests.post('http://ircnotifier-test-01/v1/send', data={ - 'token': token, - 'channels': '#wikimedia-labs', - 'message': message -}) diff --git a/package.json b/package.json deleted file mode 100644 index 70db6bf..0000000 --- a/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "grrrit", - "version": "0.2.0", - "description": "Gerrit IRC bot", - "main": "src/relay.js", - "dependencies": { - "irc": "~0.5", - "irc-colors": "~1.3.0", - "js-yaml": "^3.4.2", - "ssh2": "~0.5.3", - "swig-templates": "~2.0.2", - "underscore": "~1.8.3", - "winston": "~2.1.1" - }, - "devDependencies": { - "grunt": "^0.4.5", - "grunt-cli": "^0.1.13", - "grunt-contrib-jshint": "^0.11.3" - }, - "scripts": { - "start": "node src/relay.js", - "test": "js-yaml config.yaml; js-yaml config.yaml.sample; js-yaml connections.yaml.sample; grunt test;" - }, - "repository": { - "type": "git", - "url": "https://gerrit.wikimedia.org/r/labs/tools/grrrit" - }, - "author": "Yuvi Panda <yuvipa...@gmail.com>", - "license": "DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE", - "readmeFilename": "README.md", - "keywords": [ - "irc", - "gerrit" - ] -} diff --git a/src/colors.js b/src/colors.js deleted file mode 100644 index 2dfc7c5..0000000 --- a/src/colors.js +++ /dev/null @@ -1,14 +0,0 @@ -var irc_colors = require('irc-colors'); - -exports.color = function(text, colors) { - var _fun = irc_colors; - colors = colors.split('.'); - // irc-colors allows for linked colors, for example: - // irc_colors.bold.red.underline("blablabla") - for(var i = 0; i < colors.length; ++i) { - _fun = _fun[colors[i]]; - } - - var colorized = _fun(text); - return colorized; -}; diff --git a/src/kick.bash b/src/kick.bash deleted file mode 100755 index cf7348f..0000000 --- a/src/kick.bash +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# Stop current job if it exists, and start a new one -jstop lolrrit-wm -sleep 2s # Stupid hack to make sure the job is killed -jsub -l release=trusty -N lolrrit-wm -mem 1G -continuous node /data/project/lolrrit-wm/lolrrit-wm/src/relay.js diff --git a/src/preprocess.js b/src/preprocess.js deleted file mode 100644 index 955a62f..0000000 --- a/src/preprocess.js +++ /dev/null @@ -1,181 +0,0 @@ -/* Events should have the following data in them - * - * - type: new comment? patchset? merge? abandon? what? - * - user: Who did this? - * - link: Link to the Gerrit patchset - * - message: Generated message to display in quotes - * - repo: displayable name of the repository - * - branch: branch this was to, but on ly if it is not the default - * - flags: C & V, only if they changed - */ - -function filterNonDefault(branch) { - return (branch !== 'master' && branch !== 'production') ? branch : undefined; -} - -function formatRepo(repo) { - return repo.replace(/^mediawiki\//, '').replace(/^operations\//, ''); -} - -function extractBugNumber(commitMsg) { - var match = /^Bug:\s*(\d+)\s*$/m.exec(commitMsg); - if (match !== null && match[1]) { - return match[1]; - } -} - -function extractTaskNumber(commitMsg) { - var match = /^Bug:\s*(T\d+)\s*$/m.exec(commitMsg); - if (match !== null && match[1]) { - return match[1]; - } -} - -exports['patchset-created'] = function(message) { - var ret = { - type: 'PS' + message.patchSet.number, - user: message.uploader.name, - message: message.change.subject, - repo: formatRepo(message.change.project), - branch: filterNonDefault(message.change.branch), - url: message.change.url, - bug: extractBugNumber(message.change.commitMessage), - task: extractTaskNumber(message.change.commitMessage) - }; - if(ret.user === 'SuchABot') { - // Special handling for SuchABot - ret.user = message.patchSet.author.name; - ret.via = 'SuchABot'; - } else if(ret.user !== message.change.owner.name) { - ret.owner = message.change.owner.name; - } - return ret; -}; - -exports['draft-published'] = function(message) { - var ret = { - type: 'Draft' + message.patchSet.number, - user: message.uploader.name, - message: message.change.subject, - repo: formatRepo(message.change.project), - branch: filterNonDefault(message.change.branch), - url: message.change.url, - bug: extractBugNumber(message.change.commitMessage), - task: extractTaskNumber(message.change.commitMessage) - }; - if(ret.user !== message.change.owner.name) { - ret.owner = message.change.owner.name; - } - return ret; -}; - -exports['comment-added'] = function(message) { - var ret = { - type: 'CR', - user: message.author.name, - repo: formatRepo(message.change.project), - branch: filterNonDefault(message.change.branch), - url: message.change.url, - owner: message.change.owner.name, - bug: extractBugNumber(message.change.commitMessage), - task: extractTaskNumber(message.change.commitMessage) - }; - try { - var comment = "", - inlineCount; - - if (message.comment) { - inlineCount = message.comment.match(/(?:^|\s)\((\d+) comments?\)(?:$|\s)/); - comment = message.comment - // Strip out useless first line - .replace(/^\s*Patch Set \d+:.*$/m, '') - // Strip out count of inline comments - .replace(/^\s*\(\d+ comments?\)$/m, '') - .trim().split("\n")[0].trim(); - } - - if(comment) { - comment = '"' + comment.substring(0, 138) + '"'; - } else { - comment = message.change.subject.substring(0, 140); - } - if(inlineCount) { - ret.inlineComments = inlineCount[1]; - } - ret.message = comment; - if(message.approvals) { - ret.approvals = {}; - message.approvals.forEach(function(approval) { - if(approval.type === 'Verified') { - if(ret.user === 'jenkins-bot') { - ret.message = message.change.subject; - if(!ret.approvals || approval.value === "0" || approval.value > "0" ) { - // Don't relay jenkins-bot comments that don't add negative approvals - // Also don't add V+2 from jenkins bot, since it will merge right after - // Customize to relay other messages that might be useful - ret = undefined; - } else if (ret.approvals && approval.value === "-1") { - ret.approvals.V = approval.value; - } - } else if (approval.value !== "0") { - ret.approvals.V = approval.value; - } - } else if (approval.type === 'Code-Review' && approval.value !== "0") { - ret.approvals.C = approval.value; - } - if(approval.type === 'Verified' && approval.value === 0) { - ret.approvals.V = undefined; - } - if(approval.type === 'Code-Review' && approval.value === 0) { - ret.approvals.C = undefined; - } - }); - } - if(ret.user === 'jenkins-bot') { - ret.message = message.change.subject; - if(!ret.approvals || ret.approvals.V === 0 || ret.approvals.V > 0) { - // Don't relay jenkins-bot comments that don't add negative approvals - // Also don't add V+2 from jenkins bot, since it will merge right after - // Customize to relay other messages that might be useful - ret = undefined; - } else if (ret.approvals && ret.approvals.V === -1) { - ret.user = 'jerkins-bot'; - } - } - } catch(err) { - ret = undefined; - } - return ret; -}; - -// For Merge, Restore and Abandon -function formatSimpleEvent(type, userProperty) { - return function(message) { - return { - type: type, - user: message[userProperty].name, - message: message.change.subject, - repo: formatRepo(message.change.project), - branch: filterNonDefault(message.change.branch), - url: message.change.url, - owner: message.change.owner.name, - bug: extractBugNumber(message.change.commitMessage), - task: extractTaskNumber(message.change.commitMessage) - }; - }; -} - -exports['change-merged'] = function(message) { - var ret = formatSimpleEvent('Merged', 'submitter')(message); - // Ignore any merges by anyone that is not jenkins-bot - // This is always preceded by a C:2 by them, so we need not spam - // Jenkins bot will be ignored when merging L10n-bot patches - if( ( ret.user === 'jenkins-bot' && ret.owner === 'L10n-bot' ) || - ( ret.user !== 'jenkins-bot' ) ) { - ret = undefined; - } - return ret; -}; - -exports['change-restored'] = formatSimpleEvent('Restored', 'restorer'); -exports['change-abandoned'] = formatSimpleEvent('Abandoned', 'abandoner'); diff --git a/src/relay.js b/src/relay.js deleted file mode 100644 index 86781db..0000000 --- a/src/relay.js +++ /dev/null @@ -1,253 +0,0 @@ -/* jshint unused: vars */ -/*global startRelay */ - -var _ = require('underscore'), - irc = require('irc'), - swig = require('swig-templates'), - processors = require('./preprocess.js'), - fs = require('fs'), - path = require('path'), - yaml = require('js-yaml'), - logging = require('winston'), - ssh2 = require('ssh2'), - ircUp = false, - sshUp = false, - sshConn = null, - savedTo, - ircClient, - // Sane? defaults - config_defaults = { - nick: 'grrrit', - server: 'chat.freenode.net' - }; - -var config = yaml.safeLoad(fs.readFileSync(path.resolve(__dirname, '../config.yaml'), 'utf8')); -var conns = yaml.safeLoad(fs.readFileSync(path.resolve(__dirname, '../connections.yaml'), 'utf8')); - -_.defaults(config, config_defaults); - -function errorLog(message) { - logging.error(message); -} - -function bothConnected() { - if ( sshUp && ircUp && savedTo !== undefined ) { - ircClient.say( savedTo, "Successfully connected to IRC and SSH." ); - savedTo = undefined; - } -} - -function sshConnected( listener ) { - sshUp = true; - - logging.info('Connected to Gerrit via SSH; requesting stream-events'); - sshConn.exec('gerrit stream-events', function(err, stream) { - if (err) { - logging.error(err); - // TODO won't this log it twice? - throw err; - } - logging.info('Connected to event stream!'); - stream.on('data', function(data) { - listener(err, JSON.parse(data)); - }); - }); - - bothConnected(); -} - -function ircConnected( to ) { - ircUp = true; - savedTo = to; - - logging.info( 'Connected to IRC.' ); - - bothConnected(); -} - -function subscribeToGerritStream(host, port, username, keypath, listener) { - logging.info('Connecting to gerrit..'); - - sshConn = ssh2.Client(); - sshConn.on('ready', function() { - sshConnected( listener ); - }).on('error', function(err) { - sshUp = false; - logging.error('Client error: ' + err); - }).on('close', function() { - sshUp = false; - logging.info('SSH connection to Gerrit closed, reconnecting'); - startRelay(); - }).connect({ - host: host, - port: port, - username: username, - privateKey: require('fs').readFileSync(keypath), - }); -} - -var allChannels = _.keys(config.channels); - -if(allChannels.indexOf(config['default-channel']) === -1) { - allChannels.push(config['default-channel']); -} - -if(typeof config['firehose-channel'] !== "undefined" && allChannels.indexOf(config['firehose-channel']) === -1) { - allChannels.push(config['firehose-channel']); -} - -logging.info("joining channels", allChannels); - -function channelsForRepo(repo, branch) { - var channels = []; - _.each(config.channels, function(repos, channel) { - _.each(repos, function(repo_config, repo_candidate) { - if((new RegExp(repo_candidate)).test(repo)) { - if(!_.isEmpty(repo_config) && _.has(repo_config, 'branch')) { - // Test if specified regex matches current branch - if((new RegExp(repo_config.branch)).test(branch)) { - channels.push(channel); - } - } else { - channels.push(channel); - } - } - }); - }); - if(!channels.length) { - channels = [config['default-channel']]; - } - if(typeof config['firehose-channel'] !== "undefined") { - channels.push(config['firehose-channel']); - } - - // Make the list of channels unique - // and remove annoying duplicate messaging - return channels.filter(function(v, i) { return channels.indexOf(v) === i; }); -} - -swig.setFilter('color', require('./colors.js').color); -swig.setDefaults({ autoescape: false }); -var template = swig.compileFile(__dirname + '/template.txt'); - -ircClient = new irc.Client(config.server, config.nick, { - userName: config.userName, - realName: config.realName, - password: config.password, - port: 6697, - secure: true, - selfSigned: false, - certExpired: false, - channels: allChannels, - stripColors: false, - floodProtection: true -}); -ircClient.addListener('error', errorLog); - -function startRelay() { - - subscribeToGerritStream(conns.gerrit.host, conns.gerrit.port, conns.gerrit.username, conns.gerrit.keypath, function(err, message) { - if(err) { - logging.error("Caught error in doEcho: " + err); - startRelay(); - return; - } - - if(processors[message.type]) { - var msg = processors[message.type](message); - - if(msg) { - if(config.blacklist.indexOf(msg.user) === -1) { - var relayMsg = template(msg).replace(/\s+/gm, ' '); - var channels = channelsForRepo(message.change.project, message.change.branch); - _.each(channels, function(channel) { - ircClient.say(channel, relayMsg); - logging.info("Sent message from " + msg.repo + " to " + channel); - }); - } - } - } - }); -} - -var joinedChannels = []; -function waitForChannelJoins(channel, nick, message) { - logging.info(nick + " joined " + channel); - if(nick === ircClient.nick) { - joinedChannels.push(channel); - logging.info("Joined channel " + channel); - } - if(joinedChannels.length === allChannels.length) { - ircConnected(); - ircClient.removeListener('join', waitForChannelJoins); - logging.info("Joined " + joinedChannels.length + " channels. Connecting to Gerrit via SSH."); - startRelay(); - } -} -ircClient.addListener('join', waitForChannelJoins); -ircClient.addListener('message', function (from, to, text) { - var whitelist_cloaks = /^((mediawiki|wikimedia|wikipedia|wiktionary|wikiquote|wikisource|wikispecies|wikibooks|wikinews|wikiversity|wikivoyage|wikidata|wikimedia-commons)\/|fsf\/member\/marktraceur$)/g; - - ircClient.whois(from, function(info){ - try { - var from_trusted = info.host ? info.host.match(whitelist_cloaks) : false; - - if (text.indexOf(ircClient.nick + ': ' + 'restart') === 0) { - if (from_trusted) { - logging.debug(from + ' => ' + to + ' ' + text); - - if (sshConn) { - sshConn.end(); - logging.info('Disconnected SSH connection to Gerrit.'); - } - - ircClient.say(to, "Ended SSH connection to Gerrit."); - } else { - ircClient.say(to, "Permission is denied."); - } - } - - if (text.indexOf(ircClient.nick + ': ' + 'force-restart') === 0) { - if (from_trusted) { - logging.debug(from + ' => ' + to + ' ' + text); - - if (sshConn) { - sshConn.end(); - } - - ircClient.disconnect("Restarting IRC connection.", function () { - logging.info('Disconnected from IRC.'); - - ircClient.connect(function () { - ircConnected( to ); - }); - }); - } else { - ircClient.say(to, "Permission is denied."); - } - } - - if (text.indexOf(ircClient.nick + ': nick') === 0) { - if (!from_trusted) { - ircClient.say(to, "Permission is denied."); - } else { - logging.debug(from + ' => ' + to + ' ' + text); - - if (config.nick === ircClient.nick) { - logging.info( 'Ignoring no-op nick change request.' ); - } else { - ircClient.send('NICK', config.nick); - - logging.info('Changed nick to ' + config.nick); - } - } - } - - if (text.indexOf(ircClient.nick + ': help') === 0) { - ircClient.say(to, "My current commands are: " + ircClient.nick + ": restart" + ", " + ircClient.nick + ": force-restart" + ", " + " and " + ircClient.nick + ": nick"); - } - } catch (err) { - logging.error( "Error occurred when processing command. Details: " + err ); - } - }); -}); diff --git a/src/template.txt b/src/template.txt deleted file mode 100644 index 92aece2..0000000 --- a/src/template.txt +++ /dev/null @@ -1,24 +0,0 @@ -({{type|color('green')}}) {{user|color('bold.teal')}}: - {% if approvals -%} - [{%- for value in approvals -%} - {%- if value == "1" -%} - {{loop.key}}: {{value|color('green')}}{% if not loop.last %} {% endif -%} - {%- elseif value == "2" -%} - {{loop.key}}: {{value|color('bold.green')}}{% if not loop.last %} {% endif -%} - {%- elseif value == "-1" -%} - {{loop.key}}: {{value|color('red')}}{% if not loop.last %} {% endif -%} - {%- else -%} - {{loop.key}}: {{value|color('bold.red')}}{% if not loop.last %} {% endif -%} - {%- endif -%} - {%- endfor -%}] - {% endif %} - {{message}} - {% if inlineComments -%} - ({{inlineComments|color('bold.green')}} comment{% if inlineComments > 1 %}s{% endif %}) - {% endif %} - [{{repo}}] - {% if branch %} ({{branch}}) {% endif %} - - {{url|color('teal')}} {% if bug %} (https://bugzilla.wikimedia.org/{{bug}}) {% endif %} - {% if task %} (https://phabricator.wikimedia.org/{{task}}) {% endif %} - {% if via %}(via {{via}}) {% endif %} - {% if owner %}(owner: {{ owner |color('bold.teal')}}){% endif %} -- To view, visit https://gerrit.wikimedia.org/r/328423 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I79c7cd19a7e5474704396b38fb2236da66a4af3e Gerrit-PatchSet: 1 Gerrit-Project: labs/tools/grrrit Gerrit-Branch: master Gerrit-Owner: Legoktm <lego...@member.fsf.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits