Skip to content

Commit 8226e92

Browse files
authored
Merge pull request #76 from adobeethoshelloworld/ETHOS-39859
feat(ETHOS-39859): add support to update /etc/apt/sources.list
2 parents 249c9fa + d8840e6 commit 8226e92

File tree

12 files changed

+1761
-17
lines changed

12 files changed

+1761
-17
lines changed

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.PHONY: build-shunit2 shunit2
2+
3+
SHUNIT2_IMG ?= shunit2
4+
SHUNIT2_VERSION ?= 0.1.0
5+
6+
TAG_NAME=$(SHUNIT2_IMG):$(SHUNIT2_VERSION)
7+
8+
build-shunit2:
9+
cd tests/sh && docker build -t $(TAG_NAME) -f Dockerfile.shunit2 ../..
10+
11+
shunit2: build-shunit2
12+
docker run -it $(TAG_NAME)

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@ https://hub.docker.com/r/behance/docker-base/tags/
77

88
Provides base OS, security patches, and tools for quick and easy spinup.
99

10-
1110
### Variants
1211

13-
* Ubuntu 18.04 LTS available, tagged as `-VERSION#-ubuntu-18.04`
14-
* Ubuntu 20.04 LTS available, tagged as `-VERSION#-ubuntu-20.04`
15-
* Ubuntu 22.04 LTS available, tagged as `-VERSION#-ubuntu-22.04`
16-
* Alpine builds available, tagged as `-alpine` **DEPRECATED**
17-
* Centos 7 builds available, tagged as `-centos-7` **DEPRECATED**
12+
| OS | Tag | Notes |
13+
| ------------- | --------------------------- | ------------------ |
14+
| Ubuntu 20.04 | `-VERSION#-ubuntu-20.04` | Current |
15+
| Ubuntu 22.04 | `-VERSION#-ubuntu-22.04` | Current |
16+
| Alpine | `-alpine` | **DEPRECATED** |
17+
| CentOS 7 | `-centos-7` | **DEPRECATED** |
18+
19+
`Alpine`, `CentOS 7` will be removed November 2022.
1820

1921
### Tools
2022

container/root/scripts/install_s6.sh

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash -e
22

3-
# Add S6 for zombie reaping, boot-time coordination, signal transformation/distribution
3+
# Add S6 for zombie reaping, boot-time coordination, signal transformation /
4+
# distribution
45
# @see https://github.com/just-containers/s6-overlay
56
#
67
# Downloads, verifies, and extracts
@@ -11,26 +12,38 @@ ARCH="$(archstring --x64 amd64 --arm64 aarch64)"
1112

1213
S6_NAME=s6-overlay-${ARCH}.tar.gz
1314
S6_VERSION=${S6_VERSION:="v2.1.0.2"}
14-
PUBLIC_KEY=6101B2783B2FD161
15+
# PUBLIC_KEY=6101B2783B2FD161
1516

16-
curl -fL https://github.com/just-containers/s6-overlay/releases/download/${S6_VERSION}/${S6_NAME} -o /tmp/${S6_NAME}
17-
curl -fL https://github.com/just-containers/s6-overlay/releases/download/${S6_VERSION}/${S6_NAME}.sig -o /tmp/${S6_NAME}.sig
17+
S6_OVERLAY_BASE_URL=https://github.com/just-containers/s6-overlay/
1818

19-
gpg --keyserver pgp.surfnet.nl --recv-keys $PUBLIC_KEY
20-
gpg --verify /tmp/${S6_NAME}.sig /tmp/${S6_NAME}
19+
curl -fL "${S6_OVERLAY_BASE_URL}releases/download/${S6_VERSION}/${S6_NAME}" \
20+
-o "/tmp/${S6_NAME}"
21+
curl -fL "${S6_OVERLAY_BASE_URL}releases/download/${S6_VERSION}/${S6_NAME}.sig" \
22+
-o "/tmp/${S6_NAME}.sig"
23+
24+
# 2022-08-28: commented out since this always keeps failing will need to
25+
# revisit. With newer versions of s6-overlay, the way to validate is check
26+
# the checksum
27+
# @see https://github.com/just-containers/s6-overlay#verifying-downloads
28+
#gpg --import /tmp/s6-gpg-pub-key
29+
#gpg --keyserver pgp.surfnet.nl --recv-keys $PUBLIC_KEY
30+
#gpg --verify "/tmp/${S6_NAME}.sig" "/tmp/${S6_NAME}"
2131

