Skip to content

Commit

Permalink
Merge pull request #1 from andygruber/develop
Browse files Browse the repository at this point in the history
Prepare first functioning version
  • Loading branch information
andygruber authored Nov 24, 2023
2 parents a142339 + d6953f7 commit 787cbb6
Show file tree
Hide file tree
Showing 6 changed files with 334 additions and 11 deletions.
131 changes: 131 additions & 0 deletions .github/workflows/generate-winccoa-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
name: Generate and upload WinCC OA image

on:
push:
branches: [ "main", "release/*", "develop", "develop/*" ]
# pull_request:
# branches: [ "main", "release/*", "develop", "develop/*" ]
release:
types: [published]

jobs:
get_environment:
runs-on: ubuntu-latest

steps:
- name: Define the used environment
id: env_check
run: |
ENV_NAME=staging
if [[ "${{ github.event_name }}" == "release" ]]; then
ENV_NAME=staging
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
ENV_NAME=staging
else
ENV_NAME=staging
fi
echo "Chosen environment: ${ENV_NAME}"
echo "env_name=${ENV_NAME}" >> $GITHUB_OUTPUT
outputs:
env_name: ${{ steps.env_check.outputs.env_name }}

generate-winccoa-image:
needs: [get_environment]
runs-on: ubuntu-latest
environment:
name: ${{ needs.get_environment.outputs.env_name }}

steps:
- name: Set up Git repository
uses: actions/checkout@v3

- name: Download current WinCC OA version
env:
ETM_USERNAME: ${{ secrets.ETM_USERNAME }}
ETM_PASSWORD: ${{ secrets.ETM_PASSWORD }}
run: scripts/download.sh

