Author: sebb
Date: Sat Jan 24 13:35:59 2026
New Revision: 1931504
Log:
Centralise Jira cred setup
Added:
comdev/reporter.apache.org/trunk/scripts/jira_auth.py (contents, props
changed)
Modified:
comdev/reporter.apache.org/trunk/Dockerfile
comdev/reporter.apache.org/trunk/compose.yml
comdev/reporter.apache.org/trunk/scripts/pdata.py
comdev/reporter.apache.org/trunk/scripts/readjira.py
comdev/reporter.apache.org/trunk/site/jiraversions.py
Modified: comdev/reporter.apache.org/trunk/Dockerfile
==============================================================================
--- comdev/reporter.apache.org/trunk/Dockerfile Sat Jan 24 13:01:40 2026
(r1931503)
+++ comdev/reporter.apache.org/trunk/Dockerfile Sat Jan 24 13:35:59 2026
(r1931504)
@@ -15,9 +15,6 @@ RUN echo "ServerName reporter.local" > /
COPY docker-config/25-reporter.conf /etc/apache2/sites-enabled/000-default.conf
-WORKDIR /usr/local/etc/tokens
-RUN touch /usr/local/etc/tokens/jira.txt
-
WORKDIR /var/www/reporter.apache.org
EXPOSE 80
Modified: comdev/reporter.apache.org/trunk/compose.yml
==============================================================================
--- comdev/reporter.apache.org/trunk/compose.yml Sat Jan 24 13:01:40
2026 (r1931503)
+++ comdev/reporter.apache.org/trunk/compose.yml Sat Jan 24 13:35:59
2026 (r1931504)
@@ -6,5 +6,8 @@ services:
volumes:
- .:/var/www/reporter.apache.org/
- ./docker-data/logs:/var/log/apache2
+ environment:
+ REPORTER_JIRA_USER: ${REPORTER_JIRA_USER:-githubbot}
+ REPORTER_JIRA_PASSWORD: ${REPORTER_JIRA_PASSWORD}
ports:
- 80:80
Added: comdev/reporter.apache.org/trunk/scripts/jira_auth.py
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ comdev/reporter.apache.org/trunk/scripts/jira_auth.py Sat Jan 24
13:35:59 2026 (r1931504)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+"""
+Common code for handling Jira authentication
+
+INITIAL RELEASE: include more common code later
+"""
+
+import os
+
+JIRA_USER = os.environ.get('REPORTER_JIRA_USER', 'githubbot')
+jirapass = os.environ.get('REPORTER_JIRA_PASSWORD', '')
+if jirapass == '':
+ with open("/usr/local/etc/tokens/jira.txt", "r", encoding='utf-8') as f:
+ jirapass = f.read().strip()
+if jirapass == '':
+ raise RuntimeError("Jira password cannot be empty")
+JIRA_PASS = jirapass
Modified: comdev/reporter.apache.org/trunk/scripts/pdata.py
==============================================================================
--- comdev/reporter.apache.org/trunk/scripts/pdata.py Sat Jan 24 13:01:40
2026 (r1931503)
+++ comdev/reporter.apache.org/trunk/scripts/pdata.py Sat Jan 24 13:35:59
2026 (r1931504)
@@ -29,6 +29,9 @@ CACHE_TIMEOUT = 7200
import committee_info
from urlutils import UrlCache
+sys.path.append(".") # module is in current directory
+import jira_auth
+
# This script may be called frequently, so don't just rely on IfNewer checks
uc = UrlCache(cachedir='../data/cache', interval=CACHE_TIMEOUT, silent=True)
@@ -62,10 +65,6 @@ ldapmap = {
'webservices': 'ws'
}
-jirapass = ""
-with open("/usr/local/etc/tokens/jira.txt", "r") as jf:
- jirapass = jf.read().strip()
-
def readJson(filename, *default):
"""Read a JSON file. If the read fails, return the default (if any)
otherwise return the exception"""
data = {}
@@ -125,9 +124,9 @@ def getJIRAProjects(project, tlpid):
x = readJson(RAOHOME+"data/JIRA/jira_projects.json")
else:
if sys.version_info >= (3, 0):
- base64string = base64.encodebytes(('%s:%s' % ('githubbot',
jirapass)).encode('ascii')).decode('ascii')[:-1]
+ base64string = base64.encodebytes(('%s:%s' %
(jira_auth.JIRA_USER,
jira_auth.JIRA_PASS)).encode('ascii')).decode('ascii')[:-1]
else:
- base64string = base64.encodebytes('%s:%s' % ('githubbot',
jirapass))[:-1]
+ base64string = base64.encodebytes('%s:%s' %
(jira_auth.JIRA_USER, jira_auth.JIRA_PASS))[:-1]
try:
x =
requests.get("https://issues.apache.org/jira/rest/api/2/project.json", headers
= {"Authorization": "Basic %s" % base64string}).json()
@@ -174,9 +173,9 @@ def getJIRAS(project):
pass
if refresh:
if sys.version_info >= (3, 0):
- base64string = base64.encodebytes(('%s:%s' % ('githubbot',
jirapass)).encode('ascii')).decode('ascii')[:-1]
+ base64string = base64.encodebytes(('%s:%s' % (jira_auth.JIRA_USER,
jira_auth.JIRA_PASS)).encode('ascii')).decode('ascii')[:-1]
else:
- base64string = base64.encodebytes('%s:%s' % ('githubbot',
jirapass))[:-1]
+ base64string = base64.encodebytes('%s:%s' % (jira_auth.JIRA_USER,
jira_auth.JIRA_PASS))[:-1]
try:
headers = {"Authorization": "Basic %s" % base64string}
req =
requests.get("""https://issues.apache.org/jira/rest/api/2/search?jql=project%20=%20'"""
+ project + """'%20AND%20created%20%3E=%20-91d""", headers = headers)
Modified: comdev/reporter.apache.org/trunk/scripts/readjira.py
==============================================================================
--- comdev/reporter.apache.org/trunk/scripts/readjira.py Sat Jan 24
13:01:40 2026 (r1931503)
+++ comdev/reporter.apache.org/trunk/scripts/readjira.py Sat Jan 24
13:35:59 2026 (r1931504)
@@ -21,6 +21,9 @@ from os import listdir
from os.path import isfile, join, dirname, abspath
from inspect import getsourcefile
+sys.path.append(".") # module is in current directory
+import jira_auth
+
# MYHOME = "/var/www/reporter.apache.org"
# Assume we are one directory below RAO (scripts)
MYHOME = dirname(dirname(abspath(getsourcefile(lambda:0)))) # automatically
work out home location so can run the code anywhere
@@ -36,11 +39,6 @@ mypath = "%s/data/JIRA" % MYHOME
print("Scanning mypath=%s" % mypath)
myfiles = [ f for f in listdir(mypath) if f.endswith(".json") and
isfile(join(mypath,f)) ]
-jirapass = ""
-with open("/usr/local/etc/tokens/jira.txt", "r") as f:
- jirapass = f.read().strip()
- f.close()
-
JIRA_SLEEP = 0.5 # how long to wait between API requests
JIRATIMEOUT=90 # This may need to be adjusted
jiraerrors = 0 # count how many consecutive errors occurred
@@ -56,7 +54,7 @@ def handleError():
def getCookie():
hdrs = {"content-type": "application/json"}
- data = {"username": "githubbot", "password": jirapass } # needs to be JSON
+ data = {"username": jira_auth.JIRA_USER, "password": jira_auth.JIRA_PASS }
# needs to be JSON
res = requests.post(JIRA_AUTH, headers=hdrs, json=data,
timeout=JIRATIMEOUT)
# Show more detail for login failures
if res.status_code in [401, 403]:
Modified: comdev/reporter.apache.org/trunk/site/jiraversions.py
==============================================================================
--- comdev/reporter.apache.org/trunk/site/jiraversions.py Sat Jan 24
13:01:40 2026 (r1931503)
+++ comdev/reporter.apache.org/trunk/site/jiraversions.py Sat Jan 24
13:35:59 2026 (r1931504)
@@ -10,6 +10,7 @@ import os, sys, json, urllib2, time, bas
sys.path.append("../scripts") # module is in sibling directory
import ldap_info
+import jira_auth
form = cgi.FieldStorage()
user = os.environ['HTTP_X_AUTHENTICATED_USER'] if 'HTTP_X_AUTHENTICATED_USER'
in os.environ else None
@@ -34,14 +35,10 @@ def getReleaseData(project):
except:
return {}
-jirapass = ""
-with open("/usr/local/etc/tokens/jira.txt", "r") as f:
- jirapass = f.read().strip()
-
# Do the cheapest checks first
if jiraname and user and (ldap_info.isMember(user) or project in
ldap_info.getPMCownership(user)):
jiraname = jiraname.upper()
- base64string = base64.encodestring('%s:%s' % ('githubbot', jirapass))[:-1]
+ base64string = base64.encodestring('%s:%s' % (jira_auth.JIRA_USER,
jira_auth.JIRA_PASS))[:-1]
try:
req =
urllib2.Request("https://issues.apache.org/jira/rest/api/2/project/%s/versions"
% jiraname)
req.add_header("Authorization", "Basic %s" % base64string)