Skip to content
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

Merge changes from dev #15

Merged
merged 10 commits into from
Feb 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Check out repo
uses: actions/checkout@v2

Expand All @@ -29,6 +32,7 @@ jobs:
with:
context: ./
file: ./Dockerfile
pull: true
push: true
tags: ${{ env.CONTAINER_NAME }}:latest,${{ env.CONTAINER_NAME }}:${{ steps.tag.outputs.lowercase }}

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Check out repo
uses: actions/checkout@v2

Expand All @@ -31,6 +34,7 @@ jobs:
with:
context: ./
file: ./Dockerfile
pull: true
push: true
tags: ${{ env.CONTAINER_NAME }}:${{ steps.branch.outputs.lowercase }}

80 changes: 52 additions & 28 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,38 @@
FROM centos:8 AS caen-base

LABEL maintainer = "Dan Erickson ([email protected])"
LABEL version = "v0.3"
LABEL release-date = "2022-02-02"
LABEL version = "v0.5"
LABEL release-date = "2022-02-06"
LABEL org.opencontainers.image.source = "https://github.com/derickson2402/Dockerized-CAEN"

# Prep base environment
ENV USER=1000 \
GROUP=1000
GROUP=1000 \
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/code
VOLUME /code
RUN mkdir -p /usr/um

# CentOS has been deprecated in favor of CentOS stream, so update repo list to search archives
#
# CentOS has been deprecated in favor of CentOS stream, so update repo list to
# search archives:
# https://forums.centos.org/viewtopic.php?f=54&t=78708
RUN rm -f /etc/yum.repos.d/CentOS-Linux-AppStream.repo \
&& sed -i \
-e 's/mirrorlist.centos.org/vault.centos.org/' \
-e 's/mirror.centos.org/vault.centos.org/' \
-e 's/#baseurl/baseurl/' /etc/yum.repos.d/CentOS-Linux-BaseOS.repo \
# https://www.getpagespeed.com/server-setup/how-to-fix-dnf-after-centos-8-went-eol
RUN sed -i \
-e 's/#baseurl/baseurl/g' \
-e 's/mirror.centos.org/vault.epel.cloud/g' \
-e 's/mirrorlist/#mirrorlist/g' \
/etc/yum.repos.d/CentOS-Linux-* \
&& dnf clean all \
&& dnf swap -y centos-linux-repos centos-stream-repos \
&& dnf install -y --nodocs wget bzip2 tar which
&& dnf install -y --nodocs wget bzip2 tar make

# Set bash as default
SHELL ["/bin/bash", "-c"]


################################################################################
#
# Development environment with basic tools installed, for testing new layers and
# configurations
# Development environment with basic tools installed, used for builder layers
# and for testing

FROM caen-base AS caen-dev

Expand All @@ -47,18 +50,32 @@ CMD ["/bin/bash"]

################################################################################
#
# Experimental golang environment
# Builder container for compiling cppcheck

FROM caen-base AS caen-golang
FROM caen-dev AS builder-cppcheck

RUN wget https://dl.google.com/go/go1.16.12.linux-amd64.tar.gz -O /tmp/go.tar.gz \
&& tar -C /usr/um -xzf /tmp/go.tar.gz \
&& rm -rf /tmp/go.tar.gz /usr/local/go /usr/go /usr/bin/go \
&& ln -s /usr/um/go/bin/go /usr/bin/go
# Download and compile cppcheck. Note that /usr/share/Cppcheck has an
# uppercase 'C', as this is what CAEN has for some reason
RUN wget https://github.com/danmar/cppcheck/archive/2.4.tar.gz \
-O /tmp/cppcheck-2.4.tar.gz \
&& tar -C /tmp -xzf /tmp/cppcheck-2.4.tar.gz \
&& rm -rf /tmp/cppcheck-2.4.tar.gz \
&& cd /tmp/cppcheck-2.4 \
&& FILESDIR=/usr/share/Cppcheck make install \
&& rm -rf /tmp/cppcheck-2.4

