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

Subscribers

People subscribed via source and target branches

to all changes: