diff --git a/.github/workflows/bake_to_latest.yml b/.github/workflows/bake_to_latest.yml
index 73a8c25..080afb2 100644
--- a/.github/workflows/bake_to_latest.yml
+++ b/.github/workflows/bake_to_latest.yml
@@ -1,10 +1,10 @@
-name: Build release-tags
+name: Build latest/main tags
on:
workflow_dispatch:
push:
branches:
- - master
+ - main
jobs:
bake-latest:
@@ -14,20 +14,20 @@ jobs:
contents: read
steps:
- name: Checkout
- uses: actions/checkout@v5
- - name: Set up QEMU
+ uses: actions/checkout@v6
+ - name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- - name: Set up Docker Buildx
+ - name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
- uses: docker/login-action@v1.10.0
+ uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
- uses: docker/login-action@v1.10.0
+ uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -39,10 +39,17 @@ jobs:
file: ./docker/docker-py3-kms/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
- tags: pykmsorg/py-kms:python3,ghcr.io/py-kms-organization/py-kms:python3
+ # the tag "python3" is for backward compatibility only
+ tags: |
+ pykmsorg/py-kms:main
+ ghcr.io/py-kms-organization/py-kms:main
+ pykmsorg/py-kms:main-full
+ ghcr.io/py-kms-organization/py-kms:main-full
+ pykmsorg/py-kms:python3
+ ghcr.io/py-kms-organization/py-kms:python3
build-args: |
BUILD_COMMIT=${{ github.sha }}
- BUILD_BRANCH=${{ github.ref_name }}
+ BUILD_REFERENCE=${{ github.ref_name }}
- name: Build (minimal)
uses: docker/build-push-action@v6
with:
@@ -50,7 +57,14 @@ jobs:
file: ./docker/docker-py3-kms-minimal/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
- tags: pykmsorg/py-kms:latest,ghcr.io/py-kms-organization/py-kms:latest,pykmsorg/py-kms:minimal,ghcr.io/py-kms-organization/py-kms:minimal
+ # the tag "minimal" is for backward compatibility only
+ tags: |
+ pykmsorg/py-kms:latest
+ ghcr.io/py-kms-organization/py-kms:latest
+ pykmsorg/py-kms:main-minimal
+ ghcr.io/py-kms-organization/py-kms:main-minimal
+ pykmsorg/py-kms:minimal
+ ghcr.io/py-kms-organization/py-kms:minimal
build-args: |
BUILD_COMMIT=${{ github.sha }}
- BUILD_BRANCH=${{ github.ref_name }}
+ BUILD_REFERENCE=${{ github.ref_name }}
diff --git a/.github/workflows/bake_to_next.yml b/.github/workflows/bake_to_next.yml
index 99032e0..b3128a3 100644
--- a/.github/workflows/bake_to_next.yml
+++ b/.github/workflows/bake_to_next.yml
@@ -1,4 +1,4 @@
-name: Build next-tags
+name: Build next tags
on:
workflow_dispatch:
@@ -14,20 +14,20 @@ jobs:
contents: read
steps:
- name: Checkout
- uses: actions/checkout@v5
- - name: Set up QEMU
+ uses: actions/checkout@v6
+ - name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- - name: Set up Docker Buildx
+ - name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
- uses: docker/login-action@v1.10.0
+ uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
- uses: docker/login-action@v1.10.0
+ uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -39,10 +39,17 @@ jobs:
file: ./docker/docker-py3-kms/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
- tags: pykmsorg/py-kms:python3-next,ghcr.io/py-kms-organization/py-kms:python3-next
+ # the tag "python3-next" is for backward compatibility only
+ tags: |
+ pykmsorg/py-kms:next
+ ghcr.io/py-kms-organization/py-kms:next
+ pykmsorg/py-kms:next-full
+ ghcr.io/py-kms-organization/py-kms:next-full
+ pykmsorg/py-kms:python3-next
+ ghcr.io/py-kms-organization/py-kms:python3-next
build-args: |
BUILD_COMMIT=${{ github.sha }}
- BUILD_BRANCH=${{ github.ref_name }}
+ BUILD_REFERENCE=${{ github.ref_name }}
- name: Build (minimal)
uses: docker/build-push-action@v6
with:
@@ -50,7 +57,14 @@ jobs:
file: ./docker/docker-py3-kms-minimal/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
- tags: pykmsorg/py-kms:latest-next,ghcr.io/py-kms-organization/py-kms:latest-next,pykmsorg/py-kms:minimal-next,ghcr.io/py-kms-organization/py-kms:minimal-next
+ # the tag "latest-next" and "minimal-next" are for backward compatibility only
+ tags: |
+ pykmsorg/py-kms:next-minimal
+ ghcr.io/py-kms-organization/py-kms:next-minimal
+ pykmsorg/py-kms:latest-next
+ ghcr.io/py-kms-organization/py-kms:latest-next
+ pykmsorg/py-kms:minimal-next
+ ghcr.io/py-kms-organization/py-kms:minimal-next
build-args: |
BUILD_COMMIT=${{ github.sha }}
- BUILD_BRANCH=${{ github.ref_name }}
+ BUILD_REFERENCE=${{ github.ref_name }}
diff --git a/.github/workflows/bake_to_version.yml b/.github/workflows/bake_to_version.yml
new file mode 100644
index 0000000..7b13841
--- /dev/null
+++ b/.github/workflows/bake_to_version.yml
@@ -0,0 +1,62 @@
+name: Build version tags
+
+on:
+ workflow_dispatch:
+ push:
+ tags:
+ - "v*"
+
+jobs:
+ bake-latest:
+ runs-on: ubuntu-latest
+ permissions:
+ packages: write
+ contents: read
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ - name: Docker Setup QEMU
+ uses: docker/setup-qemu-action@v3
+ with:
+ platforms: all
+ - name: Docker Setup Buildx
+ uses: docker/setup-buildx-action@v3
+ - name: Login to DockerHub
+ uses: docker/login-action@v3
+ with:
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+ - name: Login to GitHub Container Registry
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: Build (full)
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: ./docker/docker-py3-kms/Dockerfile
+ platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
+ push: true
+ tags: |
+ pykmsorg/py-kms:${{ github.ref_name }}-full
+ ghcr.io/py-kms-organization/py-kms:${{ github.ref_name }}-full
+ build-args: |
+ BUILD_COMMIT=${{ github.sha }}
+ BUILD_REFERENCE=${{ github.ref_name }}
+ - name: Build (minimal)
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: ./docker/docker-py3-kms-minimal/Dockerfile
+ platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
+ push: true
+ tags: |
+ pykmsorg/py-kms:${{ github.ref_name }}
+ ghcr.io/py-kms-organization/py-kms:${{ github.ref_name }}
+ pykmsorg/py-kms:${{ github.ref_name }}-minimal
+ ghcr.io/py-kms-organization/py-kms:${{ github.ref_name }}-minimal
+ build-args: |
+ BUILD_COMMIT=${{ github.sha }}
+ BUILD_REFERENCE=${{ github.ref_name }}
diff --git a/.github/workflows/test_basic_client.yml b/.github/workflows/test_basic_client.yml
new file mode 100644
index 0000000..2f6628d
--- /dev/null
+++ b/.github/workflows/test_basic_client.yml
@@ -0,0 +1,27 @@
+name: "Test: Basic Client"
+
+on:
+ workflow_dispatch:
+ push:
+
+jobs:
+ run-test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: "3.11"
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r requirements.txt
+ - name: Run tests
+ run: |
+ cd py-kms; timeout 30 python3 pykms_Server.py -F STDOUT -s ./pykms_database.db &
+ sleep 5
+ python3 pykms_Client.py -F STDOUT # fresh client
+ python3 pykms_Client.py -F STDOUT -c 174f5409-0624-4ce3-b209-adde1091956b # (maybe) existing client
+ python3 pykms_Client.py -F STDOUT -c 174f5409-0624-4ce3-b209-adde1091956b # now-for-sure existing client
diff --git a/.github/workflows/bake_to_test.yml b/.github/workflows/test_image_build.yml
similarity index 79%
rename from .github/workflows/bake_to_test.yml
rename to .github/workflows/test_image_build.yml
index 72fc196..0d8f072 100644
--- a/.github/workflows/bake_to_test.yml
+++ b/.github/workflows/test_image_build.yml
@@ -1,4 +1,4 @@
-name: Test-Build Docker Image
+name: "Test: Build Docker Image"
on:
workflow_dispatch:
@@ -9,12 +9,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v5
- - name: Set up QEMU
+ uses: actions/checkout@v6
+ - name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- - name: Set up Docker Buildx
+ - name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Build (full)
uses: docker/build-push-action@v6
@@ -25,7 +25,7 @@ jobs:
push: false
build-args: |
BUILD_COMMIT=${{ github.sha }}
- BUILD_BRANCH=${{ github.ref_name }}
+ BUILD_REFERENCE=${{ github.ref_name }}
- name: Build (minimal)
uses: docker/build-push-action@v6
with:
@@ -35,4 +35,4 @@ jobs:
push: false
build-args: |
BUILD_COMMIT=${{ github.sha }}
- BUILD_BRANCH=${{ github.ref_name }}
+ BUILD_REFERENCE=${{ github.ref_name }}
diff --git a/README.md b/README.md
index 8eb8138..34e0cbd 100644
--- a/README.md
+++ b/README.md
@@ -1,48 +1,36 @@
-# Readme
+# py-kms
+


