Skip to content

Merges main into help50 branch #201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
fceeb99
updates Node, Ruby, SQLite
dmalan Jan 5, 2024
70c1829
fixed typo in version
dmalan Jan 5, 2024
e287f7b
updated patch
dmalan Jan 6, 2024
329b354
fixate version number for http-server
rongxin-liu Jan 6, 2024
4d5402d
patching http-server too
dmalan Jan 6, 2024
caa4790
rebuild image
rongxin-liu Jan 16, 2024
209646f
Reverts Ruby for now
dmalan Jan 25, 2024
5813e11
Merge pull request #192 from cs50/versions
rongxin-liu Jan 25, 2024
52fc813
added R
dmalan Jan 26, 2024
22b66b8
removed http-server.patch as unnecessary in cs50/cli
dmalan Jan 26, 2024
fceacf2
updated R install
dmalan Jan 26, 2024
3ebda35
removed --prefix for R
dmalan Jan 26, 2024
c91eab6
using long opts
dmalan Jan 26, 2024
a165985
added back prefix
dmalan Jan 26, 2024
658e622
added TODO
dmalan Jan 26, 2024
4da9f31
Merge pull request #196 from cs50/http-server
rongxin-liu Jan 26, 2024
1f4fd1b
tweaked R install
dmalan Jan 26, 2024
f43d8b6
Merge branch 'main' into r
dmalan Jan 26, 2024
f6659a4
removed patch
dmalan Jan 26, 2024
df2f981
updated SQLite
dmalan Jan 26, 2024
8c48dbb
added --vanilla
dmalan Jan 26, 2024
e28fea6
fixed stats package
dmalan Jan 26, 2024
3cab982
tidied Dockerfile
dmalan Jan 27, 2024
5a6e240
downloading JDK conditionally
dmalan Jan 27, 2024
6558ed3
tidied Dockerfile
dmalan Jan 27, 2024
6702327
added wget
dmalan Jan 27, 2024
d7e621d
Merge branch 'main' into r
dmalan Jan 27, 2024
7d990b6
Merge pull request #198 from cs50/r
dmalan Jan 27, 2024
20cf242
added R dependencies
dmalan Jan 27, 2024
d41ceb0
added docker-squash, removed packages
dmalan Jan 27, 2024
93e7832
upgraded runner
dmalan Jan 27, 2024
833d2bb
reverted runner
dmalan Jan 27, 2024
c3013ec
outputting sizes in Makefile
dmalan Jan 27, 2024
907584f
removed --cleanup
dmalan Jan 27, 2024
d2a501e
added Setup Python
dmalan Jan 27, 2024
8e37087
use 64-core runner
rongxin-liu Jan 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
on: push
jobs:
build:
runs-on: ubuntu-latest-16-cores
runs-on: ubuntu-latest-64-cores
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
Expand All @@ -15,6 +15,11 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Build for linux/amd64
uses: docker/build-push-action@v3
with:
Expand All @@ -26,6 +31,12 @@ jobs:
cache-from: type=registry,ref=cs50/cli:amd64-buildcache
cache-to: type=registry,ref=cs50/cli:amd64-buildcache,mode=max

- name: Squash for linux/amd64
if: ${{ github.ref == 'refs/heads/develop' }}
run: |
pip3 install docker-squash
docker-squash --tag cs50/cli:amd64 cs50/cli:amd64

- name: Push linux/amd64 build to Docker Hub
if: ${{ github.ref == 'refs/heads/main' }}
run: |
Expand All @@ -42,6 +53,12 @@ jobs:
cache-from: type=registry,ref=cs50/cli:arm64-buildcache
cache-to: type=registry,ref=cs50/cli:arm64-buildcache,mode=max

- name: Squash for linux/arm64
if: ${{ github.ref == 'refs/heads/develop' }}
run: |
pip3 install docker-squash
docker-squash --cleanup --tag cs50/cli:arm64 cs50/cli:arm64

