--- /dev/null
+*
+!updateHostsFile.py
+!data
+!alternates
+!extensions
+!readmeData.json
+!requirements.txt
--- /dev/null
+# 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 }}
-# 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
### 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
import locale
import os
import platform
+from pathlib import Path
import re
import shutil
import socket
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
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():
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Script by Steven Black
# https://github.com/StevenBlack