- Virtualenv 20.13.0
- Python 3.10.12+
- beautifulsoup4 4.12.3
- Tested on Ubuntu 22.04 LTS
Let's call it dl-go.py.
import platform as pl
from bs4 import BeautifulSoup
import urllib.request as urlreq
import subprocess
import re
# Parse download page
page = urlreq.urlopen('https://go.dev/dl/')
soup = BeautifulSoup(page, features='html.parser')
# Get parent element of stable versions
stable_versions = soup.body.find('h2', attrs={'id':'stable'})
# Get next elements under the parent for stable versions
fnext = stable_versions.find_next()
y = fnext.find_all("tr", "")
# Get all stable versions
all_stable_versions = {}
for i in y:
td_find = i.find("td", "filename")
tt_find = i.find("tt")
if td_find != None and tt_find != None:
all_stable_versions[td_find.string] = tt_find.string
all_stable_versions_keys = list(all_stable_versions.keys())
# Getting the linux, mac and windows versions in a dict
stable_linux = {}
stable_mac = {}
stable_windows = {}
for key in all_stable_versions_keys:
if "linux" in key:
stable_linux[key] = all_stable_versions[key]
elif "darwin" in key:
stable_mac[key] = all_stable_versions[key]
elif "windows" in key:
stable_windows[key] = all_stable_versions[key]
else:
continue
# Get latest stable version
# https://stackoverflow.com/a/8955701
new_version = re.search('\d+(\.\d+){2,}',all_stable_versions_keys[0])
new_version = new_version.group(0)
# Get system and cpu info of host
# https://stackoverflow.com/a/7491509
plat = pl.platform().lower()
system = pl.system().lower()
cpu = pl.processor().lower()
if cpu == "x86_64":
cpu = "amd64"
# Get current installed go version
try:
installed_go = str(subprocess.run(['go', 'version'], check=True, text=True, capture_output=True).stdout)
except FileNotFoundError:
installed_go = "0.0.1"
installed_go_version = re.search('\d+(\.\d+){2,}',installed_go)
installed_go_version = installed_go_version.group(0)
print("Installed go version is: {0}".format(installed_go_version))
# Get latest stable filename for current system
file_to_dl = "go" + new_version + "." + system + "-" + cpu + ".tar.gz"
# Get download url for file
download_url = "https://go.dev/dl/" + file_to_dl
# Download tar.gz file
if installed_go_version == new_version:
print("Latest golang version installed.")
print("Program will terminate now.")
exit(0)
else:
print("There's a new golang version !")
print("Downloading {0}".format(file_to_dl))
urlreq.urlretrieve(download_url, file_to_dl)
# Get SHA256 hashkey from scraped data for downloaded file
if "linux" in file_to_dl:
hashkey = stable_linux[file_to_dl]
elif "darwin" in file_to_dl:
hashkey = stable_mac[file_to_dl]
elif "windows" in file_to_dl:
hashkey = stable_windows[file_to_dl]
# Get SHA256 hashkey from downloaded file
downloaded_hashkey = str(subprocess.run(['sha256sum', './{}'.format(file_to_dl)],
check=True, text=True, capture_output=True).stdout) \
.split(" ")[0]
# Compare SHA256 hashkeys
# If not the same, exit script with an error message
if hashkey == downloaded_hashkey:
print("Hashkey check: VALID")
else:
print("ERROR: Hashkey check: INVALID !")
print("Program will terminate now.")
exit(0)
# Removing old version
# rm -rf /usr/local/go (as root)
if installed_go_version == "0.0.1":
print("Golang not installed, skipping deletion")
else:
print("Removing /usr/local/go")
removed_output = str(subprocess.run(['rm', '-rf', '/usr/local/go'], check=True, text=True, capture_output=True).stdout)
print(removed_output)
# Installing new version
# tar -C /usr/local -xzf ./go1.22.6.linux-amd64.tar.gz (as root)
print("Installing {0} to /usr/local".format(file_to_dl))
installed_output = str(subprocess.run(['tar', '-C','/usr/local/','-xzf','./{0}'.format(file_to_dl)],
check=True, text=True, capture_output=True).stdout)
print(installed_output)
print("New version of golang is:")
go_version_output = str(subprocess.run(['go', 'version'], check=True, text=True, capture_output=True).stdout)
print(go_version_output)To test the above script build and run the following Dockerfile to test the scenario that you don't have golang installed:
FROM ubuntu:22.04
RUN apt-get update \
&& apt-get install -y python3 python3-pip wget tar
ADD dl-go.py .
RUN pip3 install beautifulsoup4
RUN mkdir -p /usr/local/
ENV PATH="$PATH:/usr/local/go/bin"
CMD ["python3","./dl-go.py"]Build:
docker build -t dl-go .Run:
docker run dl-goYou should get as output:
$ docker run dl-go
Installed go version is: 0.0.1
There's a new golang version !
Downloading go1.23.0.linux-amd64.tar.gz
Hashkey check: VALID
Golang not installed, skipping deletion
Installing go1.23.0.linux-amd64.tar.gz to /usr/local
New version of golang is:
go version go1.23.0 linux/amd64
Use the following Dockerfile:
FROM ubuntu:22.04
RUN apt-get update \
&& apt-get install -y python3 python3-pip wget tar
ADD dl-go.py .
RUN pip3 install beautifulsoup4
RUN mkdir -p /usr/local/ \
&& wget https://go.dev/dl/go1.22.4.linux-amd64.tar.gz \
&& tar -C /usr/local/ -xzf ./go1.22.4.linux-amd64.tar.gz
ENV PATH="$PATH:/usr/local/go/bin"
CMD ["python3","./dl-go.py"]Build and run as before.
You should get the following output:
Installed go version is: 1.22.4
There's a new golang version !
Downloading go1.23.0.linux-amd64.tar.gz
Hashkey check: VALID
Removing /usr/local/go
Installing go1.23.0.linux-amd64.tar.gz to /usr/local
New version of golang is:
go version go1.23.0 linux/amd64