- name: Push linux/arm64 build to Docker Hub
if: ${{ github.ref == 'refs/heads/main' }}
run: |
Expand Down
152 changes: 91 additions & 61 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,54 @@
# Build statge
# Build stage
FROM ubuntu:22.04 as builder
ARG DEBIAN_FRONTEND=noninteractive


# Stage-wide dependencies
RUN apt update && \
apt install --no-install-recommends --no-install-suggests --yes \
build-essential \
ca-certificates \
curl


# Install Java 21.x
# http://jdk.java.net/21/
RUN cd /tmp && \
if [ $(uname -m) = "x86_64" ]; then ARCH="x64"; else ARCH="aarch64"; fi && \
curl --remote-name https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-${ARCH}_bin.tar.gz && \
tar xzf openjdk-21.0.2_linux-${ARCH}_bin.tar.gz && \
rm --force openjdk-21.0.2_linux-${ARCH}_bin.tar.gz && \
mv jdk-21.0.2 /opt/jdk && \
mkdir --parent /opt/bin && \
ln --symbolic /opt/jdk/bin/* /opt/bin/ && \
chmod a+rx /opt/bin/*


# Install Node.js 21.x
# https://nodejs.dev/en/download/
# https://github.com/tj/n#installation
RUN curl --location https://github.com/raw/tj/n/master/bin/n --output /usr/local/bin/n && \
chmod a+x /usr/local/bin/n && \
n 21.6.1


# Install Node.js packages
RUN npm install --global \
http-server


# Patch index.js in http-server
COPY index.js.patch /tmp
RUN cd /usr/local/lib/node_modules/http-server/lib/core/show-dir && \
patch index.js < /tmp/index.js.patch && \
rm --force /tmp/index.js.patch


# Suggested build environment for Python, per pyenv, even though we're building ourselves
# https://github.com/pyenv/pyenv/wiki#suggested-build-environment
RUN apt update && \
apt install --no-install-recommends --no-install-suggests --yes \
curl ca-certificates build-essential git \
build-essential ca-certificates curl git \
libssl-dev libbz2-dev libreadline-dev libsqlite3-dev \
llvm libncursesw5-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev \
make tk-dev unzip wget xz-utils zlib1g-dev
Expand All @@ -16,11 +57,11 @@ RUN apt update && \
# Install Python 3.11.x
# https://www.python.org/downloads/
RUN cd /tmp && \
curl https://www.python.org/ftp/python/3.11.7/Python-3.11.7.tgz --output Python-3.11.7.tgz && \
curl --remote-name https://www.python.org/ftp/python/3.11.7/Python-3.11.7.tgz && \
tar xzf Python-3.11.7.tgz && \
rm --force Python-3.11.7.tgz && \
cd Python-3.11.7 && \
CFLAGS="-Os" ./configure --enable-optimizations --without-tests && \
CFLAGS="-Os" ./configure --disable-static --enable-optimizations --enable-shared --with-lto --without-tests && \
./configure && \
make && \
make install && \
Expand All @@ -31,14 +72,32 @@ RUN cd /tmp && \
pip3 install --no-cache-dir --upgrade pip


# Install R
# https://docs.posit.co/resources/install-r-source/#build-and-install-r
# https://cran.rstudio.com/src/base/R-4/
RUN sed --in-place "/^#.*deb-src.*universe$/s/^# //g" /etc/apt/sources.list && \
apt update && \
apt build-dep --yes r-base && \
cd /tmp && \
curl --remote-name https://cran.rstudio.com/src/base/R-4/R-4.3.2.tar.gz && \
tar xzf R-4.3.2.tar.gz && \
rm --force R-4.3.2.tar.gz && \
cd R-4.3.2 && \
./configure --enable-memory-profiling --enable-R-shlib && \
make && \
make install && \
cd .. && \
rm --force --recursive R-4.3.2


# Install Ruby 3.2.x
# https://www.ruby-lang.org/en/downloads/
RUN apt update && \
apt install --no-install-recommends --no-install-suggests --yes \
autoconf \
libyaml-dev && \
apt clean && \
rm -rf /var/lib/apt/lists/* && \
rm --force --recursive /var/lib/apt/lists/* && \
cd /tmp && \
curl https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz --output ruby-3.2.2.tar.gz && \
tar xzf ruby-3.2.2.tar.gz && \
Expand Down Expand Up @@ -66,64 +125,33 @@ RUN gem install --no-document \
# https://www.sqlite.org/howtocompile.html#compiling_the_command_line_interface
COPY shell.c.patch /tmp
RUN cd /tmp && \
curl --remote-name https://www.sqlite.org/2023/sqlite-amalgamation-3440000.zip && \
unzip sqlite-amalgamation-3440000.zip && \
rm --force sqlite-amalgamation-3440000.zip && \
cd sqlite-amalgamation-3440000 && \
curl --remote-name https://www.sqlite.org/2024/sqlite-amalgamation-3450000.zip && \
unzip sqlite-amalgamation-3450000.zip && \
rm --force sqlite-amalgamation-3450000.zip && \
cd sqlite-amalgamation-3450000 && \
patch shell.c < /tmp/shell.c.patch && \
gcc -D HAVE_READLINE -D SQLITE_DEFAULT_FOREIGN_KEYS=1 -D SQLITE_OMIT_DYNAPROMPT=1 shell.c sqlite3.c -lpthread -ldl -lm -lreadline -lncurses -o /usr/local/bin/sqlite3 && \
cd .. && \
rm --force --recursive sqlite-amalgamation-3440000 && \
rm --force --recursive sqlite-amalgamation-3450000 && \
rm --force /tmp/shell.c.patch


# Install Java 21.x
# http://jdk.java.net/21/
RUN cd /tmp && \
curl --remote-name https://download.java.net/java/GA/jdk21.0.1/415e3f918a1f4062a0074a2794853d0d/12/GPL/openjdk-21.0.1_linux-x64_bin.tar.gz && \
tar xzf openjdk-21.0.1_linux-x64_bin.tar.gz && \
rm --force openjdk-21.0.1_linux-x64_bin.tar.gz && \
mv jdk-21.0.1 /opt/ && \
mkdir --parent /opt/bin && \
ln --symbolic /opt/jdk-21.0.1/bin/* /opt/bin/ && \
chmod a+rx /opt/bin/*


# Install Node.js 21.x
# https://nodejs.dev/en/download/
# https://github.com/tj/n#installation
RUN curl --location https://github.com/raw/tj/n/master/bin/n --output /usr/local/bin/n && \
chmod a+x /usr/local/bin/n && \
n 21.2.0


# Install GitHub CLI
# https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-raspberry-pi-os-apt
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \
apt update && \
apt install gh --no-install-recommends --no-install-suggests --yes


# Final stage
FROM ubuntu:22.04
LABEL maintainer="[email protected]"
ARG DEBIAN_FRONTEND=noninteractive


# Copy files from builder
COPY --from=builder /usr /usr
COPY --from=builder /opt /opt
COPY --from=builder /usr/local /usr/local


# Avoid "delaying package configuration, since apt-utils is not installed"
# Install locales
RUN apt update && \
apt install --no-install-recommends --no-install-suggests --yes \
apt-utils \
curl \
ca-certificates \
locales && \
locale-gen \
en_US.utf8 \
Expand All @@ -145,16 +173,18 @@ RUN apt update && \
ENV LANG=C.UTF-8


# Install CS50, Ubuntu, and Python packages
RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh | bash && \
apt update && \
# Install Ubuntu packages
RUN apt update && \
apt upgrade --yes && \
apt install --no-install-recommends --no-install-suggests --yes \
astyle \
bash-completion \
build-essential `# dpkg-dev, libc, gcc, g++, make, etc.`\
ca-certificates \
clang \
coreutils `# For fold` \
cowsay \
curl \
dos2unix \
dnsutils `# For nslookup` \
fonts-noto-color-emoji `# For render50` \
Expand All @@ -163,24 +193,36 @@ RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh |
git-lfs \
jq \
less \
libcs50 \
liblapack3 `# For R` \
libmagic-dev `# For style50` \
libpango-1.0-0 libharfbuzz0b libpangoft2-1.0-0 `# For render50` \
libpangocairo-1.0-0 `# For R` \
libtiff5 `# For R` \
libxt6 `# For R` \
libyaml-0-2 `# Runtime package for gem` \
man \
man-db \
nano \
openssh-client `# For ssh-keygen` \
psmisc `# For fuser` \
ruby-dev `# Ruby development headers` \
sudo \
tzdata `# For TZ` \
unzip \
valgrind \
vim \
wget \
zip && \
apt clean && \
pip3 install --no-cache-dir \
apt clean


# Install CS50 library
RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh | bash && \
apt update && \
apt install --yes libcs50


# Install Python packages
RUN pip3 install --no-cache-dir \
autopep8 \
black \
"check50<4" \
Expand All @@ -196,18 +238,6 @@ RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh |
"submit50<4"


# Install Node.js packages
RUN npm install --global \
http-server


# Patch index.js in http-server
COPY index.js.patch /tmp
RUN cd /usr/local/lib/node_modules/http-server/lib/core/show-dir && \
patch index.js < /tmp/index.js.patch && \
rm --force /tmp/index.js.patch


# Copy files to image
COPY ./etc /etc
COPY ./opt /opt
Expand Down
17 changes: 14 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
.PHONY: default
default: run

build:
docker build --build-arg VCS_REF="$(shell git rev-parse HEAD)" -t cs50/cli .
docker build --build-arg VCS_REF="$(shell git rev-parse HEAD)" --tag cs50/cli .
$(MAKE) squash

depends:
pip3 install docker-squash

rebuild:
docker build --no-cache -t cs50/cli .
docker build --no-cache --tag cs50/cli .
$(MAKE) squash

run:
docker run --env LANG="$(LANG)" -it -P --rm --security-opt seccomp=unconfined -v "$(PWD)":/home/ubuntu cs50/cli bash --login || true
docker run --env LANG="$(LANG)" --interactive --publish-all --rm --security-opt seccomp=unconfined --tty --volume "$(PWD)":/home/ubuntu cs50/cli bash --login || true

squash: depends
docker images cs50/codespace
docker-squash --tag cs50/cli cs50/cli
docker images cs50/codespace
1 change: 1 addition & 0 deletions etc/profile.d/cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ if [ "$(whoami)" != "root" ]; then
alias mv="mv -i"
alias pip="pip --no-cache-dir"
alias python="python -q"
alias R="R --vanilla"
alias rm="rm -i"
alias sudo="sudo " # Trailing space enables elevated command to be an alias

Expand Down
1 change: 1 addition & 0 deletions index.js.patch
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# diff /usr/local/lib/node_modules/http-server/lib/core/show-dir/index.js index.js > index.js.patch
129,131c129
< html += `<br><address>Node.js ${
< process.version
Expand Down
29 changes: 4 additions & 25 deletions shell.c.patch
Original file line number Diff line number Diff line change
@@ -1,25 +1,4 @@
# diff shell.c shell_modified.c > shell.c.patch
28631,28641c28631,28641
< printf(
< "SQLite version %s %.19s%s\n" /*extra-version-info*/
< "Enter \".help\" for usage hints.\n",
< sqlite3_libversion(), sqlite3_sourceid(), zCharset
< );
< if( warnInmemoryDb ){
< printf("Connected to a ");
< printBold("transient in-memory database");
< printf(".\nUse \".open FILENAME\" to reopen on a "
< "persistent database.\n");
< }
---
> // printf(
> // "SQLite version %s %.19s%s\n" /*extra-version-info*/
> // "Enter \".help\" for usage hints.\n",
> // sqlite3_libversion(), sqlite3_sourceid(), zCharset
> // );
> // if( warnInmemoryDb ){
> // printf("Connected to a ");
> // printBold("transient in-memory database");
> // printf(".\nUse \".open FILENAME\" to reopen on a "
> // "persistent database.\n");
> // }
29438,29440d29437
< sputf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/
< "Enter \".help\" for usage hints.\n",
< sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);