Merge ~ubuntu-docker-images/ubuntu-docker-images/+git/utils:golang-manifest-builder into ~ubuntu-docker-images/ubuntu-docker-images/+git/utils:master

Proposed by Sergio Durigan Junior
Status: Merged
Merge reported by: Sergio Durigan Junior
Merged at revision: df901223aebbacd6741fd7f08a1bdb3ab18736b8
Proposed branch: ~ubuntu-docker-images/ubuntu-docker-images/+git/utils:golang-manifest-builder
Merge into: ~ubuntu-docker-images/ubuntu-docker-images/+git/utils:master
Diff against target: 114 lines (+108/-0)
1 file modified
golang-manifest-builder.py (+108/-0)
Reviewer Review Type Date Requested Status
Bryce Harrington Approve
Lucas Kanashiro Pending
Canonical Server Pending
Review via email: mp+398384@code.launchpad.net

Description of the change

This is the manifest builder script that I've been working on. It's ready to go into production, and Emilia from the security team has given her ACK.

To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Overal LGTM, just a minor question for one potentially unchecked error path.

Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

Thanks for the review, Christian.

Revision history for this message
Bryce Harrington (bryce) wrote :

A few super minor suggestions below but otherwise LGTM, and looks like Christian's question has been answered.

review: Approve
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

Thanks, Bryce. I've addressed your comments and merged the branch.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/golang-manifest-builder.py b/golang-manifest-builder.py
2new file mode 100755
3index 0000000..583f1c6
4--- /dev/null
5+++ b/golang-manifest-builder.py
6@@ -0,0 +1,108 @@
7+#!/usr/bin/env python3
8+
9+# This Python script can be used to generate a security manifest file
10+# from a list of Golang modules, that can be obtained with (e.g.):
11+#
12+# $ "go list -m all"
13+#
14+# The code has been written to be used with the telegraf and the
15+# cortex OCI images in mind, so it is heavily tweaked to work with the
16+# module list generated by these two packages.
17+#
18+# The idea is to use the information provided by pkg.go.dev and obtain
19+# the git repository URL for each module. Unfortunately, pkg.go.dev
20+# does not offer an API, so we have to download the webpages and
21+# scrape them.
22+
23+# Author: Sergio Durigan Junior <sergio.durigan@canonical.com>
24+
25+from lxml import html
26+import requests
27+import os
28+import sys
29+
30+# This script requires one argument, which is filename containing the
31+# list of modules to be processed.
32+if len (sys.argv) != 2:
33+ print ("E: You must provide the filename containing the list of modules.",
34+ file = sys.stderr)
35+ sys.exit (1)
36+
37+# A dictionary that maps a Golang module name to a git tag prefix that
38+# is used by the upstream.
39+#
40+# This is needed because some upstreams develop and release several
41+# Golang modules from a single git repository, and, in order to
42+# properly differentiate the release tags for each of these modules,
43+# they use a "namespaced" (prefixed) tag. Unfortunately, though, this
44+# information is not present in the pkg.go.dev page, so we have to
45+# keep a manual list here.
46+TAG_PREFIX = {
47+ "cloud.google.com/go/pubsub" : "pubsub/",
48+ "cloud.google.com/go/bigquery" : "bigquery/",
49+ "cloud.google.com/go/datastore" : "datastorage/",
50+ "cloud.google.com/go/storage" : "storage/",
51+ "cloud.google.com/go/bigtable" : "bigtable/",
52+
53+ "github.com/Azure/go-autorest/autorest" : "autorest/",
54+ "github.com/Azure/go-autorest/autorest/adal" : "autorest/adal/",
55+ "github.com/Azure/go-autorest/autorest/azure/auth" : "autorest/azure/auth/",
56+ "github.com/Azure/go-autorest/autorest/azure/cli" : "autorest/azure/cli/",
57+ "github.com/Azure/go-autorest/autorest/date" : "autorest/date/",
58+ "github.com/Azure/go-autorest/autorest/to" : "autorest/to/",
59+ "github.com/Azure/go-autorest/autorest/mocks" : "autorest/mocks/",
60+ "github.com/Azure/go-autorest/autorest/validation" : "autorest/validation",
61+ "github.com/Azure/go-autorest/logger" : "logger/",
62+ "github.com/Azure/go-autorest/tracing" : "tracing/",
63+
64+ "github.com/hashicorp/consul/api" : "api/",
65+ "github.com/hashicorp/consul/sdk" : "sdk/",
66+
67+ "go.elastic.co/apm/module/apmhttp" : "module/apmhttp/",
68+ "go.elastic.co/apm/module/apmot" : "module/apmot/",
69+ }
70+
71+with open(sys.argv[1], 'r') as f:
72+ for line in f.readlines ():
73+ # Grab the name and version of each module.
74+ modinfo = line.split (' ')
75+ modinfo[0] = modinfo[0].lstrip ().rstrip ().replace ('\n', '')
76+ modinfo[1] = modinfo[1].lstrip ().rstrip ().replace ('\n', '')
77+
78+ # Grab the page. We offer a retry mechanism in case of
79+ # failure.
80+ attempts = 0
81+ while True:
82+ page = requests.get ('https://pkg.go.dev/{}'.format (modinfo[0]))
83+ tree = html.fromstring (page.content)
84+
85+ try:
86+ repo = tree.xpath ('//div[@class="UnitMeta"]/a/text()')[0].replace ('\n', '').lstrip ().rstrip ()
87+ except IndexError:
88+ attempts = attempts + 1
89+ if attempts < 3:
90+ continue
91+
92+ print ("E: Unable to obtain information for module '{}'".format (modinfo[0]),
93+ file = sys.stderr)
94+
95+ if sys.stdin.isatty ():
96+ print ("Would you like to retry? (Y/n) ",
97+ file = sys.stderr, end = '')
98+ retry = input ()
99+ if retry == 'n':
100+ break
101+ continue
102+ else:
103+ # If the input is not coming from a tty, it likely
104+ # means we're building on docker/LP or some such.
105+ # In this case, we want to fail so that the user
106+ # can retry the whole build.
107+ sys.exit (1)
108+ break
109+
110+ # Do we need to adjust the tag?
111+ if modinfo[0] in TAG_PREFIX.keys ():
112+ modinfo[1] = "{}{}".format (TAG_PREFIX[modinfo[0]], modinfo[1])
113+
114+ print ("{},{}".format (repo, modinfo[1]).replace ('\n', ''))

Subscribers

People subscribed via source and target branches

to all changes: