diff --git a/.github/workflows/roverlight-build.yml b/.github/workflows/roverlight-build.yml new file mode 100644 index 00000000..6a3ab6ba --- /dev/null +++ b/.github/workflows/roverlight-build.yml @@ -0,0 +1,57 @@ +name: Roverlight-Test-Build-On-PR + +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + platform: [linux/amd64, linux/arm64] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-${{ matrix.platform }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-${{ matrix.platform }}-buildx- + + - name: Generate tags + id: tag + run: echo "date=$(date +'%g%m.%d%H%M')" >> $GITHUB_OUTPUT + + - name: Test Building + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile.roverlight + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache + push: false + load: true + tags: roverlight:${{ steps.tag.outputs.date }}, roverlight:latest_test + platforms: ${{ matrix.platform }} + + - name: Scan container + uses: anchore/scan-action@v3 + id: scan + with: + image: roverlight:${{ steps.tag.outputs.date }} + severity-cutoff: critical + + - name: Upload scan SARIF report + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: ${{ steps.scan.outputs.sarif }} \ No newline at end of file diff --git a/.github/workflows/roverlight-release.yml b/.github/workflows/roverlight-release.yml new file mode 100644 index 00000000..5c0a1744 --- /dev/null +++ b/.github/workflows/roverlight-release.yml @@ -0,0 +1,80 @@ +name: Roverlight-Build-On-Release + +on: + release: + types: [created] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + attestations: write + + strategy: + matrix: + platform: [linux/amd64, linux/arm64] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-${{ matrix.platform }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-${{ matrix.platform }}-buildx- + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate tags + id: tag + run: echo "date=$(date +'%g%m.%d%H%M')" >> $GITHUB_OUTPUT + + - name: Building roverlight + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile.roverlight + push: true + load: true + tags: ghcr.io/${{ github.repository }}/roverlight:${{ steps.tag.outputs.date }}, ghcr.io/${{ github.repository }}/roverlight:latest + platforms: ${{ matrix.platform }} + + - name: Scan container + uses: anchore/scan-action@v3 + id: scan + with: + image: ghcr.io/${{ github.repository }}/roverlight:latest + severity-cutoff: critical + + - name: Upload scan SARIF report + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: ${{ steps.scan.outputs.sarif }} + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true \ No newline at end of file diff --git a/Dockerfile.roverlight b/Dockerfile.roverlight new file mode 100644 index 00000000..9d68958c --- /dev/null +++ b/Dockerfile.roverlight @@ -0,0 +1,141 @@ +########################################################### +# base tools and dependencies +########################################################### +FROM --platform=${TARGETPLATFORM} ubuntu as base + +ARG SSH_PASSWD TARGETARCH TARGETOS +ARG USERNAME=vscode +ARG USER_UID=1001 +ARG USER_GID=${USER_UID} + +ENV SSH_PASSWD=${SSH_PASSWD} \ + USERNAME=${USERNAME} \ + PATH="${PATH}:/opt/mssql-tools/bin:/home/vscode/.local/lib/shellspec/bin:/home/vscode/go/bin:/usr/local/go/bin" \ + TF_DATA_DIR="/home/${USERNAME}/.terraform.cache" \ + TF_PLUGIN_CACHE_DIR="/tf/cache" \ + TF_REGISTRY_DISCOVERY_RETRY=5 \ + TF_REGISTRY_CLIENT_TIMEOUT=15 \ + ARM_USE_MSGRAPH=true \ + LANG=en_US.UTF-8 \ + LANGUAGE=en_US:en \ + LC_ALL=en_US.UTF-8 + +WORKDIR /tf/rover +COPY ./scripts/.kubectl_aliases . +COPY ./scripts/zsh-autosuggestions.zsh . + + # installation common tools +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + apt-transport-https \ + apt-utils \ + bsdmainutils \ + ca-certificates \ + curl \ + fonts-powerline \ + gettext \ + git \ + gpg \ + gpg-agent \ + jq \ + less \ + locales \ + sudo \ + unzip \ + vim \ + wget \ + zip && \ + # + # Create USERNAME + # + echo "Creating ${USERNAME} user..." && \ + groupadd docker && \ + useradd --uid $USER_UID -m -G docker ${USERNAME} && \ + # + # Set the locale + locale-gen en_US.UTF-8 && \ + # Change ownership on the plugin cache directory + mkdir /tf/cache && \ + chown -R ${USERNAME}:${USERNAME} ${TF_PLUGIN_CACHE_DIR} && \ + # + # Create USERNAME home folder structure + # + mkdir -p /tf/caf \ + /tf/rover \ + /tf/logs \ + /home/${USERNAME}/.ansible \ + /home/${USERNAME}/.azure \ + /home/${USERNAME}/.gnupg \ + /home/${USERNAME}/.packer.d \ + /home/${USERNAME}/.ssh \ + /home/${USERNAME}/.ssh-localhost \ + /home/${USERNAME}/.terraform.logs \ + /home/${USERNAME}/.terraform.cache \ + /home/${USERNAME}/.terraform.cache/tfstates \ + /home/${USERNAME}/.vscode-server \ + /home/${USERNAME}/.vscode-server-insiders && \ + chown -R ${USER_UID}:${USER_GID} /home/${USERNAME} /tf/rover /tf/caf /tf/logs && \ + chmod 777 -R /home/${USERNAME} /tf/caf /tf/rover && \ + chmod 700 /home/${USERNAME}/.ssh && \ + echo ${USERNAME} ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/${USERNAME} && \ + chmod 0440 /etc/sudoers.d/${USERNAME} && \ + # for non-root user + mkdir /commandhistory && \ + touch /commandhistory/.bash_history && \ + chown -R ${USERNAME} /commandhistory && \ + echo "set -o history" >> "/home/${USERNAME}/.bashrc" && \ + echo "export HISTCONTROL=ignoredups:erasedups" >> "/home/${USERNAME}/.bashrc" && \ + echo "PROMPT_COMMAND=\"${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r\"" >> "/home/${USERNAME}/.bashrc" && \ + echo "[ -f /tf/rover/.kubectl_aliases ] && source /tf/rover/.kubectl_aliases" >> "/home/${USERNAME}/.bashrc" && \ + echo "alias watch=\"watch \"" >> "/home/${USERNAME}/.bashrc" && \ + # + # Clean-up + # + apt-get remove -y \ + apt-utils && \ + apt-get autoremove -y && \ + apt-get clean && \ + rm -rf /tmp/* && \ + rm -rf /var/lib/apt/lists/* && \ + find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf + +# +# Switch to non-root ${USERNAME} context +# + +USER ${USERNAME} + +COPY .devcontainer/.zshrc $HOME +COPY ./scripts/sshd_config /home/${USERNAME}/.ssh/sshd_config + +RUN sudo apt-get update && \ + sudo apt-get install -y \ + zsh && \ + # + # Install Oh My Zsh + # + sudo runuser -l ${USERNAME} -c 'sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended' && \ + chmod 700 -R /home/${USERNAME}/.oh-my-zsh && \ + echo "DISABLE_UNTRACKED_FILES_DIRTY=\"true\"" >> /home/${USERNAME}/.zshrc && \ + echo "alias rover=/tf/rover/rover.sh" >> /home/${USERNAME}/.bashrc && \ + echo "alias rover=/tf/rover/rover.sh" >> /home/${USERNAME}/.zshrc && \ + echo "cd /tf/caf || true" >> /home/${USERNAME}/.bashrc && \ + echo "cd /tf/caf || true" >> /home/${USERNAME}/.zshrc && \ + echo "[ -f /tf/rover/.kubectl_aliases ] && source /tf/rover/.kubectl_aliases" >> /home/${USERNAME}/.zshrc && \ + echo "source /tf/rover/zsh-autosuggestions.zsh" >> /home/${USERNAME}/.zshrc && \ + echo "alias watch=\"watch \"" >> /home/${USERNAME}/.zshrc + +FROM base + +ARG USERNAME=vscode \ + versionRover + +ENV versionRover=${versionRover} + +RUN echo "Set rover version to ${versionRover}..." && \ + echo "${versionRover}" > /tf/rover/version.txt + +COPY ./scripts/rover.sh ./scripts/tfstate.sh ./scripts/functions.sh ./scripts/remote.sh ./scripts/parse_command.sh ./scripts/banner.sh ./scripts/clone.sh ./scripts/walkthrough.sh ./scripts/sshd.sh ./scripts/backend.hcl.tf ./scripts/backend.azurerm.tf ./scripts/ci.sh ./scripts/cd.sh ./scripts/task.sh ./scripts/symphony_yaml.sh ./scripts/test_runner.sh ./ +COPY ./scripts/ci_tasks/* ./ci_tasks/ +COPY ./scripts/lib/* ./lib/ +COPY ./scripts/tfcloud/* ./tfcloud/ \ No newline at end of file diff --git a/docker-bake.hcl b/docker-bake.hcl index 7d6d2f62..a09376b1 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -8,12 +8,12 @@ # group "default" { - targets = ["rover_local", "rover_agents"] + targets = ["rover_local", "roverlight"] } target "rover_local" { dockerfile = "./Dockerfile" - tags = ["${tag}"] + tags = ["rover_local:${tag}"] args = { extensionsAzureCli = extensionsAzureCli versionDockerCompose = versionDockerCompose @@ -30,9 +30,19 @@ target "rover_local" { versionTerrascan = versionTerrascan versionTfupdate = versionTfupdate } - platforms = ["linux/amd64","linux/arm64" ] - cache-to = ["type=local,dest=/tmp/.buildx-cache,mode=max"] - cache-from = ["type=local,src=/tmp/.buildx-cache"] + platforms = ["linux/arm64", "linux/amd64" ] + # cache-to = ["type=local,dest=/tmp/.buildx-cache,mode=max"] + # cache-from = ["type=local,src=/tmp/.buildx-cache"] +} + +target "roverlight" { + dockerfile = "./Dockerfile.roverlight" + tags = [ + "roverlight:${tag}" + ] + args = { + } + platforms = ["linux/arm64", "linux/amd64" ] } target "rover_registry" { @@ -43,18 +53,22 @@ target "rover_registry" { } } + variable "registry" { - default = "" + default = "" } +# The tag variable is used to set the tag for the Docker image. variable "tag" { - default = "latest" + default = "latest" } +# The versionRover variable is used to set the version of the Rover. variable "versionRover" { - default = "" + default = "" } +# The versionTerraform variable is used to set the version of Terraform. variable "versionTerraform" { - default = "" + default = "" } \ No newline at end of file