├── .editorconfig ├── .github └── workflows │ ├── build-on-pr.yml │ ├── publish-image.yml │ └── publish-tags.yml ├── .gitignore ├── Dockerfile ├── README.md ├── files ├── bin │ └── praise └── root │ ├── .bashrc │ ├── .valgrind.gcc.supp │ └── .valgrindrc ├── unix ├── install-ch.sh └── setup.sh └── windows ├── install-ch.ps1 └── setup.ps1 /.editorconfig: -------------------------------------------------------------------------------- 1 | [{*.bat,*.sh}] 2 | indent_style = space 3 | indent_size = 2 4 | -------------------------------------------------------------------------------- /.github/workflows/build-on-pr.yml: -------------------------------------------------------------------------------- 1 | name: Build Docker Image 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | push_to_registry: 10 | name: Build Docker Image 11 | runs-on: ubuntu-20.04 12 | steps: 13 | - 14 | name: Check out the repo 15 | uses: actions/checkout@v2 16 | - 17 | name: Set up QEMU 18 | uses: docker/setup-qemu-action@v1 19 | - 20 | name: Set up Docker Buildx 21 | uses: docker/setup-buildx-action@v1 22 | - 23 | name: Build 24 | uses: docker/build-push-action@v2 25 | with: 26 | context: . 27 | platforms: |- 28 | linux/amd64 29 | linux/arm64 30 | file: ./Dockerfile 31 | pull: true 32 | cache-from: type=gha 33 | cache-to: type=gha 34 | -------------------------------------------------------------------------------- /.github/workflows/publish-image.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker Image 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | push_to_registry: 10 | name: Push image to Docker Hub 11 | runs-on: ubuntu-latest 12 | steps: 13 | - 14 | name: Check out the repo 15 | uses: actions/checkout@v2 16 | - 17 | name: Set up QEMU 18 | uses: docker/setup-qemu-action@v1 19 | - 20 | name: Set up Docker Buildx 21 | uses: docker/setup-buildx-action@v1 22 | - 23 | name: Login to DockerHub 24 | uses: docker/login-action@v1 25 | with: 26 | username: ${{ secrets.DOCKERHUB_USERNAME }} 27 | password: ${{ secrets.DOCKERHUB_TOKEN }} 28 | - 29 | name: Build and push 30 | uses: docker/build-push-action@v2 31 | with: 32 | context: . 33 | platforms: |- 34 | linux/amd64 35 | linux/arm64 36 | file: ./Dockerfile 37 | push: true 38 | tags: usccsci104/docker:20.04 39 | cache-from: type=registry,ref=usccsci104/docker:buildcache 40 | cache-to: type=registry,ref=usccsci104/docker:buildcache,mode=max 41 | - 42 | name: Image digest 43 | run: echo ${{ steps.docker_build.outputs.digest }} 44 | -------------------------------------------------------------------------------- /.github/workflows/publish-tags.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker Image 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | push_to_registry: 10 | name: Push image to Docker Hub 11 | runs-on: ubuntu-20.04 12 | steps: 13 | - 14 | name: Check out the repo 15 | uses: actions/checkout@v2 16 | - 17 | name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v1 19 | - 20 | name: Login to DockerHub 21 | uses: docker/login-action@v1 22 | with: 23 | username: ${{ secrets.DOCKERHUB_USERNAME }} 24 | password: ${{ secrets.DOCKERHUB_TOKEN }} 25 | - name: Branch data 26 | id: branch_name 27 | run: | 28 | echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} 29 | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} 30 | echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/} 31 | - 32 | name: Build and push 33 | uses: docker/build-push-action@v2 34 | with: 35 | context: . 36 | file: ./Dockerfile 37 | pull: true 38 | push: true 39 | cache-from: type=registry,ref=usccsci104/docker:dev 40 | cache-to: type=inline 41 | tags: usccsci104/docker:${{ steps.branch_name.outputs.SOURCE_TAG }} 42 | - 43 | name: Image digest 44 | run: echo ${{ steps.docker_build.outputs.digest }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /manage* 2 | /.container 3 | /.idea 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | # Scripts and configuration 4 | COPY files/root/* /root/ 5 | COPY files/bin/* /bin/ 6 | 7 | # tzdata will stall autobuild of docker image 8 | # this fixes that 9 | ENV TZ=US/Pacific 10 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 11 | 12 | # Make sure line endings are Unix 13 | # This changes nothing if core.autocrlf is set to input 14 | RUN sed -i 's/\r$//' /root/.bashrc 15 | 16 | RUN apt-get update && apt-get install -y \ 17 | clang \ 18 | clang-tidy \ 19 | clang-format \ 20 | g++ \ 21 | make \ 22 | valgrind \ 23 | gdb \ 24 | llvm \ 25 | libgtest-dev \ 26 | software-properties-common \ 27 | cmake \ 28 | curl \ 29 | default-jre \ 30 | pkg-config \ 31 | wget 32 | 33 | # GTEST installation for labs 34 | WORKDIR /usr/src/gtest 35 | RUN cmake CMakeLists.txt \ 36 | && make \ 37 | && cp ./lib/libgtest*.a /usr/lib \ 38 | && mkdir -p /usr/local/lib/gtest/ \ 39 | && ln -s /usr/lib/libgtest.a /usr/local/lib/gtest/libgtest.a \ 40 | && ln -s /usr/lib/libgtest_main.a /usr/local/lib/gtest/libgtest_main.a 41 | 42 | # Grading, curricula requires python3.9 43 | RUN add-apt-repository ppa:deadsnakes/ppa \ 44 | && apt-get install -y \ 45 | git \ 46 | acl \ 47 | python3.9 \ 48 | python3.9-dev \ 49 | python3-pip 50 | 51 | # Removed while we're doing CMake grading 52 | # && python3.9 -m pip install curricula curricula-grade curricula-grade-cpp curricula-compile curricula-format watchdog 53 | 54 | # Install xmltodict for CMake tests 55 | RUN python3 -m pip install xmltodict 56 | 57 | VOLUME ["/work"] 58 | WORKDIR /work 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSCI 104 Docker 2 | 3 | 4 | Supported Platforms 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | ## Introduction 14 | 15 | This repository contains a Dockerfile and a couple of management scripts for creating and using a virtualized Linux container capable of building, running, and debugging C++. 16 | Using a virtualized container is preferable to a user's local machine because it guarantees consistent compilation and execution of C++ binaries. 17 | While compilers and tooling may vary between systems, creating a sealed environment from the exact same components every time ensures that code runs the same for graders as it does students. 18 | 19 | But why use Docker over a traditional virtual machine? 20 | Docker is considerably less resource-intensive than installing a full virtual machine. 21 | Instead of needing the facilities for a graphical interface, virtual file system, etc., we can mount any directory of the host machine directly in the container and use a shell to run compilation and debugging. 22 | Development and file management may be done normally on the local machine. 23 | 24 | Feel free to read through the [wiki](https://github.com/csci104/docker/wiki) for **a more in-depth guide on [how setup and use Docker](https://github.com/csci104/docker/wiki/Usage)** as well as [how it works](https://github.com/csci104/docker/wiki/Details). 25 | 26 | ## Installation 27 | 28 | This is a fairly long wiki in order to be as clear as possible. Feel free to jump around using the Table of Contents icon on the upper left side of this README: 29 | 30 |
31 | screenshot of github table of contents list 32 |
33 | 34 | 35 | 36 | ### Prerequisites 37 | 38 | You will be running a lot of commands in the terminal to set this up. If you have not done 39 | this before, we *highly recommend* checking out CP Jamie Flores' great [Linux](https://bytes.usc.edu/cs104/wiki/linux) wiki. 40 | Specifically, you'll want to look at the [Navigating Directories](https://bytes.usc.edu/cs104/wiki/linux/#navigating-directories) section. 41 | 42 | Please make sure that your machine meets the requirements for Docker Desktop, which you will install in [Step 1](#step-1-install-docker): 43 | 44 | Windows host: 45 | 46 | - Windows 10 64-bit: (Build 18362 or later) 47 | - WSL2 container backend 48 | 49 | > **Optional:** If you are using Windows 10 Home, you can obtain a "free" license for Windows 10 Education here. 50 | 51 | Mac host: 52 | 53 | - Intel: 54 | - Mac hardware must be a 2010 or newer model 55 | - macOS must be version 10.13 or newer 56 | - 4 GB RAM minimum 57 | - Apple Silicon (e.g. M1, M1X, ...): 58 | - *note:* Please use a standard "native" terminal. **DO NOT** use a Rosetta-emulated terminal, gdb and valgrind [will not work with emulation](https://github.com/docker/for-mac/issues/5191#issuecomment-834154431). 59 | 60 | Linux host: 61 | 62 | - x86_64/amd64: tested on Ubuntu 20.04, Arch Linux 63 | 64 | - aarch64 (e.g. Raspberry Pi): 64-bit OS: tested on Ubuntu Server 21.10 65 | 66 | ### Step 0: Install WSL2 (Windows only) 67 | 68 | If you are using macOS or Linux operating system, you can skip this section. 69 | If you are running Windows, you must install the Windows Subsystem for Linux 2 (WSL2) before installing Docker. 70 | 71 | Follow the instructions below to install WSL2 on your machine: Windows Subsystem for Linux Installation Guide 72 | 73 | 74 | ### Step 1: Install Docker 75 | 76 | 77 | Install Docker Desktop from the website 78 | 79 | When the installation has finished, open up Docker Desktop to make sure it's running. If Docker is running 80 | properly, you will see a green icon in the lower left side, like the image below: 81 | 82 |
83 | screenshot of Docker Desktop with a green icon on the lower left side 84 |
85 | 86 | 87 | 88 | If you encounter errors in this process, please see the Troubleshooting wiki. 89 | 90 | ### Step 2: Create a working directory 91 | 92 | We highly recommend that you create a dedicated working directory to clone CSCI 104 93 | repositories and to do your programming assignments. 94 | 95 | Create a `csci104` folder on your machine. Next, you'll need to open a terminal into 96 | the folder to run the remaining commands in the setup. 97 | 98 | Open up a Terminal (macOS) or Powershell/Windows Terminal (Windows). Next, navigate 99 | to your `csci104` folder by typing `cd ` (notice the space) and dragging the 100 | `csci104` folder from Finder or File Explorer into the terminal, then press enter. 101 | 102 | ### Step 3: Clone this repository 103 | 104 | After setting up Docker, you need to clone this repository which contains 105 | a setup script for both Windows and Unix-based systems. 106 | 107 | 108 | Run the commands below to clone the repository and change directories into the new folder: 109 | 110 | ```shell 111 | git clone https://github.com/csci104/docker.git 112 | cd docker 113 | ``` 114 | 115 | If this command fails with an error like `git command not found`, you need to 116 | install the git command-line interface (CLI). See this link 117 | and download the version for your operating system. 118 | 119 | The `git clone` command downloads a repository (think of it as a folder) from the Github URL. To learn more about what the `cd` command does, take a look at the Linux wiki. 120 | 121 | ### Step 4: Run the setup script 122 | 123 | This repository contains a setup script to install a command-line tool you will 124 | use to access your Docker containers, pull the CSCI 104 docker image and setup your virtualized environment. 125 | 126 | If you followed [Step 3](#step-3-clone-this-repository) properly, you have a terminal open 127 | in the docker folder. If you're not sure, see the [Filepaths in the Terminal](#filepaths-in-the-terminal) tip. 128 | 129 | Now that you're ready to run the setup script, read and follow the instructions 130 | below corresponding to your operating system: 131 | 132 | **macOS/Linux** 133 | 134 | On macOS in Terminal, run the respective setup script inside the `docker` folder: 135 | 136 | ```bash 137 | ./unix/setup.sh 138 | ``` 139 | 140 | > Note: if you're not able to run `ch` after setup, you may need to run `source ~/.zshrc` or `source ~/.bashrc` 141 | > depending on your default shell. If you don't understand what this means, you can safely ignore the comment! 142 | 143 | **Windows** 144 | 145 | On Windows in PowerShell or Windows Terminal, the process is similar but you must make sure you can run PowerShell scripts: 146 | 147 | Make sure you run this in an Admin PowerShell: 148 | 149 | ```powershell 150 | # must execute this in admin powershell and select [A] to run scripts 151 | Set-ExecutionPolicy RemoteSigned 152 | ``` 153 | 154 | In PowerShell, run this command in the `docker` folder: 155 | 156 | ```powershell 157 | .\windows\setup 158 | ``` 159 | 160 | ### Step 5: Set your working directory 161 | 162 | If the command above runs successfully, you will be prompted to provide the directory in your local machine you wish to be accessible from the virtual machine. 163 | 164 | If you followed [Step 2](#step-2-create-a-working-directory), you will drag the 165 | `csci104` folder you created into your terminal from Finder/File Explorer. See 166 | the [Filepaths in the Terminal](#filepaths-in-the-terminal) tip for more help. 167 | 168 | 169 | ### Step 6: Verify your installation 170 | 171 | Once you've finished answering the prompts and setup script finishes, you should be ready to use `ch` to work with your csci104 environment! 172 | 173 | > If you're on macOS, try running `source ~/.zshrc` or `source ~/.bashrc` and then run `ch list`. 174 | If this fails, try opening up a new terminal and retry the command. If this fails, you can 175 | ask a CP, post on Piazza, or create a Github Issue if 176 | you're not in the class but still need help. 177 | 178 | Let's check and make sure everything works by running `ch list` in your terminal. 179 | You should get output like this below, but don't worry if the filepath in `Volume` 180 | looks a little different: 181 | 182 | **macOS** 183 | 184 | ```shell 185 | $ ch list 186 | Name: csci104 187 | Image: usccsci104/docker:20.04 188 | Volume: /Users/username/csci104:/work 189 | SecOpt: seccomp:unconfined 190 | CapAdd: SYS_PTRACE 191 | ``` 192 | 193 | **Windows** 194 | 195 | ```powershell 196 | PS C:\Users\Username> ch list 197 | Name: csci104 198 | Image: usccsci104/docker:20.04 199 | Volume: C:\Users\Username\csci104:/work 200 | SecOpt: seccomp:unconfined 201 | CapAdd: SYS_PTRACE 202 | ``` 203 | 204 | If you see output something like this, you're all set up! Congrats! 205 | 206 | ## Working 207 | 208 | The `ch` (container-helper) command-line tool allows you to create and access Docker environments. 209 | When you ran the `setup` script, it created and pulled a Docker image made for 210 | compiling, running and debugging C++ code in CSCI 104. To run this environment, 211 | you can run this command (the same for both Unix and Windows systems): 212 | 213 | ```bash 214 | ch COMMAND csci104 215 | ``` 216 | 217 | There are three commands you will regularly use: 218 | - The first, `start`, starts the container up in the background. 219 | The container should continue running until you shut down your computer, exit docker, or kill the container manually. 220 | - Next is `shell`, which simply opens a shell inside the virtual machine. 221 | This is where you can run standard linux commands, such as `g++` or `valgrind`. You can exit the shell with the key sequence 222 | - The last is `stop`, which manually shuts down the virtual container. 223 | 224 | 225 | You will use the `ch shell csci104` command to access the Docker container and compile or execute your code and run the 226 | autograder tests after assignments are graded. Anytime you need to push code to Github, make sure to exit the container. 227 | This last note deserves some emphasis: 228 | 229 | 230 | > **You should not run any git commands in Docker**. This means you should not 231 | > run `git pull`, `git push`, `git clone`, etc after running `ch shell csci104`. 232 | 233 | To Windows users: 234 | 235 | > You should only use the `ch shell csci104` commands in Powershell or Windows Terminal on Windows. 236 | > If you use GitBash, Cygwin, or another terminal emulator, you will unexpectedly exit `gdb` debugging 237 | > sessions when you run `ctrl-c`. 238 | 239 | ### Example 240 | 241 | See full documentation for `ch` here. 242 | 243 | ```bash 244 | # start your environment 245 | ch start csci104 246 | 247 | # get a shell into the csci104 environment 248 | ch shell csci104 249 | 250 | # exit the shell with or typing `exit` 251 | 252 | # stop the running environment 253 | ch stop csci104 254 | 255 | # print the running environments 256 | ch running 257 | ``` 258 | 259 | ## Tips 260 | 261 | ### Filepaths in the terminal 262 | 263 | For the installation script and when navigating your terminal for the first 264 | time, you might need to provide a filepath. This represents where on your 265 | machine a specific folder or file is located. For more about this and 266 | terminal commands in general, please check out the 267 | [Linux wiki](https://bytes.usc.edu/cs104/wiki/linux/#navigating-directories). 268 | 269 | There are many ways to do this, but this seems like the easiest way for 270 | people getting used to using their terminal: 271 | 272 | 1. open Finder (macOS) or File Explorer (Windows) 273 | 2. find the folder where you want to go to 274 | 3. drag the path into your terminal to get the path 275 | 276 | If you're wanting to change directories like in [Step 3](#step-3-clone-this-repository), you'll type `cd ` into your terminal and 277 | drag the folder in. 278 | 279 | If you're running the setup script in [Step 4](#step-4-run-the-setup-script), you will drag your csci104 folder in the terminal 280 | when the script asks for a filepath. 281 | ### Valgrind Suppression 282 | 283 | To determine the correct valgrind suppression in the future, refer to [this manual](https://wiki.wxwidgets.org/Valgrind_Suppression_File_Howtohttps://wiki.wxwidgets.org/Valgrind_Suppression_File_Howto). 284 | Running it on a sufficiently complex piece of leak-free code will yield most of the necessary configurations. 285 | 286 | ### Hypervisor on Windows 287 | 288 | If you plan to using Docker and Virtual Box as a fallback, please be aware of what you will need to do to switch between the two systems. You'll have to toggle the Hypervisor: 289 | 290 | - Docker: Hypervisor **ON** 291 | - VirtualBox: Hypervisor **OFF** 292 | 293 | Here's how you can do that on Windows: 294 | 295 | 1. Press Windows key + X and select `Apps and Features`. 296 | 2. Scroll down to the bottom and click Programs and Features link. 297 | 3. Then click the Turn Windows Hypervisor on or off link on the left pane. 298 | 299 | This issue **ONLY** concerns Windows users. 300 | -------------------------------------------------------------------------------- /files/bin/praise: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Praise be unto he who delivered us unto Docker!" 4 | echo "Noah Kim was here. Good luck with 104 :^)" 5 | -------------------------------------------------------------------------------- /files/root/.bashrc: -------------------------------------------------------------------------------- 1 | # Convenience 2 | 3 | # remove colors from ls command and add / to directories 4 | alias ls="ls -p --color=none" 5 | 6 | alias la="ls -la" 7 | 8 | # Change shell to ignore hostname 9 | export PS1="\u@docker:\w$ " 10 | 11 | # Go to work directory 12 | if [[ -s /work ]] 13 | then 14 | cd /work 15 | fi 16 | 17 | -------------------------------------------------------------------------------- /files/root/.valgrind.gcc.supp: -------------------------------------------------------------------------------- 1 | { 2 | 3 | Memcheck:Leak 4 | match-leak-kinds: reachable 5 | fun:malloc 6 | obj:/usr/lib/libstdc++.so.6.0.25 7 | obj:/lib/ld-musl-x86_64.so.1 8 | } 9 | { 10 | 11 | Memcheck:Leak 12 | match-leak-kinds: reachable 13 | fun:calloc 14 | obj:/lib/ld-musl-x86_64.so.1 15 | } 16 | -------------------------------------------------------------------------------- /files/root/.valgrindrc: -------------------------------------------------------------------------------- 1 | --suppressions=/root/.valgrind.gcc.supp 2 | -------------------------------------------------------------------------------- /unix/install-ch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repository="camerondurham/ch" 3 | 4 | function precheck_failed_msg() { 5 | echo -e "\nThis script requires unzip or gunzip installed to work" 6 | echo -e "please retry after installing unzip (macOS) or gunzip (Linux)\n" 7 | echo -e "macOS (with homebrew):\n brew install unzip " 8 | echo -e "Linux (Debian-based, i.e. ubuntu):\n sudo apt install unzip" 9 | echo -e "Linux (Arch, Manjaro):\n sudo pacman -S unzip" 10 | exit 1 11 | } 12 | 13 | function precheck() { 14 | which unzip || { 15 | precheck_failed_msg 16 | } 17 | } 18 | 19 | function get_latest_release() { 20 | curl --silent "https://api.github.com/repos/$1/releases/latest" | # Get latest release from GitHub api 21 | grep '"tag_name":' | # Get tag line 22 | sed -E 's/.*"([^"]+)".*/\1/' # Pluck JSON value 23 | } 24 | 25 | function get_release_package() { 26 | download_url=$1 27 | download_path=$2 28 | filename=$3 29 | cd "$download_path" || exit 1 30 | curl -LO "$download_url" || { 31 | echo Download failed... 32 | exit 1 33 | } 34 | 35 | unzip -o "$filename" || { 36 | echo Unzip failed... 37 | exit 1 38 | } 39 | } 40 | 41 | function get_release_url() { 42 | local repo=$1 43 | local version=$2 44 | local filename=$3 45 | echo "https://github.com/$repo/releases/download/$version/$filename" 46 | } 47 | 48 | function add_if_not_present() { 49 | local export_command=$1 50 | local file=$2 51 | if ! grep "$export_command" "$file" &> /dev/null; then 52 | echo "Adding path to ch to $file" 53 | echo -e "\n$export_command" >> "$file" 54 | fi 55 | } 56 | 57 | function add_to_path() { 58 | local location=$1 59 | if [ ! -d "$location" ]; then 60 | echo No such directory: "$location" 61 | exit 1 62 | fi 63 | 64 | # add to current profile 65 | export PATH="$PATH:$location" 66 | local export_command="export PATH=\"\$PATH:$location\"" 67 | 68 | if [ -e "$HOME/.zprofile" ] || [ "${SHELL##*/}" = "zsh" ]; then 69 | add_if_not_present "$export_command" "$HOME/.zprofile" 70 | add_if_not_present "$export_command" "$HOME/.zshrc" 71 | elif [ -e "$HOME/.bash_profile" ] || [ "${SHELL##*/}" = "bash" ]; then 72 | add_if_not_present "$export_command" "$HOME/.bash_profile" 73 | add_if_not_present "$export_command" "$HOME/.bashrc" 74 | else 75 | add_if_not_present "$export_command" "$HOME/.profile" 76 | fi 77 | } 78 | 79 | precheck 80 | 81 | version=$(get_latest_release $repository) 82 | architecture=$(uname -m) 83 | operating_system=$(uname) 84 | zip_filename= 85 | if [ "$operating_system" = "Linux" ] && { [ "$architecture" = "x86_64" ] || [ "$architecture" = "x86-64" ]; } then 86 | zip_filename="ch-linux-amd64.zip" 87 | elif [ "$operating_system" = "Linux" ] && [ "$architecture" = "aarch64" ]; then 88 | # aarch64 is supposedly the same as arm64 and containerd treats them the 89 | # same so we should be good 90 | # https://stackoverflow.com/a/47274698/4676641 91 | zip_filename="ch-linux-arm64.zip" 92 | elif [ "$operating_system" = "Darwin" ] && [ "$architecture" = "arm64" ]; then 93 | zip_filename="ch-darwin-arm64.zip" 94 | else 95 | zip_filename="ch-darwin-amd64.zip" 96 | fi 97 | 98 | release_url=$(get_release_url "$repository" "$version" "$zip_filename") 99 | get_release_package "$release_url" "$HOME" "$zip_filename" 100 | 101 | # remove downloaded zip file 102 | rm -f "$HOME/$zip_filename" 103 | 104 | # add directory to path if not already already present 105 | if ! echo "$PATH" | grep ${zip_filename%.*} > /dev/null ; then 106 | add_to_path "$HOME/${zip_filename%.*}" 107 | fi 108 | 109 | echo "Done! Try using ch with: ch --help" 110 | 111 | -------------------------------------------------------------------------------- /unix/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Go to docker folder 4 | cd "$(cd "$(dirname "$(dirname "${BASH_SOURCE[0]}")")" || return >/dev/null 2>&1 && pwd)" || return 5 | 6 | # Check for docker on path 7 | echo "Looking for docker..." 8 | command -v docker >/dev/null 2>&1 || { 9 | echo "Docker is not installed or available on path!" 10 | echo "Please make sure you have Docker installed before running this script" 11 | exit 1 12 | } 13 | 14 | echo "Looking for ch..." 15 | command -v ch >/dev/null 2>&1 || { 16 | echo "Installing ch..." 17 | . ./unix/install-ch.sh 18 | } 19 | 20 | # Get mount point 21 | echo "Preparing csci104 environment..." 22 | read -r -p "Select a directory to mount: " work 23 | 24 | while [[ ! -d "${work}" ]]; do 25 | echo "Invalid directory!" 26 | read -r -p "Select a directory to mount: " work 27 | done 28 | 29 | # Get absolute path of directory 30 | work="$(cd "${work}" || return; pwd -P)" 31 | echo "Mount point set, this can be changed later by editing $HOME/.ch.yaml..." 32 | 33 | # Create csci104 environment with ch CLI 34 | echo "Creating csci104 environment..." 35 | ch create csci104 --image usccsci104/docker:20.04 --shell /bin/bash --volume "$work:/work" --security-opt seccomp:unconfined --cap-add SYS_PTRACE --privileged --replace 36 | 37 | echo "Done!" 38 | 39 | file= 40 | if [ -e "$HOME/.bash_profile" ]; then 41 | file="~/.bash_profile" 42 | elif [ -e "$HOME/.zprofile" ]; then 43 | file="~/.zprofile" 44 | else 45 | file="~/.profile" 46 | fi 47 | 48 | echo -e "\nRemember to run this command to add ch to your path:\n source $file" -------------------------------------------------------------------------------- /windows/install-ch.ps1: -------------------------------------------------------------------------------- 1 | $program = "ch" 2 | $repository = "camerondurham/ch" 3 | $zip_filename = "ch-windows-amd64.zip" 4 | 5 | function Get-LatestReleaseVersion($repository) { 6 | # call with Get-LatestReleaseVersion("camerondurham/ch") 7 | $release_endpoint = "https://api.github.com/repos/$repository/releases/latest" 8 | $resp = Invoke-WebRequest -Uri $release_endpoint -UseBasicParsing 9 | $content = ConvertFrom-Json $resp.content 10 | return $content.tag_name 11 | } 12 | 13 | function Get-ReleasePackage($Url, $DownloadPath, $ExtractPath) { 14 | Invoke-WebRequest $Url -OutFile $DownloadPath 15 | Write-Output "Unpacking file" 16 | Expand-Archive -LiteralPath $DownloadPath -DestinationPath $ExtractPath -Force 17 | } 18 | 19 | function Get-ReleaseUrl($Repository, $Version, $Filename) { 20 | # repository: username/reponame format 21 | # example: camerondurham/ch 22 | # version: version tag to download 23 | # example: v0.0.6-beta 24 | # zip_filename: asset to download 25 | # example: ch-windows-amd64.zip 26 | "https://github.com/{0}/releases/download/{1}/{2}" -f $Repository.Trim(" "), $Version.Trim(" "), $Filename.Trim(" ") 27 | } 28 | 29 | function Add-ToPath($directory) { 30 | if (Test-Path $directory) { 31 | # add program binary location to path 32 | $path = [Environment]::GetEnvironmentVariable('Path') 33 | $newpath = "$path" + ";$directory" 34 | 35 | # set path for future sessions 36 | [Environment]::SetEnvironmentVariable('Path', $newpath, [EnvironmentVariableTarget]::User) 37 | 38 | # set path for current session 39 | $env:Path = $newpath 40 | } 41 | else { 42 | Write-Output "Invalid path [$directory] , ignoring..." 43 | } 44 | } 45 | 46 | $latest_version = Get-LatestReleaseVersion($repository) 47 | 48 | $download_url = Get-ReleaseUrl -Repository $repository -Version $latest_version -Filename $zip_filename 49 | 50 | $home_directory = [Environment]::GetFolderPath("USERPROFILE") 51 | 52 | Write-Output "Downloading $program version: $latest_version to $home_directory" 53 | 54 | $download_path = Join-Path -Path $home_directory -ChildPath $zip_filename 55 | $unpack_path = $home_directory 56 | 57 | Get-ReleasePackage -Url $download_url -DownloadPath $download_path -ExtractPath $unpack_path 58 | 59 | # remove zip file 60 | Remove-Item (Join-Path -Path $unpack_path -ChildPath $zip_filename) 61 | 62 | $unpacked_folder = $zip_filename.TrimEnd(".zip") 63 | $binary_location = Join-Path -Path $unpack_path -ChildPath $unpacked_folder 64 | 65 | # add directory to path if not already already added 66 | $found=([Environment]::GetEnvironmentVariable('Path') | Select-String -Pattern $unpacked_folder) 67 | if ([string]::IsNullOrEmpty($found)) { 68 | Add-ToPath $binary_location 69 | } 70 | 71 | 72 | Write-Output "Done! Try using ch with: ch --help" 73 | -------------------------------------------------------------------------------- /windows/setup.ps1: -------------------------------------------------------------------------------- 1 | Function Test-CommandExists ($command) { 2 | $oldPreference = $ErrorActionPreference 3 | $ErrorActionPreference = 'stop' 4 | try {if(Get-Command $command){ return $true }} 5 | catch { return $false } 6 | finally {$ErrorActionPreference=$oldPreference} 7 | } 8 | 9 | Write-Output "Looking for docker..." 10 | if (-Not (Test-CommandExists -command docker)) { 11 | Write-Output Docker is not installed or available on path! 12 | Write-Output Please make sure you have Docker installed before running this script 13 | exit 1 14 | } 15 | 16 | Write-Output "Looking for ch..." 17 | if (-Not (Test-CommandExists -command ch)) { 18 | Write-Output "Installing ch..." 19 | .\windows\install-ch.ps1 20 | } 21 | 22 | # Get mount point 23 | Write-Output "Preparing csci104 environment..." 24 | $work = Read-Host "Select a directory to mount " 25 | 26 | while (-Not (Test-Path -Path $work)) { 27 | $work = Read-Host "Select a directory to mount " 28 | } 29 | 30 | $work = Resolve-Path -Path $work 31 | $conf_path = Join-Path -Path ([Environment]::GetEnvironmentVariable("USERPROFILE")) -ChildPath ".ch.yaml" 32 | Write-Output "Mount point set, this can be changed later by editing $conf_path" 33 | 34 | # Create csci104 environment with ch CLI 35 | Write-Output "Creating csci104 environment..." 36 | ch create csci104 --image usccsci104/docker:20.04 --shell /bin/bash --volume ("{0}:/work" -f $work) --security-opt seccomp:unconfined --cap-add SYS_PTRACE --privileged --replace 37 | --------------------------------------------------------------------------------