-
+


-***
-_Keep in mind that this project is not intended for production use. Feel free to use it to test your own systems or maybe even learn something from the protocol structure. :)_
+_Keep in mind that this project is not intended for production use. Feel free to use it to test your own systems or maybe even learn something from the protocol structure._ 😉
## History
_py-kms_ is a port of node-kms created by [cyrozap](http://forums.mydigitallife.info/members/183074-markedsword), which is a port of either the C#, C++, or .NET implementations of KMS Emulator. The original version was written by [CODYQX4](http://forums.mydigitallife.info/members/89933-CODYQX4) and is derived from the reverse-engineered code of Microsoft's official KMS.
This version of _py-kms_ is for itself a fork of the original implementation by [SystemRage](https://github.com/SystemRage/py-kms), which was abandoned early 2021.
+### What is with version `1.0.0`?
+Semantic versioning is now being used in this project, so checkout the [GitHub Releases](https://github.com/Py-KMS-Organization/py-kms/releases). Before, a `CHANGELOG.md` file was used to track changes, but got abandoned over time. Its content got moved into the [Historic Releases](docs/Historic%20Releases.md) document for reference.
+
## Features
- Responds to `v4`, `v5`, and `v6` KMS requests.
-- Supports activating:
- - Windows Vista
- - Windows 7
- - Windows 8
- - Windows 8.1
- - Windows 10 ( 1511 / 1607 / 1703 / 1709 / 1803 / 1809 )
- - Windows 10 ( 1903 / 1909 / 20H1, 20H2, 21H1, 21H2 )
- - Windows 11 ( 21H2 )
- - Windows Server 2008
- - Windows Server 2008 R2
- - Windows Server 2012
- - Windows Server 2012 R2
- - Windows Server 2016
- - Windows Server 2019
- - Windows Server 2022
- - Microsoft Office 2010 ( Volume License )
- - Microsoft Office 2013 ( Volume License )
- - Microsoft Office 2016 ( Volume License )
- - Microsoft Office 2019 ( Volume License )
- - Microsoft Office 2021 ( Volume License )
- - It's written in Python (tested with Python 3.10.1).
+- Supports activating [a lot of products](docs/Keys.md), so checkout the docs for more information.
+ - It's written in Python.
- Supports execution by `Docker`, `systemd` and many more...
- Uses `sqlite` for persistent data storage (with a simple web-based explorer).
## Documentation
-The wiki has been completly reworked and is now available on [readthedocs.io](https://py-kms.readthedocs.io/en/latest/). It should provide you all the necessary information about how to setup and to use _py-kms_ , all without clumping this readme. The documentation also houses more details about activation with _py-kms_ and how to get GVLK keys.
+The wiki has been completely reworked and is now available on [readthedocs.io](https://py-kms.readthedocs.io/en/latest/). It should provide you all the necessary information about how to setup and to use _py-kms_, all without clumping this readme. The documentation also houses more details about the activation procedure with _py-kms_ and how to get GVLK keys.
## Quick start
-- To start the server, execute `python3 pykms_Server.py [IPADDRESS] [PORT]`, the default _IPADDRESS_ is `::` ( all interfaces ) and the default _PORT_ is `1688`. Note that both the address and port are optional. It's allowed to use IPv4 and IPv6 addresses. If you have a IPv6-capable dual-stack OS, a dual-stack socket is created when using a IPv6 address. **In case your OS does not support IPv6, make sure to explicitly specify the legacy IPv4 of `0.0.0.0`!**
+- To start the server, execute `python3 pykms_Server.py [IPADDRESS] [PORT]`, the default _IPADDRESS_ is `::` ( all interfaces ) and the default _PORT_ is `1688`.
+ - Note that both the address and port are optional.
+ - It's allowed to use IPv4 and IPv6 addresses.
+ - If you have an IPv6-capable dual-stack OS, a dual-stack socket is created when using a IPv6 address.
+ - **[In case your OS does not support IPv6](https://github.com/Py-KMS-Organization/py-kms/issues/108), make sure to explicitly specify the legacy IPv4 of `0.0.0.0`!**
- To start the server automatically using Docker, execute `docker run -d --name py-kms --restart always -p 1688:1688 ghcr.io/py-kms-organization/py-kms`.
- To show the help pages type: `python3 pykms_Server.py -h` and `python3 pykms_Client.py -h`.
diff --git a/docker/docker-py3-kms-minimal/Dockerfile b/docker/docker-py3-kms-minimal/Dockerfile
index 1807b37..64204e5 100644
--- a/docker/docker-py3-kms-minimal/Dockerfile
+++ b/docker/docker-py3-kms-minimal/Dockerfile
@@ -9,7 +9,7 @@ ENV LCID=1033
ENV CLIENT_COUNT=26
ENV ACTIVATION_INTERVAL=120
ENV RENEWAL_INTERVAL=10080
-ENV HWID RANDOM
+ENV HWID=RANDOM
ENV LOGLEVEL=INFO
ENV LOGFILE=STDOUT
ENV LOGSIZE=""
@@ -36,11 +36,10 @@ COPY docker/start.py /usr/bin/start.py
RUN chmod 555 /usr/bin/entrypoint.py /usr/bin/healthcheck.py /usr/bin/start.py
# Additional permission hardening: All files read-only for the executing user
-RUN chown root: -R /home/py-kms && \
- chmod 444 -R /home/py-kms && \
- chown py-kms: /home/py-kms && \
- chmod 700 /home/py-kms && \
- find /home/py-kms -type d -print -exec chmod +x {} ';'
+RUN find /home/py-kms -type f -print -exec chmod 444 {} ';' && \
+ find /home/py-kms -type d -print -exec chmod 555 {} ';' && \
+ chown root: -R /home/py-kms && \
+ chown py-kms: /home/py-kms
WORKDIR /home/py-kms
diff --git a/docker/docker-py3-kms/Dockerfile b/docker/docker-py3-kms/Dockerfile
index 547171b..836fe74 100644
--- a/docker/docker-py3-kms/Dockerfile
+++ b/docker/docker-py3-kms/Dockerfile
@@ -2,7 +2,7 @@
FROM alpine:3.22
ARG BUILD_COMMIT=unknown
-ARG BUILD_BRANCH=unknown
+ARG BUILD_REFERENCE=unknown
ENV IP=::
ENV DUALSTACK=1
@@ -29,7 +29,7 @@ RUN apk add --no-cache --update \
tzdata \
shadow \
&& pip3 install --break-system-packages --no-cache-dir -r /home/py-kms/requirements.txt \
- && mkdir /db/ \
+ && mkdir /db/ /home/py-kms/db \
&& adduser -S py-kms -G users -s /bin/bash \
&& chown py-kms:users /home/py-kms \
# Fix undefined timezone, in case the user did not mount the /etc/localtime
@@ -41,16 +41,17 @@ COPY docker/healthcheck.py /usr/bin/healthcheck.py
COPY docker/start.py /usr/bin/start.py
RUN chmod 555 /usr/bin/entrypoint.py /usr/bin/healthcheck.py /usr/bin/start.py
-# Additional permission hardening: All files read-only for the executing user
-RUN chown root: -R /home/py-kms && \
- chmod 444 -R /home/py-kms && \
+# Additional permission hardening: keep application files read-only, but preserve
+# a dedicated writable database directory for WebUI/SQLite at runtime.
+RUN find /home/py-kms -type f -print -exec chmod 444 {} ';' && \
+ find /home/py-kms -type d -print -exec chmod 555 {} ';' && \
+ chown root: -R /home/py-kms && \
chown py-kms: /home/py-kms && \
- chmod 700 /home/py-kms && \
- find /home/py-kms -type d -print -exec chmod +x {} ';'
+ chmod 1777 /home/py-kms/db
# Web-interface specifics
COPY LICENSE /LICENSE
-RUN echo "$BUILD_COMMIT" > /VERSION && echo "$BUILD_BRANCH" >> /VERSION
+RUN echo "$BUILD_COMMIT" > /VERSION && echo "$BUILD_REFERENCE" >> /VERSION
WORKDIR /home/py-kms
diff --git a/docker/entrypoint.py b/docker/entrypoint.py
index b564966..e920110 100755
--- a/docker/entrypoint.py
+++ b/docker/entrypoint.py
@@ -15,15 +15,20 @@ PYTHON3 = '/usr/bin/python3'
dbPath = os.path.join(os.sep, 'home', 'py-kms', 'db') # Do not include the database file name, as we must correct the folder permissions (the db file is recursively reachable)
def change_uid_grp(logger):
- if os.geteuid() != 0:
- logger.info(f'not root user, cannot change uid/gid.')
- return None
user_db_entries = pwd.getpwnam("py-kms")
user_grp_db_entries = grp.getgrnam("users")
- uid = int(user_db_entries.pw_uid)
- gid = int(user_grp_db_entries.gr_gid)
- new_gid = int(os.getenv('GID', str(gid)))
- new_uid = int(os.getenv('UID', str(uid)))
+ now_uid = os.geteuid() # as what are we running effectively right now?
+ now_gid = os.getegid()
+ ebd_uid = int(user_db_entries.pw_uid) # what was compiled (embedded) into the image?
+ ebd_gid = int(user_grp_db_entries.gr_gid)
+ new_gid = int(os.getenv('GID', str(ebd_gid))) # what is desired by the user at runtime?
+ new_uid = int(os.getenv('UID', str(ebd_uid)))
+ if now_uid == new_uid and now_gid == new_gid:
+ logger.info(f'UID/GID already set to {new_uid}:{new_gid}')
+ return None
+ if now_uid != 0:
+ logger.warning(f'Not root user (UID is {now_uid}), cannot change UID/GID to {new_uid}:{new_gid}!')
+ return None
os.chown("/home/py-kms", new_uid, new_gid)
os.chmod("/home/py-kms", 0o700)
if os.path.isdir(dbPath):
@@ -50,9 +55,8 @@ def change_uid_grp(logger):
os.chmod(os.environ['LOGFILE'], 0o777)
logger.error(str(subprocess.check_output(['ls', '-la', os.environ['LOGFILE']])))
# Drop actual permissions
- logger.info(f"Setting gid to {new_gid}")
+ logger.info(f"Setting UID/GID to {new_uid}:{new_gid}")
os.setgid(new_gid)
- logger.info(f"Setting uid to {new_uid}")
os.setuid(new_uid)
def change_tz(logger):
@@ -75,7 +79,7 @@ if __name__ == "__main__":
streamhandler.setFormatter(formatter)
loggersrv.addHandler(streamhandler)
loggersrv.info("Log level: %s" % log_level)
- loggersrv.debug("user id: %s" % os.getuid())
+ loggersrv.debug("Running as UID/GID %s:%s" % (os.geteuid(), os.getegid()))
change_tz(loggersrv)
childProcess = subprocess.Popen(PYTHON3 + " -u /usr/bin/start.py", preexec_fn=change_uid_grp(loggersrv), shell=True)
diff --git a/docker/start.py b/docker/start.py
index 5b192fe..4feceab 100755
--- a/docker/start.py
+++ b/docker/start.py
@@ -72,9 +72,12 @@ def start_kms(logger):
pass
except KeyboardInterrupt:
pass
+ logger.info("Shutting down...")
if pykms_webui_process:
+ logger.debug("Terminating webui process...")
pykms_webui_process.terminate()
+ logger.debug("Terminating KMS process...")
pykms_process.terminate()
@@ -90,6 +93,7 @@ if __name__ == "__main__":
formatter = logging.Formatter(fmt='\x1b[94m%(asctime)s %(levelname)-8s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S')
streamhandler.setFormatter(formatter)
loggersrv.addHandler(streamhandler)
- loggersrv.debug("user id: %s" % os.getuid())
+ loggersrv.info("Log level: %s" % log_level)
+ loggersrv.debug("Running as UID/GID %s:%s" % (os.geteuid(), os.getegid()))
start_kms(loggersrv)
diff --git a/docs/Contributing.md b/docs/Contributing.md
index 6718bae..6ab49ca 100644
--- a/docs/Contributing.md
+++ b/docs/Contributing.md
@@ -3,7 +3,7 @@
You want to improve this project?
Awesome! But before you write or modify the existing source code, please note the following guideline:
-- Always make sure to add your changes to the wiki.
+- Always base your branch on the latest `next` branch to avoid merge conflicts.
- 8-space indentation without tabs.
- Docstrings as this:
```python
@@ -13,3 +13,14 @@ Awesome! But before you write or modify the existing source code, please note th
```
- Wrap lines only if really long (it does not matter 79 chars return)
- For the rest a bit as it comes with a look at [PEP8](https://www.python.org/dev/peps/pep-0008/) :)
+
+Test your changes, please. For example, run the server via:
+```bash
+python3 pykms_Server.py -F STDOUT -s ./pykms_database.db
+```
+Then trigger (multiple) client requests and check the output for errors via:
+```bash
+python3 pykms_Client.py -F STDOUT # fresh client
+python3 pykms_Client.py -F STDOUT -c 174f5409-0624-4ce3-b209-adde1091956b # (maybe) existing client
+python3 pykms_Client.py -F STDOUT -c 174f5409-0624-4ce3-b209-adde1091956b # now-for-sure existing client
+```
diff --git a/docs/Getting Started.md b/docs/Getting Started.md
index 54d2b08..61a9776 100644
--- a/docs/Getting Started.md
+++ b/docs/Getting Started.md
@@ -14,7 +14,7 @@ command will download, "install" and start _py-kms_ and also keep it alive after
```bash
docker run -d --name py-kms --restart always -p 1688:1688 -v /etc/localtime:/etc/localtime:ro ghcr.io/py-kms-organization/py-kms
```
-If you just want to use the image and don't want to build them yourself, you can always use the official image at the [GitHub Container Registry](https://github.com/Py-KMS-Organization/py-kms/pkgs/container/py-kms) (`ghcr.io/py-kms-organization/py-kms`). To ensure that you are using always the latest version you should check something like [watchtower](https://github.com/containrrr/watchtower) out!
+If you just want to use the image and don't want to build them yourself, you can always use the official image at the [GitHub Container Registry](https://github.com/Py-KMS-Organization/py-kms/pkgs/container/py-kms) (`ghcr.io/py-kms-organization/py-kms`). To ensure that you are using always the latest version you should check something like [watchtower](https://github.com/nicholas-fedor/watchtower/) out!
#### Tags
There are currently three tags of the image available (select one just by appending `:
This instance is running version "{{ version_info['hash'] }}" from branch "{{ version_info['branch'] }}" of py-kms.
+
This instance is running version "{{ version_info['hash'] }}" from Git "{{ version_info['reference'] }}" of py-kms.
{% endif %}
{{ client.clientMachineId }}{{ client.clientMachineId }}
+ Whoops?
{% endif %} {% endif %} -{% endblock %} \ No newline at end of file +{% endblock %}