- name: Extract version information
id: get_version
run: |
zip_file=$(ls *.zip | head -n 1)
if [ -f "$zip_file" ]; then
echo "ZIP file found: $zip_file"
[[ $zip_file =~ ([0-9]+)\.([0-9]+)_linux_debian_x86_64_P([0-9]+)\.?([0-9]*)\.zip ]]
major_version=${BASH_REMATCH[1]}
minor_version=${BASH_REMATCH[2]}
patch_version=$(echo ${BASH_REMATCH[3]} | sed 's/^0*//') # Remove leading zeros
revision=${BASH_REMATCH[4]#\.} # Remove leading dot from the revision
if [ "$revision" != "0" ] && [ ! -z "$revision" ]; then
version_string="$major_version.$minor_version.$patch_version.$revision"
else
version_string="$major_version.$minor_version.$patch_version"
fi
echo "Version info found: ${version_string}"
echo "major_version=${major_version}" >> $GITHUB_OUTPUT
echo "minor_version=${minor_version}" >> $GITHUB_OUTPUT
echo "patch_version=${patch_version}" >> $GITHUB_OUTPUT
echo "revision=${revision}" >> $GITHUB_OUTPUT
echo "version=${version_string}" >> $GITHUB_OUTPUT
else
echo "No ZIP file found"
exit 1
fi
- name: Unzip data
run: |
mkdir data && cd data && \
unzip ../*.zip
- name: Prepare data for Docker image build
run: |
# copy files provided from WinCC OA package for our custom Docker build
cp data/docker-entrypoint.sh data/Dockerfile build-docker/
# patch Dockerfile so it does not copy and install the packages, but only does preparation
scripts/patchDockerfile.sh build-docker/Dockerfile
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Docker build setup
working-directory: ./build-docker
run: |
docker network create winccoarepo
docker compose up -d
# wait until repo data is generated
docker compose wait create-repo
- name: Docker build preparation image
working-directory: ./build-docker
run: |
DOCKER_BUILDKIT=0 docker build --no-cache --network=winccoarepo -t winccoaprepare:temp .
- name: Docker build and push images
working-directory: ./build-docker
run: |
# specify targets from Dockerfile_install here
for target in api server uiserver; do
tag_suffix=${target}
image_name="${DOCKER_IMAGE}:v${{ steps.get_version.outputs.version }}-${tag_suffix}"
DOCKER_BUILDKIT=0 docker build --network=winccoarepo --build-arg BASE_IMAGE=winccoaprepare:temp --target winccoa${target} --tag ${image_name} -f Dockerfile_install .
docker push ${image_name}
done
env:
DOCKER_IMAGE: ${{ vars.DOCKER_IMAGE }}

- name: Docker build teardown
working-directory: ./build-docker
run: |
docker compose down
docker network rm winccoarepo
88 changes: 88 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Documentation for "build-winccoa-docker-image" Repository

This repository hosts a GitHub Action workflow for
- downloading the current WinCC OA version from winccoa.com and
- generating and uploading Docker images of WinCC OA.

The workflow is defined in `.github\workflows\generate-winccoa-image.yml`.

## Setting Up

### Create environment
By default, for all workflow runs, an environment with the name `staging` is used.

Create all required environments and adapt the logic in the workflow (`get_environment -> env_check`) if you want to use multiple environments.

### Required Secrets
- `ETM_USERNAME`: Username for winccoa.com
- `ETM_PASSWORD`: Password for winccoa.com
- `DOCKER_USER`: DockerHub username
- `DOCKER_PASSWORD`: DockerHub password

### Required environment variables
- `DOCKER_IMAGE`: Name of the Docker image, e.g. `mydockerhubuser/winccoa`

### Triggering the Workflow
The workflow is triggered on:
- Push to `main`, `release/*`, `develop`, and `develop/*` branches.
- Published releases.

## Workflow Overview

### Get Environment
- **Environment Setup**: Gets the desired environment

### Preparation
- **Download Current WinCC OA Version**: Requires ETM_USERNAME and ETM_PASSWORD secrets for authentication​​
- **Extract Version Information**: Processes a ZIP filename to determine the WinCC OA version​​
- **Prepare Data for Docker Image Build**: Involves unzipping data and preparing it for Docker build​​.

### Docker Image Generation
- **Docker Setup**: Sets up Docker and builds a temporary image
- **Docker Build and Push Images**: Builds and pushes Docker images for different targets
- **Docker Build Teardown**: Tears down the Docker setup post-build​​

## Dockerfile Targets and Tags
The `build-docker/Dockerfile_install` includes targets like `api`, `server`, and `uiserver` with the prefix `winccoa`. Each target corresponds to a possible tag of the resulting Docker image.

The really built targets are defined in the step `Docker build and push images`.

### Modify or Add New Targets

1. **Adapt Dockerfile**: Define a new target in `build-docker/Dockerfile_install` in the form of `FROM <base> as winccoa<targetname>` or modify an existing one
2. **Edit Workflow File**: In the `.github/workflows` directory, open the workflow file `generate-winccoa-image.yml`
3. **Add/Modify Steps**:
- Under the `Docker build and push images` step, modify the list of targets in the for loop include your new target or modify the existing one.
- The default list defines the targets: `api server uiserver`

### Testing Your Changes
- It is highly recommended testing changes locally if possible, all docker commands can be run locally as well
- Once changes are verified locally, test the changes by triggering the workflow
- Monitor the build process to ensure your changes are correctly built and pushed

## Example
Given:
- Docker image base name: `mydockerhubuser/winccoa`
- Downloaded WinCC OA filename `WinCC_OA_3.19_linux_debian_x86_64_P007.zip`
- Extracted version: `3.19.7`
- List of targets: `api server uiserver`

Resulting Docker image names:
- `mydockerhubuser/winccoa:v3.19.7-api` from target `winccoaapi`
- `mydockerhubuser/winccoa:v3.19.7-server` from target `winccoaserver`
- `mydockerhubuser/winccoa:v3.19.7-uiserver` from target `winccoauiserver`

These images are built and pushed to DockerHub using the provided credentials.

## Contributing

Your contributions play a pivotal role in enhancing the open-source community, making it a hub for learning, inspiration, and innovation. Every contribution, big or small, is deeply appreciated.

**Steps to Contribute**:
1. Fork the Project.
2. Create your Feature Branch: `git checkout -b feature/YourFeatureName`.
3. Commit your Changes: `git commit -m 'Describe your change'`.
4. Push to the Branch: `git push origin feature/YourFeatureName`.
5. Open a Pull Request.

For suggestions or enhancements, either submit a pull request or open an issue with the "enhancement" tag. If you find value in this project, kindly star it. Your support means a lot to me!
25 changes: 25 additions & 0 deletions build-docker/Dockerfile_install
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# To change the base image please pass the desired value
# during the docker build, for example:
# docker build --build-arg BASE_IMAGE=customdockerregistry/baseimage:latest -t winccoa319 .
ARG BASE_IMAGE=winccoaprepare:temp
# Pass ARCH as prefix to BASE_IMAGE to explicitly set the used architecture.
# The image needs to be available under the resulting FROM argument and your
# environment needs to be able to run the architecture from the image
# docker build --build-arg ARCH=arm64v8/ -t arm64v8/winccoa319 .
ARG ARCH=
FROM ${ARCH}${BASE_IMAGE} as addedrepo

RUN echo 'deb [trusted=yes] http://repo-server/ /' | sudo tee -a /etc/apt/sources.list.d/build.list > /dev/null && \
sudo apt-get update

FROM addedrepo AS winccoabase
RUN sudo apt-get -y install winccoa-\*-base

FROM winccoabase AS winccoaapi
RUN sudo apt-get -y install winccoa-\*-apicpp

FROM winccoabase AS winccoaserver
RUN sudo apt-get -y install winccoa-\*-baseserver

FROM winccoaserver AS winccoauiserver
RUN sudo apt-get -y install winccoa-\*-baseui winccoa-\*-baseshortcuts winccoa-\*-desktopuiserver
41 changes: 41 additions & 0 deletions build-docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
version: "3"
services:
create-repo:
image: debian:bullseye-slim
restart: no
command: ['bash', '-c', 'apt-get update && apt-get -y install dpkg-dev gzip && cd /work/ && dpkg-scanpackages -m . | gzip > Packages.gz']
volumes:
- ../data/:/work/
repo-server:
image: nginx:latest
expose:
- "80"
volumes:
- ../data/:/usr/share/nginx/html/
# - ./file-listing.conf:/etc/nginx/conf.d/default.conf
networks:
- winccoarepo
depends_on:
- create-repo

# _winccoa_build:
# image: winccoa320
# command: ['echo', 'build completed'] # any linux command which directly terminates.
# build:
#context: winccoa/.
# network: repo-server
# args:
# BASE_IMAGE: artifactory.etm.at:8445/docker-winccoa/runtime/debian:bullseye-linux-amd64 # to speedup build a bit we use an image which already has most dependencies installed
# BASE_IMAGE: artifactory.etm.at:8445/docker-winccoa/build/debian:bullseye # for debugging we need to use a developer image
# volumes:
# - ../data/Dockerfile:/work/

networks:
winccoarepo:
driver: bridge
external: true
name: winccoarepo


# docker buildx create --use --name winccoabuilder --driver docker-container --driver-opt "network=winccoarepo"
# docker buildx
38 changes: 27 additions & 11 deletions scripts/download.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
#!/bin/bash

# File containing the HTML content
HTML_FILE="Downloads.html"

# Files containing the HTML content
HTML1_FILE="login.html"
HTML2_FILE="all319platforms.html"
HTML3_FILE="debiandownload.html"
# Define the base URL
BASE_URL="https://www.winccoa.com"

OUTPUT_FILE="WinCC_OA.zip"
echo "Login to ${BASE_URL}"
curl -o "$HTML1_FILE" -c cookie.txt -d "user=${ETM_USERNAME}&pass=${ETM_PASSWORD}&logintype=login" -X POST "${BASE_URL}/index.html?tx_felogin_login%5Baction%5D=login&amp;tx_felogin_login%5Bcontroller%5D=Login"

echo "Open main Downloadpage"
curl -o "$HTML2_FILE" -b cookie.txt "${BASE_URL}/downloads/category/wincc-oa-319.html"

PATCH_NUM="p007"
echo "Search for download link"
LINK=$(awk -v RS="</a>" '
/WinCC OA 3.19/ && /Debian 11 \(Bullseye\)/ && !/arm64/ {
match($0, /href="([^"]+)"/, arr)
if (arr[1] != "") {
print arr[1]
exit
}
}
' $HTML2_FILE | sed 's/\&amp;/\&/g')

curl -o "$HTML_FILE" -c cookie.txt -d "user=${USERNAME}&pass=${PASSWORD}&logintype=login" -X POST "${BASE_URL}/index.html?tx_felogin_login%5Baction%5D=login&amp;tx_felogin_login%5Bcontroller%5D=Login"
echo "Opening link: ${BASE_URL}/${LINK}"

curl -o "$HTML_FILE" -b cookie.txt "${BASE_URL}/downloads/detail/wincc-oa-319-${PATCH_NUM}-debian-11-bullseye.html"
curl -o "$HTML3_FILE" -b cookie.txt "${BASE_URL}/${LINK}"

# Extract the relative URL
RELATIVE_URL=$(grep "Download ZIP File" $HTML_FILE | grep -v "arm64" | sed -n 's/.*href="\([^"]*\).*/\1/p' | sed 's/\&amp;/\&/g')
RELATIVE_URL=$(grep "Download ZIP File" $HTML3_FILE | grep -v "arm64" | sed -n 's/.*href="\([^"]*\).*/\1/p' | sed 's/\&amp;/\&/g')

# Create the full URL
FULL_URL="${BASE_URL}${RELATIVE_URL}"

echo "Downloading $FULL_URL to $OUTPUT_FILE"
echo "Downloading $FULL_URL"
# Specify the output filename

# Download the file with verbose output
curl -o "$OUTPUT_FILE" -b cookie.txt "$FULL_URL"
# OUTPUT_FILE="WinCC_OA.zip"
# curl -o "$OUTPUT_FILE" -b cookie.txt "$FULL_URL"

echo "Downloaded to $OUTPUT_FILE"
# Download using original filename
curl -O -J -b cookie.txt "$FULL_URL" -w "%{filename_effective}"
22 changes: 22 additions & 0 deletions scripts/patchDockerfile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

# Check if a file path is provided
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <path_to_dockerfile>"
exit 1
fi

# File paths
original_dockerfile="$1"
backup_dockerfile="${original_dockerfile}.backup"

# Create a backup of the original Dockerfile
cp "$original_dockerfile" "$backup_dockerfile"

# Apply changes
sed -i '/^COPY \*.deb/s/^/#/' "$original_dockerfile"
sed -i '/^RUN find \/tmp\/deb\//s/^/#/' "$original_dockerfile"
sed -i '/^\s*-name \\\*.deb/s/^/#/' "$original_dockerfile"
sed -i '/^\s*-not -name/s/^/#/' "$original_dockerfile"
sed -i '/^\s*-exec apt-get install/s/^/#/' "$original_dockerfile"
sed -i '/^\s*apt-get clean/s/^/#/' "$original_dockerfile"

0 comments on commit 787cbb6

Please sign in to comment.