2232
# Special handling - CentOS >= 7 + Ubuntu >= 20.04
2333
# @see https://github.com/just-containers/s6-overlay#bin-and-sbin-are-symlinks
24-
# Need to also exclude the symlink included in s6-overlay-amd64.tar.gz as the symlink would otherwise overwrite the binary
34+
# Need to also exclude the symlink included in s6-overlay-amd64.tar.gz as the
35+
# symlink would otherwise overwrite the binary
2536
# $ tar tvzf s6-overlay-amd64.tar.gz |grep execlineb
2637
# -rwxr-xr-x root/root 33856 2019-03-21 12:29 ./bin/execlineb
2738
# lrwxrwxrwx root/root 0 2019-03-21 12:40 ./usr/bin/execlineb -> /bin/execlineb
2839

2940
if [[ -L /bin ]]; then
30-
tar xzf /tmp/${S6_NAME} -C / --exclude="./bin" --exclude="./usr/bin/execlineb"
31-
tar xzf /tmp/${S6_NAME} -C /usr ./bin --exclude="./usr/bin/execlineb"
41+
tar xzf "/tmp/${S6_NAME}" -C \
42+
/ --exclude="./bin" --exclude="./usr/bin/execlineb"
43+
tar xzf "/tmp/${S6_NAME}" -C \
44+
/usr ./bin --exclude="./usr/bin/execlineb"
3245
else
33-
tar xzf /tmp/${S6_NAME} -C /
46+
tar xzf "/tmp/${S6_NAME}" -C /
3447
fi
3548

36-
rm /tmp/${S6_NAME} && rm /tmp/${S6_NAME}.sig
49+
rm "/tmp/${S6_NAME}" && rm "/tmp/${S6_NAME}.sig"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/bash -e
2+
3+
# https://jira.corp.adobe.com/browse/ETHOS-28973
4+
# Add the ability to switch to a different mirror as needed
5+
6+
APT_SOURCE_LIST=${APT_SOURCE_LIST:=/etc/apt/sources.list}
7+
8+
update_apt_sources() {
9+
local _src="$1" _mirror="$2"
10+
11+
# Mirror URL must be set and must begin with http
12+
if [[ -z "$_mirror" ]]; then
13+
return
14+
fi
15+
16+
if [[ "$_mirror" == http* ]]; then
17+
sed -i -e "s|${_src}|${_mirror}|g" "${APT_SOURCE_LIST}"
18+
else
19+
echo "warning: Unsupported mirror url: $_mirror"
20+
fi
21+
}
22+
23+
if [[ ! -f "$APT_SOURCE_LIST" ]]; then
24+
echo "failure: $APT_SOURCE_LIST does not exist!"
25+
exit 1
26+
fi
27+
28+
if [[ -n "$UBUNTU_ARCHIVE_MIRROR_URL" ]]; then
29+
update_apt_sources "http://archive.ubuntu.com/ubuntu/" \
30+
"$UBUNTU_ARCHIVE_MIRROR_URL"
31+
fi
32+
33+
if [[ -n "$UBUNTU_SECURITY_MIRROR_URL" ]]; then
34+
update_apt_sources "http://security.ubuntu.com/ubuntu/" \
35+
"$UBUNTU_SECURITY_MIRROR_URL"
36+
fi
37+
38+
if [[ -n "$UBUNTU_PORTS_MIRROR_URL" ]]; then
39+
update_apt_sources "http://ports.ubuntu.com/ubuntu-ports/" \
40+
"$UBUNTU_PORTS_MIRROR_URL"
41+
fi
42+
43+
# Useful when you need to debug the contents of sources.list
44+
if [[ -n "$DEBUG" ]]; then
45+
echo "*** DEBUG is set. Dumping $APT_SOURCE_LIST ***"
46+
grep -v '#' "$APT_SOURCE_LIST"
47+
fi