# Run the container in the user's project folder
WORKDIR /code
CMD ["/bin/bash"]

################################################################################
#
# Builder container for compiling cppcheck

FROM caen-dev AS builder-golang

# Download and install golang
RUN wget https://dl.google.com/go/go1.16.12.linux-amd64.tar.gz \
-O /tmp/go.tar.gz \
&& tar -C /usr/um -xzf /tmp/go.tar.gz \
&& rm -rf /tmp/go.tar.gz /usr/local/go /usr/go /usr/bin/go


################################################################################
Expand All @@ -68,19 +85,26 @@ CMD ["/bin/bash"]
FROM caen-base

# Install dev packages and tools
RUN yum --setopt=group_package_types=mandatory groupinstall --nodocs -y "Development Tools" \
&& yum install --nodocs -y perf valgrind \
&& yum clean all \
RUN dnf --setopt=group_package_types=mandatory \
groupinstall --nodocs -y "Development Tools" \
&& dnf install --nodocs -y perf valgrind \
&& dnf clean all \
&& rm -rf /var/cache/yum \
&& rm -rf /var/lib/rpm/Packages

# Sym link expected location of CAEN compiler just in case
RUN mkdir -p /usr/um/gcc-6.2.0/bin/ \
&& ln -s /usr/bin/gcc /usr/um/gcc-6.2.0/bin/gcc \
&& ln -s /usr/bin/g++ /usr/um/gcc-6.2.0/bin/g++ \
&& echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/code" >> /root/.bashrc
&& ln -s /usr/bin/g++ /usr/um/gcc-6.2.0/bin/g++

# Set up cppcheck
COPY --from=builder-cppcheck /usr/bin/cppcheck /usr/bin/cppcheck
COPY --from=builder-cppcheck /usr/share/Cppcheck /usr/share/Cppcheck

# Set up golang
COPY --from=builder-golang /usr/um/go /usr/um/go
RUN ln -s /usr/um/go/bin/go /usr/bin/go

# Run the container in the user's project folder
WORKDIR /code
CMD ["/bin/bash"]

44 changes: 32 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,31 @@
Tired of using ssh and Duo mobile when testing your code with CAEN? With this script, all you have to do is run:

```bash
./caen <program> [args]
caen <program> [args]
```

This will run your command in an environment identical to CAEN Linux. For example, if you are working on a c++ project for EECS 281, you could use:
This will run your command in an environment identical to CAEN Linux. For example, if you are working on a C++ project for EECS 281, you could use:

```bash
./caen make clean
./caen make my_program.cpp
./caen valgrind my_program.cpp
./caen perf my_program.cpp
caen make clean
caen make my_program.cpp < input.txt
caen valgrind my_program.cpp
caen perf record my_program.cpp
```

Or maybe you are writing a program in Go, you might want to use:

```bash
caen go build my_program.go
caen ./my_program
```

## Installation

