refactor: more containerization
authorRuben ten Hove <redacted>
Tue, 5 Jul 2022 16:39:02 +0000 (12:39 -0400)
committerRuben ten Hove <redacted>
Tue, 5 Jul 2022 16:39:02 +0000 (12:39 -0400)
.dockerignore [new file with mode: 0644]
.github/workflows/container.yml [new file with mode: 0644]
Dockerfile
readme_template.md
updateHostsFile.py [changed mode: 0644->0755]
updateHostsWindows.bat [changed mode: 0644->0755]
updateReadme.py [changed mode: 0644->0755]

diff --git a/.dockerignore b/.dockerignore
new file mode 100644 (file)
index 0000000..e27f1a0
--- /dev/null
@@ -0,0 +1,7 @@
+*
+!updateHostsFile.py
+!data
+!alternates
+!extensions
+!readmeData.json
+!requirements.txt
diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml
new file mode 100644 (file)
index 0000000..0b4e541
--- /dev/null
@@ -0,0 +1,43 @@
+# Based on https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#publishing-a-package-using-an-action
+
+name: Create and publish a container image
+
+on:
+  push:
+    branches:
+      - master
+
+env:
+  REGISTRY: ghcr.io
+  IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+  build-and-push-image:
+    name: Build and push container image
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      packages: write
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v2
+      - name: Log in to the Container registry
+        uses: docker/login-action@v2
+        with:
+          registry: ${{ env.REGISTRY }}
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+      - name: Extract metadata (tags, labels)
+        id: meta
+        uses: docker/metadata-action@v4
+        with:
+          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+      - name: Build and push container image
+        uses: docker/build-push-action@v3
+        with:
+          context: .
+          push: true
+          tags: ${{ steps.meta.outputs.tags }}
+          labels: ${{ steps.meta.outputs.labels }}
index d71293ced02c1e435614233498b3b7490ceaaeae..11fa72ae6efeecd82b9089feea49a974ebdfd94b 100644 (file)
@@ -1,14 +1,11 @@
-# using container digest is recommended https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests 
-# https://cloud.google.com/architecture/using-container-images
+FROM docker.io/python:3-alpine
 
-FROM python:3@sha256:b7bfea0126f539ba570a01fb595ee84cc4e7dcac971ad83d12c848942fa52cb6
+ENV IN_CONTAINER 1
 
-WORKDIR /usr/src
-COPY requirements.txt ./
-RUN pip install --no-cache-dir -r requirements.txt
-RUN git clone --depth 1 https://github.com/StevenBlack/hosts.git
-WORKDIR /usr/src/hosts
+RUN apk add --no-cache git sudo
 
-# Now you launch this with
-#  $ docker build ./
-#  $ docker run -it (containerid) bash
+COPY . /usr/src/hosts
+
+RUN pip install --no-cache-dir --upgrade -r /usr/src/hosts/requirements.txt
+
+ENV PATH $PATH:/usr/src/hosts
index 52fe6a59ccd9eb2458be9886066aa125957ae73b..8d65f71cebd0497ecaad5594274d2637a7a07755 100644 (file)
@@ -72,19 +72,37 @@ You have two options to generate your own hosts file.  You can do it in your own
 
 ### Option 1: Generate in a Docker container
 
-We provide a [Dockerfile](https://github.com/StevenBlack/hosts/blob/master/Dockerfile) that you can use to create a Docker container with everything you need.
+We provide a [Dockerfile](https://github.com/StevenBlack/hosts/blob/master/Dockerfile) that you can use to create a container image with everything you need.
 The container will contain Python 3 and all its dependency requirements, and a copy of the latest version of this repository.
 
 Build the Docker container like this:
 
 ```sh
-docker build ./
+docker build --no-cache . -t stevenblack-hosts
 ```
 
-Access the terminal like this:
+Then run your command as such:
 
 ```sh
-docker run -it (containerid) bash
+docker run --rm -it -v "${PWD}/test:/pwd" stevenblack-hosts updateHostsFile.py
+```
+
+> It is recommended to mount a host directory, so your changes are saved when you exit
+the container. Add `-v "${PWD}:/pwd" -w /pwd` after `-it` to mount your current working
+directory, and have that as current working directory in your container.
+
+#### Linux example
+
+This will replace your `/etc/hosts` and optionally add any custom hosts.
+
+(Optionally) First create custom hosts files as per [the instructions](#how-do-i-control-which-sources-are-unified).
+
+Then run the following command to have everything setup.
+
+```sh
+docker run --pull always --rm -it -v /etc/hosts:/etc/hosts -v "${PWD}:/pwd" \
+-w /pwd ghcr.io/StevenBlack/hosts updateHostsFile.py --auto \
+--replace --extensions gambling porn
 ```
 
 ### Option 2: Generate it in your own environment
old mode 100644 (file)
new mode 100755 (executable)
index fb71194..8d60d9d
@@ -12,6 +12,7 @@ import json
 import locale
 import os
 import platform
+from pathlib import Path
 import re
 import shutil
 import socket
@@ -467,7 +468,7 @@ def prompt_for_move(final_file, **move_params):
         move_file = query_yes_no(prompt)
 
     if move_file:
-        move_hosts_file_into_place(final_file)
+        move_file = move_hosts_file_into_place(final_file)
 
     return move_file
 
@@ -1279,17 +1280,41 @@ def move_hosts_file_into_place(final_file):
 
     filename = os.path.abspath(final_file.name)
 
-    if os.name == "posix":
-        print(
-            "Moving the file requires administrative privileges. You might need to enter your password."
-        )
-        if subprocess.call(SUDO + ["cp", filename, "/etc/hosts"]):
-            print_failure("Moving the file failed.")
-    elif os.name == "nt":
-        print("Automatically moving the hosts file in place is not yet supported.")
-        print(
-            "Please move the generated file to %SystemRoot%\\system32\\drivers\\etc\\hosts"
-        )
+    if sys.platform == "linux":
+        target_file = "/etc/hosts"
+
+        if os.getenv("IN_CONTAINER"):
+            # It's not allowed to remove/replace a mounted /etc/hosts, so we replace the content.
+            # This requires running the container user as root, as is the default.
+            print(f"Running in container, so we will replace the content of {target_file}.")
+            try:
+                with open(target_file, "w") as target_stream:
+                    with open(filename, "r") as source_stream:
+                        target_stream.write(source_stream.read())
+                return True
+            except Exception:
+                print_failure(f"Replacing content of {target_file} failed.")
+                return False
+        else:
+            print(
+                f"Replacing {target_file} requires root privileges. You might need to enter your password."
+            )
+            try:
+                subprocess.run(SUDO + ["cp", filename, target_file], check=True)
+                return True
+            except subprocess.CalledProcessError:
+                print_failure(f"Replacing {target_file} failed.")
+                return False
+    elif sys.platform == "win32":
+        target_file = Path(os.getenv("SystemRoot")) / "system32" / "drivers" / "etc" / "hosts"
+        try:
+            with open(target_file, "w") as target_stream:
+                with open(filename, "r") as source_stream:
+                    target_stream.write(source_stream.read())
+            return True
+        except Exception:
+                print_failure(f"Replacing content of {target_file} failed.")
+                return False
 
 
 def flush_dns_cache():
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index ce1dbee..cb65262
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Script by Steven Black
 # https://github.com/StevenBlack
git clone https://git.99rst.org/PROJECT