docs/mirrors.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Mirrors
2+
3+
By default, Ubuntu ships with the following configuration:
4+
5+
```shell
6+
root@979e866735eb:/# grep -v '#' /etc/apt/sources.list
7+
deb http://ports.ubuntu.com/ubuntu-ports/ focal main restricted
8+
deb http://ports.ubuntu.com/ubuntu-ports/ focal-updates main restricted
9+
deb http://ports.ubuntu.com/ubuntu-ports/ focal universe
10+
deb http://ports.ubuntu.com/ubuntu-ports/ focal-updates universe
11+
deb http://ports.ubuntu.com/ubuntu-ports/ focal multiverse
12+
deb http://ports.ubuntu.com/ubuntu-ports/ focal-updates multiverse
13+
deb http://ports.ubuntu.com/ubuntu-ports/ focal-backports main restricted universe multiverse
14+
deb http://ports.ubuntu.com/ubuntu-ports/ focal-security main restricted
15+
deb http://ports.ubuntu.com/ubuntu-ports/ focal-security universe
16+
deb http://ports.ubuntu.com/ubuntu-ports/ focal-security multiverse
17+
```
18+
19+
There might be a need for you to replace the sources URL (as it was with
20+
[ETHOS-28973]) and re-point to a different mirror.
21+
22+
One way to tackle this problem is to simply add something similar to the
23+
following before you perform an `apt-get -y update`:
24+
25+
```shell
26+
RUN sed -i \
27+
-e 's|http://archive.ubuntu.com/ubuntu|https://your/remote|g' \
28+
-e 's|http://security.ubuntu.com/ubuntu|https://your/remote|g' \
29+
-e 's|http://ports.ubuntu.com/ubuntu-ports|https://your/remote|g' \
30+
"/etc/apt/sources.list"
31+
```
32+
33+
# update_apt_sources.sh
34+
35+
For Blessed Base Containers which inherit from this `docker-base`, we use
36+
the [update_apt_sources.sh] script to re-point the sources to our Corporate
37+
mirrors on demand.
38+
39+
To use the script, you would set one or more of the following environment.
40+
When set, the script will search and replace the URL with the value that you
41+
specify:
42+
43+
| Environment Variable | Search and replace URL if present |
44+
| ----------------------------- | ------------------------------------------ |
45+
| `UBUNTU_PORTS_MIRROR_URL` | http://ports.ubuntu.com/ubuntu-ports/ |
46+
| `UBUNTU_ARCHIVE_MIRROR_URL` | http://archive.ubuntu.com/ubuntu/ |
47+
| `UBUNTU_SECURITY_MIRROR_URL` | http://security.ubuntu.com/ubuntu/ |
48+
49+
For example, in your `Dockerfile`
50+
51+
```
52+
COPY ./container/root /
53+
54+
# Set environment
55+
ENV UBUNTU_PORTS_MIRROR_URL=https://foo/my/mirror
56+
57+
# Run the replacement before an apt-get
58+
RUN /bin/bash -e /scripts/ubuntu/test_update_apt_sources.sh && \
59+
apt-get -y update && apt-get -y upgrade \
60+
[...snip...]
61+
```
62+
63+
[update_apt_sources.sh]: ../container/root/scripts/ubuntu/test_update_apt_sources.sh

docs/tests.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Tests
2+
3+
## shunit2
4+
5+
Starting August 28, 2022, all shell scripts should ideally have a corresponding
6+
`shunit2` test.
7+
8+
See [shunit2] for usage and documentation.
9+
10+
Guidelines:
11+
12+
* Tests are stored in `tests/sh`
13+
* Path to the test should mirror the actual location of the original script
14+
* Name of the script should be `test_` + name of actual script to test
15+
16+
For an example, see [test_update_apt_sources.sh].
17+
18+
To run all tests:
19+
20+
```shell
21+
make shunit2
22+
```
23+
24+
To run a specific test file (useful to target a specific test)
25+
26+
```shell
27+
RUN_TEST_FILE=tests/sh/container/root/scripts/ubuntu/test_update_apt_sources.sh make shunit2
28+
```
29+
30+
To run all tests in a specific directory:
31+
32+
```shell
33+
RUN_TEST_DIR=tests/sh/container/root/scripts/ubuntu make shunit2
34+
```
35+
36+
[shunit2]: https://github.com/kward/shunit2
37+
[test_update_apt_sources.sh]: ../tests/sh/container/root/scripts/ubuntu/test_update_apt_sources.sh