To use this script, you need to have Docker installed on your [macOS](https://docs.docker.com/desktop/mac/install/), [Windows](https://docs.docker.com/desktop/windows/install/), or [Linux](https://docs.docker.com/engine/install/) computer. With Docker installed and running, simply the ```caen``` script in your project folder and preface any of your commands with it. Run the following in your project folder to automatically grab the script:
To use this script, you need to have Docker installed on your [macOS](https://docs.docker.com/desktop/mac/install/), [Windows](https://docs.docker.com/desktop/windows/install/), or [Linux](https://docs.docker.com/engine/install/) computer. With Docker installed, simply run the following command in a shell:

```bash
wget https://raw.githubusercontent.com/derickson2402/Dockerized-CAEN/main/caen && chmod +x ./caen
wget https://raw.githubusercontent.com/derickson2402/Dockerized-CAEN/main/caen -O /usr/local/bin/caen && chmod +x /usr/local/bin/caen
```

## How Does This Work?
Expand All @@ -35,10 +42,16 @@ Oops! Sorry about that! Please log an issue [here](https://github.com/derickson2

## Useful Tips

This container is currently under development, but the script does not check for updates automatically. To get the newest container version, run the following in a terminal with Docker running:
If you want to use a different version of the container other than the default, you can specify the ```CAEN_VERSION``` environment variable before running the script like such:

```bash
docker pull ghcr.io/derickson2402/dockerized-caen:latest
CAEN_VERSION=dev caen my-program
```

This also works for optional arguements to the Docker engine, but this is not recommended as it could conflict with the other options used:

```bash
CAEN_ARGS="-e UID=1001" caen my-program
```

Executables generated with this container are compiled for CAEN servers and won't work on your host system. You should run your ```make clean``` script before switching back and forth, and then run ```make``` from the environment you want to use.
Expand All @@ -57,13 +70,19 @@ docker run --rm -it -v "$(pwd):/code" ghcr.io/derickson2402/dockerized-caen:late

## Hackery

If the container environment is not suiting your needs, you can always run the container manually and hack it into working. The problem is that the update won't survive a container restart, so change the normal script like so:
You can specify the name of the container to use just like you can specify the tag:

```bash
CAEN_REPO_NAME=my-container-name caen my-program
```

If the container environment is not suiting your needs, you can always run the container manually and hack it into working. This is not recommended, and will not necessarily work if you don't know how docker works. However, the following should be what you want:

```bash
docker run -it --name caen-tainer -v "$(pwd):/code" ghcr.io/derickson2402/dockerized-caen:latest bash
```

The important part is to get rid of the ```--rm``` tag so the container isn't destroyed when it exits, and to give it a name to easily reference it with (you don't have to use ```caen-tainer```, but I thought it was funny :smile:). You should be able to jump back into the container with either of:
The important part is to mount your local directory correctly, and to get rid of the ```--rm``` tag so the container isn't destroyed when it exits. If you give the container a name to easily reference it with (you don't have to use ```caen-tainer```, but I thought it was funny :smile:), you should be able to jump back into the container with either of:

```bash
docker start -ai caen-tainer
Expand All @@ -75,3 +94,4 @@ docker exec -it caen-tainer <command>
I started working on this project while taking EECS-281, in order to make debugging my programs easier. I am sharing this project online in hopes that others will find it useful, but note that I don't have much free time to develop this project.

With that said, if you have an idea that would make this project even better, feel free to log an issue or submit a Pull Request. I greatly appreciate any help on developing this project!

106 changes: 96 additions & 10 deletions caen
Original file line number Diff line number Diff line change
@@ -1,20 +1,106 @@
#!/bin/bash

# Present the help screen
if [ $# -eq 0 ] || [ $1 = "help" ]; then
echo -e "Helper script for Dockerized-CAEN. To use, run the following:\n"
echo -e " ./caen <program> [args]\n"
echo -e "For example, running the following would run Valgrind on an"
echo -e "executable called 'program.exe' with a '--flag' and input from a file:\n"
echo -e " ./caen valgrind program.exe --flag < input.txt\n"
# Shell settings to improve safety
set -f -o pipefail

# Define our help message, docker flags, and env vars
CAEN_DEFAULT_ARGS="--rm -i --name caen-tainer -e TERM=${TERM:=linux}"
CAEN_WORKING_DIR="-v '$(pwd):/code'"
HELP_MESSAGE=$(cat << EOF
Helper script for Dockerized-CAEN. To use, run the following:

$0 <program> [args]

For example, running the following would run Valgrind on an
executable called 'program.exe' with a '--flag' and input from a file:

$0 valgrind program.exe --flag < input.txt

You can specify a specific version of the container to run with the
\$CAEN_VERSION environment variable like so:

CAEN_VERSION=dev $0 valgrind

EOF
)

# Get OS information
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
HOST_OS=linux
elif [[ "$OSTYPE" == "darwin"* ]]; then
HOST_OS=mac
elif [[ "$OSTYPE" == "cygwin"* ]] | [[ "$OSTYPE" == "msys" ]]; then
HOST_OS=windows
else
echo -e "Uh Oh!! We couldn't figure out what computer you're running..."
echo -e "You can probably still run the container manually though, check"
echo -e "out the GitHub page for help!"
echo -e "\n\thttps://github.com/derickson2402/Dockerized-CAEN"
exit
fi

# Make sure that Docker Engine is installed and running
if ( ! command -v docker &> /dev/null ); then
echo -e "Heads up! Docker is not installed on your computer!"
echo -e "You can download and install it here:"
if [[ "$HOST_OS" == "windows" ]]; then
echo -e "\n\thttps://docs.docker.com/desktop/#download-and-install"
elif [[ "$HOST_OS" == "mac" ]]; then
echo -e "\n\thttps://docs.docker.com/desktop/mac/install/"
else
echo -e "\n\thttps://docs.docker.com/engine/install/"
fi
exit
elif ( ! docker stats --no-stream &> /dev/null ); then
echo -e "Waking up Moby the Whale..."
if [[ "$HOST_OS" == "mac" ]]; then
open /Applications/Docker.app
elif [[ "$HOST_OS" == "windows" ]]; then
/mnt/c/Program\ Files/Docker/Docker/resources/dockerd.exe
elif [[ "$HOST_OS" == "linux" ]]; then
sudo systemctl start docker
fi
sleep 5
declare -i counter=0
while ( ! docker stats --no-stream &> /dev/null ); do
(( counter += 1 ))
echo -e "Waiting for Moby the Whale to wake up..."
sleep 10
if [[ counter -gt 2 ]]; then
echo -e "Couldn't wake up Moby :("
echo -e "Maybe try restarting Docker?"
exit
fi
done
fi

# Process the CLI args and get the specified program
# Process the CLI args, set default vars, and get the specified program
if [ $# -eq 0 ]; then
echo -e "$HELP_MESSAGE" && exit
fi
if ( wget -q --spider http://github.com ); then
CAEN_DEFAULT_ARGS="$CAEN_DEFAULT_ARGS --pull always"
fi
PROGRAM=$1
shift
case $PROGRAM in
help)
echo -e "$HELP_MESSAGE" && exit
;;
perf)
echo -e "Heads up! Perf requires SYS_ADMIN Docker capabilities to run."
echo -e "You should only do this with code that you trust!"
read -p "Hit [Ctrl+c] to cancel, or enter to continue" </dev/tty
CAEN_DEFAULT_ARGS="$CAEN_DEFAULT_ARGS --privileged --cap-add SYS_ADMIN"
;;
esac

# Execute the given program and its args using the CAEN container
# docker run --rm -it -v "$(pwd):/code" ghcr.io/derickson2402/dockerized-caen:latest $PROGRAM $@
docker run --rm -it -v "$(pwd):/code" ghcr.io/derickson2402/dockerized-caen:latest $PROGRAM $@
# Also check for stdin, allowing for file redirection
if [ ! -t 0 ]; then
eval -- docker run "$CAEN_DEFAULT_ARGS" "$CAEN_ARGS" "$CAEN_WORKING_DIR" "${CAEN_REPO_NAME:=ghcr.io/derickson2402/dockerized-caen}":"${CAEN_VERSION:=latest}" "$PROGRAM" "$@" < /dev/stdin
else
CAEN_DEFAULT_ARGS="$CAEN_DEFAULT_ARGS -t"
eval -- docker run "$CAEN_DEFAULT_ARGS" "$CAEN_ARGS" "$CAEN_WORKING_DIR" "${CAEN_REPO_NAME:=ghcr.io/derickson2402/dockerized-caen}":"${CAEN_VERSION:=latest}" "$PROGRAM" "$@"
fi