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

Prepare first functioning version #1

Merged
merged 13 commits into from
Nov 24, 2023
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
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"