tests/sh/Dockerfile.shunit2

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM ubuntu:22.04
2+
3+
WORKDIR /
4+
5+
# Copy the top-level directory that we wish to test
6+
COPY ./container/root /
7+
8+
# Copy our tests
9+
COPY ./tests /tests
10+
11+
# Run the shunit2 tests
12+
CMD ["/bin/bash", "/tests/sh/run_tests.sh"]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# tests CHANGELOG
2+
3+
# 0.1.0
4+
5+
- Add this folder
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/bin/bash
2+
3+
setUp() {
4+
# Get the path to this test script
5+
SHUNIT2_TEST_SCRIPT=$0
6+
# Replace the path tests/sh and strip out the test_ part of the name
7+
SCRIPT_TO_TEST=$(echo "$SHUNIT2_TEST_SCRIPT" | \
8+
sed 's|tests/sh/container/root||' | sed 's|test_||')
9+
# Temp location to store script output for validation purposes
10+
TEST_OUTPUT=/tmp/$$.out
11+
12+
# Fake copy of the real apt sources list
13+
FAKE_APT_SOURCE_LIST=/tmp/foo.list
14+
}
15+
16+
tearDown() {
17+
# Clean up
18+
if [[ -f "$TEST_OUTPUT" ]]; then
19+
rm -f "$TEST_OUTPUT"
20+
fi
21+
}
22+
23+
create_fake_source_list() {
24+
# Helper to create a temporary source list for testing purposes
25+
local _prefix="$1"
26+
27+
# Create a fake source list for testing purposes
28+
cat << EOF > "/tmp/${_prefix}.list"
29+
deb http://${_prefix}.ubuntu.com/ubuntu/ focal main restricted
30+
31+
deb http://${_prefix}.ubuntu.com/ubuntu-ports/ focal-updates main restricted
32+
33+
deb http://${_prefix}.ubuntu.com/ubuntu-ports/ focal universe
34+
deb http://${_prefix}.ubuntu.com/ubuntu-ports/ focal-updates universe
35+
EOF
36+
}
37+
38+
test_fail_when_sources_list_does_not_exist() {
39+
APT_SOURCE_LIST=/tmp/foo \
40+
bash "$SCRIPT_TO_TEST" 2>&1 | tee -a "$TEST_OUTPUT" > /dev/null
41+
# cat "$TEST_OUTPUT"
42+
43+
grep "failure: /tmp/foo does not exist!" "$TEST_OUTPUT" > /dev/null
44+
assertTrue "Expecting failure message" "[ $? -eq 0 ]"
45+
}
46+
47+
test_non_http_mirror() {
48+
UBUNTU_ARCHIVE_MIRROR_URL=ftp://foo.bar \
49+
bash "$SCRIPT_TO_TEST" 2>&1 | tee -a "$TEST_OUTPUT" > /dev/null
50+
# cat "$TEST_OUTPUT"
51+
52+
grep "warning: Unsupported mirror url: ftp://foo.bar" "$TEST_OUTPUT" \
53+
> /dev/null
54+
assertTrue "Expecting warning message" "[ $? -eq 0 ]"
55+
}
56+
57+
test_update_apt_source_ports() {
58+
# Make a copy of the original sources.list.
59+
# Typical contents of this file looks like:
60+
# root@979e866735eb:/# grep -v '#' /etc/apt/sources.list
61+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal main restricted
62+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal-updates main restricted
63+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal universe
64+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal-updates universe
65+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal multiverse
66+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal-updates multiverse
67+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal-backports main restricted universe multiverse
68+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal-security main restricted
69+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal-security universe
70+
# deb http://ports.ubuntu.com/ubuntu-ports/ focal-security multiverse
71+
cp /etc/apt/sources.list "$FAKE_APT_SOURCE_LIST"
72+
73+
# Do our search and replace
74+
APT_SOURCE_LIST="$FAKE_APT_SOURCE_LIST" \
75+
UBUNTU_PORTS_MIRROR_URL=https://foo/bar/ports-ubuntu-remote \
76+
bash "$SCRIPT_TO_TEST" 2>&1 | tee -a "$TEST_OUTPUT" > /dev/null
77+
78+
# Confirm that ports.ubuntu.com no longer exist
79+
grep "http://ports.ubuntu.com/ubuntu-ports" "$FAKE_APT_SOURCE_LIST" \
80+
> /dev/null
81+
assertTrue "Expecting warning message" "[ $? -ne 0 ]"
82+
83+
# Confirm that we completed our search and replace
84+
local _total=""
85+
_total=$(grep -c "$UBUNTU_PORTS_MIRROR_URL" "$FAKE_APT_SOURCE_LIST")
86+
assertTrue "Expecting ports url to be replaced" "[ $_total -gt 0 ]"
87+
}
88+
89+
test_update_apt_source_archive() {
90+
create_fake_source_list "archive"
91+
92+
# Do our search and replace
93+
APT_SOURCE_LIST="/tmp/archive.list" \
94+
UBUNTU_ARCHIVE_MIRROR_URL=https://foo/bar/archive-ubuntu-remote \
95+
bash "$SCRIPT_TO_TEST" 2>&1 | tee -a "$TEST_OUTPUT" > /dev/null
96+
97+
local _total=""
98+
_total=$(grep -c "$UBUNTU_ARCHIVE_MIRROR_URL" "$FAKE_APT_SOURCE_LIST")
99+
assertTrue "Expecting archive url to be replaced" "[ $_total -gt 0 ]"
100+
}
101+
102+
test_update_apt_source_security() {
103+
create_fake_source_list "security"
104+
105+
# Do our search and replace
106+
APT_SOURCE_LIST="/tmp/security.list" \
107+
UBUNTU_ARCHIVE_MIRROR_URL=https://foo/bar/security-ubuntu-remote \
108+
bash "$SCRIPT_TO_TEST" 2>&1 | tee -a "$TEST_OUTPUT" > /dev/null
109+
110+
local _total=""
111+
_total=$(grep -c "$UBUNTU_ARCHIVE_MIRROR_URL" "$FAKE_APT_SOURCE_LIST")
112+
assertTrue "Expecting url to be replaced" "[ $_total -gt 0 ]"
113+
}
114+
115+
# Load shunit2 as the last line
116+
. /tests/sh/vendor/shunit2/shunit2

0 commit comments

Comments
 (0)