Archive Legacy Setup And Add Ansible Control Plane
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
name: Deploy cloud-pc
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
stack:
|
||||
description: "Stack to deploy (leave empty to reconcile all)"
|
||||
required: false
|
||||
push:
|
||||
paths:
|
||||
- ".gitea/workflows/deploy-cloud-pc.yml"
|
||||
- "cloud-pc/**"
|
||||
- "scripts/deploy.sh"
|
||||
schedule:
|
||||
- cron: "0 4 * * *"
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: cloud-pc
|
||||
steps:
|
||||
- name: Sync repo
|
||||
run: |
|
||||
git config --global --replace-all safe.directory /opt/services
|
||||
git -C /opt/services pull origin main --ff-only
|
||||
chown -R 1000:100 /opt/services
|
||||
|
||||
- name: Deploy stacks
|
||||
run: /opt/services/scripts/deploy.sh cloud-pc "${{ inputs.stack }}"
|
||||
@@ -0,0 +1,28 @@
|
||||
name: Deploy mini-pc
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
stack:
|
||||
description: "Stack to deploy (leave empty to reconcile all)"
|
||||
required: false
|
||||
push:
|
||||
paths:
|
||||
- ".gitea/workflows/deploy-mini-pc.yml"
|
||||
- "mini-pc/**"
|
||||
- "scripts/deploy.sh"
|
||||
schedule:
|
||||
- cron: "0 4 * * *"
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: mini-pc
|
||||
steps:
|
||||
- name: Sync repo
|
||||
run: |
|
||||
git config --global --replace-all safe.directory /opt/services
|
||||
git -C /opt/services pull origin main --ff-only
|
||||
chown -R 1000:100 /opt/services
|
||||
|
||||
- name: Deploy stacks
|
||||
run: /opt/services/scripts/deploy.sh mini-pc "${{ inputs.stack }}"
|
||||
@@ -0,0 +1,28 @@
|
||||
name: Deploy ru-vps
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
stack:
|
||||
description: "Stack to deploy (leave empty to reconcile all)"
|
||||
required: false
|
||||
|
||||
push:
|
||||
paths:
|
||||
- ".gitea/workflows/deploy-ru-vps.yml"
|
||||
- "ru-vps/**"
|
||||
schedule:
|
||||
- cron: "0 4 * * *"
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ru-vps
|
||||
steps:
|
||||
- name: Sync repo
|
||||
run: |
|
||||
git config --global --replace-all safe.directory /opt/services
|
||||
git -C /opt/services pull origin main --ff-only
|
||||
chown -R 1000:100 /opt/services
|
||||
|
||||
- name: Deploy stacks
|
||||
run: /opt/services/scripts/deploy.sh ru-vps "${{ inputs.stack }}"
|
||||
@@ -0,0 +1,33 @@
|
||||
name: NixOS switch cloud-pc
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- ".gitea/workflows/nixos-switch-cloud-pc.yml"
|
||||
- "nixos/flake.nix"
|
||||
- "nixos/flake.lock"
|
||||
- "nixos/modules/**"
|
||||
- "nixos/hosts/cloud-pc/**"
|
||||
|
||||
jobs:
|
||||
switch:
|
||||
runs-on: cloud-pc
|
||||
steps:
|
||||
- name: Sync repo
|
||||
run: |
|
||||
git config --global --replace-all safe.directory /opt/services
|
||||
git -C /opt/services pull origin main --ff-only
|
||||
chown -R 1000:100 /opt/services
|
||||
|
||||
- name: Switch NixOS generation
|
||||
env:
|
||||
NIXOS_DEPLOY_KEY: ${{ secrets.NIXOS_DEPLOY_KEY }}
|
||||
run: |
|
||||
KEY=$(mktemp)
|
||||
echo "$NIXOS_DEPLOY_KEY" > "$KEY"
|
||||
chmod 600 "$KEY"
|
||||
trap "rm -f $KEY" EXIT
|
||||
ssh -i "$KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
ada@192.168.1.5 \
|
||||
"sudo /run/current-system/sw/bin/nixos-rebuild switch --flake /opt/services/nixos#cloud-pc"
|
||||
@@ -0,0 +1,33 @@
|
||||
name: NixOS switch mini-pc
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- ".gitea/workflows/nixos-switch-mini-pc.yml"
|
||||
- "nixos/flake.nix"
|
||||
- "nixos/flake.lock"
|
||||
- "nixos/modules/**"
|
||||
- "nixos/hosts/mini-pc/**"
|
||||
|
||||
jobs:
|
||||
switch:
|
||||
runs-on: mini-pc
|
||||
steps:
|
||||
- name: Sync repo
|
||||
run: |
|
||||
git config --global --replace-all safe.directory /opt/services
|
||||
git -C /opt/services pull origin main --ff-only
|
||||
chown -R 1000:100 /opt/services
|
||||
|
||||
- name: Switch NixOS generation
|
||||
env:
|
||||
NIXOS_DEPLOY_KEY: ${{ secrets.NIXOS_DEPLOY_KEY }}
|
||||
run: |
|
||||
KEY=$(mktemp)
|
||||
echo "$NIXOS_DEPLOY_KEY" > "$KEY"
|
||||
chmod 600 "$KEY"
|
||||
trap "rm -f $KEY" EXIT
|
||||
ssh -i "$KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
ada@192.168.1.10 \
|
||||
"sudo /run/current-system/sw/bin/nixos-rebuild switch --flake /opt/services/nixos#mini-pc"
|
||||
@@ -0,0 +1,13 @@
|
||||
# Archive: 2026-07 Proxmox Migration
|
||||
|
||||
Historical configuration from the pre-Proxmox HomeLab setup.
|
||||
|
||||
Moved here:
|
||||
|
||||
- `nixos/` — old NixOS host configs and modules.
|
||||
- `cloud-pc/`, `mini-pc/`, `ru-vps/` — old Docker Compose service trees.
|
||||
- `.gitea/` — old GitOps workflows.
|
||||
- `scripts/` — old deploy scripts.
|
||||
- `legacy-ansible/` — old bootstrap/base/dirs/restic/rclone playbooks and bootstrap role.
|
||||
|
||||
Use these files only as reference when implementing new Ansible roles/playbooks.
|
||||
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
ada-dev:
|
||||
image: git.ada-dev.ru/ada/ada-dev.ru:latest
|
||||
container_name: ada-dev-ru
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "7080:80"
|
||||
@@ -0,0 +1,4 @@
|
||||
FROM gitea/act_runner:latest
|
||||
|
||||
USER root
|
||||
RUN apk add --no-cache docker-cli docker-cli-compose openssh-client
|
||||
@@ -0,0 +1,13 @@
|
||||
services:
|
||||
gitea-runner:
|
||||
build: .
|
||||
restart: always
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /opt/services:/opt/services
|
||||
- /opt/data/gitea-runner:/data
|
||||
environment:
|
||||
GITEA_INSTANCE_URL: https://git.ada-dev.ru
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: ${TOKEN}
|
||||
GITEA_RUNNER_NAME: cloud-pc-runner
|
||||
GITEA_RUNNER_LABELS: cloud-pc
|
||||
@@ -0,0 +1,23 @@
|
||||
services:
|
||||
gitea:
|
||||
environment:
|
||||
USER_GID: "1000"
|
||||
USER_UID: "1000"
|
||||
hostname: gitea
|
||||
image: gitea/gitea:latest
|
||||
network_mode: bridge
|
||||
ports:
|
||||
- target: 3000
|
||||
published: "3002"
|
||||
protocol: tcp
|
||||
- target: 22
|
||||
published: "2222"
|
||||
protocol: tcp
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /opt/data/gitea
|
||||
target: /data
|
||||
networks:
|
||||
default:
|
||||
name: gitea_default
|
||||
@@ -0,0 +1,6 @@
|
||||
services:
|
||||
neural:
|
||||
ports:
|
||||
- 4567:4567
|
||||
image: git.ada-dev.ru/ada/lr_miad_nn:latest
|
||||
networks: {}
|
||||
@@ -0,0 +1,52 @@
|
||||
services:
|
||||
redis:
|
||||
image: redis:alpine
|
||||
container_name: redis
|
||||
hostname: redis
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
TZ: Europe/Moscow
|
||||
|
||||
nextcloud:
|
||||
image: nextcloud:${NC_VER}
|
||||
container_name: nextcloud
|
||||
hostname: nextcloud
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 8081:80
|
||||
dns:
|
||||
- 8.8.8.8
|
||||
extra_hosts:
|
||||
- ${NC_DOMAIN}:host-gateway
|
||||
depends_on:
|
||||
- redis
|
||||
volumes:
|
||||
- /opt/configs/nextcloud/app:/var/www/html
|
||||
- /opt/data/nextcloud:/var/www/html/data
|
||||
- /mnt/yandex:/mnt/yandex:shared
|
||||
environment:
|
||||
TZ: Europe/Moscow
|
||||
VIRTUAL_HOST: ${NC_DOMAIN}
|
||||
NEXTCLOUD_TRUSTED_DOMAINS: ${NC_DOMAIN} 127.0.0.1
|
||||
NEXTCLOUD_OVERWRITEPROTOCOL: https
|
||||
NEXTCLOUD_OVERWRITEHOST: ${NC_DOMAIN}
|
||||
NEXTCLOUD_OVERWRITECLIURL: https://${NC_DOMAIN}
|
||||
REDIS_HOST: redis
|
||||
TRUSTED_PROXIES: ${TRUSTED_PROXIES}
|
||||
|
||||
cron:
|
||||
image: nextcloud:${NC_VER}
|
||||
hostname: cron
|
||||
container_name: cron
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /opt/configs/nextcloud/app:/var/www/html
|
||||
- /opt/data/nextcloud:/var/www/html/data
|
||||
entrypoint: /cron.sh
|
||||
depends_on:
|
||||
- nextcloud
|
||||
environment:
|
||||
TZ: Europe/Moscow
|
||||
REDIS_HOST: redis
|
||||
|
||||
networks: {}
|
||||
@@ -0,0 +1,98 @@
|
||||
version = "1"
|
||||
|
||||
[global]
|
||||
scheduler = "systemd"
|
||||
|
||||
# ── Общие настройки ────────────────────────────────────────────────────────────
|
||||
[default]
|
||||
password-file = "/etc/restic/password"
|
||||
initialize = true
|
||||
|
||||
[default.forget]
|
||||
keep-daily = 7
|
||||
keep-weekly = 4
|
||||
keep-monthly = 6
|
||||
schedule-permission = "system"
|
||||
schedule-after-backup = true
|
||||
prune = true
|
||||
|
||||
[default.check]
|
||||
schedule = "Sun 04:00"
|
||||
schedule-permission = "system"
|
||||
|
||||
# ── Данные и конфиги сервисов ─────────────────────────────────────────────────
|
||||
[services]
|
||||
inherit = "default"
|
||||
repository = "/mnt/backup/restic/services"
|
||||
|
||||
[services.backup]
|
||||
source = ["/opt/data", "/opt/configs"]
|
||||
tag = ["cloud-pc", "services"]
|
||||
exclude-caches = true
|
||||
one-file-system = true
|
||||
schedule = "02:00"
|
||||
schedule-permission = "system"
|
||||
schedule-log = "/var/log/resticprofile/services.log"
|
||||
|
||||
[services.forget]
|
||||
schedule = "02:30"
|
||||
|
||||
# ── Samba-шара ────────────────────────────────────────────────────────────────
|
||||
[samba]
|
||||
inherit = "default"
|
||||
repository = "/mnt/backup/restic/samba"
|
||||
|
||||
[samba.backup]
|
||||
source = ["/opt/samba"]
|
||||
tag = ["cloud-pc", "samba"]
|
||||
exclude-caches = true
|
||||
one-file-system = true
|
||||
schedule = "03:00"
|
||||
schedule-permission = "system"
|
||||
schedule-log = "/var/log/resticprofile/samba.log"
|
||||
|
||||
[samba.forget]
|
||||
schedule = "03:30"
|
||||
|
||||
# ── Yandex Disk: ночная удалённая копия ───────────────────────────────────────
|
||||
[yadisk-default]
|
||||
inherit = "default"
|
||||
|
||||
[yadisk-default.check]
|
||||
schedule = "Sun 06:00"
|
||||
schedule-permission = "system"
|
||||
schedule-after-network-online = true
|
||||
|
||||
[yadisk-services]
|
||||
inherit = "yadisk-default"
|
||||
repository = "rclone:yadisk:System/Backups/cloud-pc/restic/services"
|
||||
|
||||
[yadisk-services.backup]
|
||||
source = ["/opt/data", "/opt/configs"]
|
||||
tag = ["cloud-pc", "services", "yadisk"]
|
||||
exclude-caches = true
|
||||
one-file-system = true
|
||||
schedule = "04:00"
|
||||
schedule-permission = "system"
|
||||
schedule-after-network-online = true
|
||||
schedule-log = "/var/log/resticprofile/yadisk-services.log"
|
||||
|
||||
[yadisk-services.forget]
|
||||
schedule = "04:30"
|
||||
|
||||
[yadisk-samba]
|
||||
inherit = "yadisk-default"
|
||||
repository = "rclone:yadisk:System/Backups/cloud-pc/restic/samba"
|
||||
|
||||
[yadisk-samba.backup]
|
||||
source = ["/opt/samba"]
|
||||
tag = ["cloud-pc", "samba", "yadisk"]
|
||||
exclude-caches = true
|
||||
one-file-system = true
|
||||
schedule = "05:00"
|
||||
schedule-permission = "system"
|
||||
schedule-after-network-online = true
|
||||
schedule-log = "/var/log/resticprofile/yadisk-samba.log"
|
||||
|
||||
[yadisk-samba.forget]
|
||||
schedule = "05:30"
|
||||
@@ -0,0 +1 @@
|
||||
SAMBA_PASSWORD=
|
||||
@@ -0,0 +1,16 @@
|
||||
services:
|
||||
samba:
|
||||
image: ghcr.io/servercontainers/samba:latest
|
||||
container_name: samba
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /opt/samba/media:/shares/media
|
||||
- /opt/samba/documents:/shares/documents
|
||||
- /opt/samba/backups_win:/shares/backups_win
|
||||
environment:
|
||||
ACCOUNT_ada: ${SAMBA_PASSWORD}
|
||||
UID_ada: "1000"
|
||||
SAMBA_VOLUME_CONFIG_media: "[media]; path = /shares/media; valid users = ada; read only = no"
|
||||
SAMBA_VOLUME_CONFIG_documents: "[documents]; path = /shares/documents; valid users = ada; read only = no"
|
||||
SAMBA_VOLUME_CONFIG_backups_win: "[backups_win]; path = /shares/backups_win; valid users = ada; read only = no"
|
||||
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
syncthing:
|
||||
image: syncthing/syncthing:latest
|
||||
container_name: syncthing
|
||||
hostname: cloud-pc
|
||||
environment:
|
||||
PUID: "1000"
|
||||
PGID: "1000"
|
||||
STGUIADDRESS: 0.0.0.0:8384
|
||||
volumes:
|
||||
- /opt/configs/syncthing:/var/syncthing/config
|
||||
- /opt/data/syncthing:/var/syncthing/data
|
||||
network_mode: host
|
||||
restart: unless-stopped
|
||||
@@ -0,0 +1,15 @@
|
||||
services:
|
||||
zerotier:
|
||||
container_name: zerotier
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- /opt/data/zerotier:/var/lib/zerotier-one
|
||||
image: zerotier/zerotier:latest
|
||||
command: ["743993800fa5a34c"]
|
||||
networks: {}
|
||||
@@ -0,0 +1,16 @@
|
||||
- name: Base server setup
|
||||
hosts: servers
|
||||
gather_facts: true
|
||||
become: false
|
||||
tasks:
|
||||
- name: Ping hosts
|
||||
ansible.builtin.ping:
|
||||
|
||||
|
||||
- name: Check expected LAN IP
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- expected_lan_ip in ansible_all_ipv4_addresses
|
||||
fail_msg: "{{ inventory_hostname }} must have {{ expected_lan_ip }}; found: {{ ansible_all_ipv4_addresses | join(', ') }}"
|
||||
success_msg: "{{ inventory_hostname }} has {{ expected_lan_ip }}"
|
||||
when: expected_lan_ip is defined
|
||||
@@ -0,0 +1,10 @@
|
||||
# Запускать один раз на новом сервере от имени root или пользователя с полным sudo:
|
||||
# ansible-playbook -i inventory/hosts.yml playbooks/bootstrap.yml -K
|
||||
#
|
||||
# После выполнения: Ansible-плейбуки всё равно требуют -K (become),
|
||||
# но деплой через GitOps (docker compose) работает без пароля.
|
||||
- name: Bootstrap servers
|
||||
hosts: servers
|
||||
become: true
|
||||
roles:
|
||||
- bootstrap
|
||||
@@ -0,0 +1,119 @@
|
||||
- name: Directory structure — cloud-pc
|
||||
hosts: cloud-pc
|
||||
become: true
|
||||
vars:
|
||||
data_user: ada
|
||||
data_group: ada
|
||||
tasks:
|
||||
- name: Create base mount points
|
||||
ansible.builtin.file:
|
||||
path: "{{ item.path }}"
|
||||
state: directory
|
||||
owner: "{{ data_user }}"
|
||||
group: "{{ data_group }}"
|
||||
mode: "0755"
|
||||
loop: "{{ storage_mounts | default([]) }}"
|
||||
|
||||
- name: Mount base storage disks
|
||||
ansible.posix.mount:
|
||||
path: "{{ item.path }}"
|
||||
src: "{{ item.src }}"
|
||||
fstype: "{{ item.fstype }}"
|
||||
opts: "{{ item.opts | default('defaults,nofail') }}"
|
||||
state: mounted
|
||||
loop: "{{ storage_mounts | default([]) }}"
|
||||
|
||||
- name: Create service data and config directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ data_user }}"
|
||||
group: "{{ data_group }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- /opt/data/postgres
|
||||
- /opt/data/nextcloud
|
||||
- /opt/data/gitea
|
||||
- /opt/data/gitea-runner
|
||||
- /opt/data/syncthing
|
||||
- /opt/data/zerotier
|
||||
- /opt/samba/media
|
||||
- /opt/samba/documents
|
||||
- /opt/samba/backups_win
|
||||
- /opt/configs
|
||||
- /opt/configs/nextcloud/app
|
||||
- /opt/configs/syncthing
|
||||
|
||||
- name: Create /opt/services
|
||||
ansible.builtin.file:
|
||||
path: /opt/services
|
||||
state: directory
|
||||
owner: "{{ data_user }}"
|
||||
group: "{{ data_group }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Create backup directories (3TB)
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ data_user }}"
|
||||
group: "{{ data_group }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- /mnt/backup/restic/services
|
||||
- /mnt/backup/restic/samba
|
||||
- /mnt/backup/devices/proxmox
|
||||
- /mnt/backup/devices/ada-x1
|
||||
|
||||
- name: Directory structure — mini-pc
|
||||
hosts: mini-pc
|
||||
become: true
|
||||
vars:
|
||||
data_user: ada
|
||||
data_group: ada
|
||||
tasks:
|
||||
- name: Create service directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ data_user }}"
|
||||
group: "{{ data_group }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- /opt/services
|
||||
- /opt/data
|
||||
- /opt/configs
|
||||
- /opt/data/vaultwarden
|
||||
- /opt/data/adguard/work
|
||||
- /opt/data/caddy
|
||||
- /opt/data/gitea-runner
|
||||
- /opt/data/npm
|
||||
- /opt/data/uptime-kuma
|
||||
- /opt/data/zerotier
|
||||
- /opt/configs/adguard
|
||||
- /opt/configs/caddy
|
||||
- /opt/configs/caddy/lego
|
||||
- /opt/configs/npm/letsencrypt
|
||||
|
||||
- name: Directory structure — ru-vps
|
||||
hosts: ru-vps
|
||||
become: true
|
||||
vars:
|
||||
data_user: ada
|
||||
data_group: ada
|
||||
tasks:
|
||||
- name: Create service directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ data_user }}"
|
||||
group: "{{ data_group }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- /opt/services
|
||||
- /opt/data
|
||||
- /opt/configs
|
||||
- /opt/data/caddy
|
||||
- /opt/data/gitea-runner
|
||||
- /opt/data/zerotier
|
||||
- /opt/configs/caddy
|
||||
@@ -0,0 +1,9 @@
|
||||
- name: Install rclone
|
||||
hosts: servers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Install rclone package
|
||||
ansible.builtin.apt:
|
||||
name: rclone
|
||||
state: present
|
||||
update_cache: true
|
||||
@@ -0,0 +1,36 @@
|
||||
- name: Install resticprofile
|
||||
hosts: servers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Install restic package
|
||||
ansible.builtin.apt:
|
||||
name: restic
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Create restic config directory
|
||||
ansible.builtin.file:
|
||||
path: /etc/restic
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
|
||||
- name: Create resticprofile log directory
|
||||
ansible.builtin.file:
|
||||
path: /var/log/resticprofile
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
|
||||
- name: Download resticprofile install script
|
||||
ansible.builtin.get_url:
|
||||
url: https://raw.githubusercontent.com/creativeprojects/resticprofile/master/install.sh
|
||||
dest: /tmp/resticprofile-install.sh
|
||||
mode: "0755"
|
||||
|
||||
- name: Install resticprofile binary
|
||||
ansible.builtin.command:
|
||||
cmd: /tmp/resticprofile-install.sh -b /usr/local/bin
|
||||
creates: /usr/local/bin/resticprofile
|
||||
@@ -0,0 +1,5 @@
|
||||
bootstrap_user: ada
|
||||
bootstrap_ssh_public_keys: [ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIWNsUQmppB6cQccXX1ZaBbFIcmM6RmghsTVbG9TgoZB ada@ada-x1]
|
||||
docker_registry_mirrors:
|
||||
- https://mirror.gcr.io
|
||||
- https://dockerhub.timeweb.cloud
|
||||
@@ -0,0 +1,4 @@
|
||||
- name: restart sshd
|
||||
ansible.builtin.service:
|
||||
name: sshd
|
||||
state: restarted
|
||||
@@ -0,0 +1,85 @@
|
||||
- name: Ensure user exists
|
||||
ansible.builtin.user:
|
||||
name: "{{ bootstrap_user }}"
|
||||
shell: /bin/bash
|
||||
groups: sudo
|
||||
append: true
|
||||
create_home: true
|
||||
state: present
|
||||
|
||||
# docker group создаётся только после установки Docker.
|
||||
# Добавление происходит в роли docker, не здесь.
|
||||
|
||||
- name: Add SSH authorized keys
|
||||
ansible.posix.authorized_key:
|
||||
user: "{{ bootstrap_user }}"
|
||||
key: "{{ item }}"
|
||||
state: present
|
||||
loop: "{{ bootstrap_ssh_public_keys }}"
|
||||
when: bootstrap_ssh_public_keys | length > 0
|
||||
|
||||
- name: Gather service facts
|
||||
ansible.builtin.service_facts:
|
||||
|
||||
- name: Ensure Docker config directory exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/docker
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Configure Docker registry mirrors
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/docker/daemon.json
|
||||
content: "{{ {'registry-mirrors': docker_registry_mirrors} | to_nice_json }}\n"
|
||||
mode: "0644"
|
||||
register: docker_daemon_config
|
||||
when: docker_registry_mirrors | length > 0
|
||||
|
||||
- name: Restart Docker after daemon config change
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: restarted
|
||||
when:
|
||||
- docker_daemon_config is changed
|
||||
- "'docker.service' in ansible_facts.services"
|
||||
|
||||
# Команды, которые реально нужны без пароля:
|
||||
# apt / apt-get — обновление пакетов
|
||||
# systemctl — управление сервисами
|
||||
# ufw — фаервол
|
||||
# resticprofile — установка systemd-таймеров бэкапа
|
||||
#
|
||||
# Ansible become НЕ входит в этот список намеренно:
|
||||
# для плейбуков запускать с -K. Это сознательный компромисс
|
||||
# между удобством и тем, чтобы не давать python3 NOPASSWD (= root).
|
||||
- name: Configure sudoers — NOPASSWD for specific commands
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/sudoers.d/{{ bootstrap_user }}
|
||||
content: |
|
||||
{{ bootstrap_user }} ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get
|
||||
{{ bootstrap_user }} ALL=(ALL) NOPASSWD: /usr/bin/systemctl
|
||||
{{ bootstrap_user }} ALL=(ALL) NOPASSWD: /usr/bin/ufw
|
||||
{{ bootstrap_user }} ALL=(ALL) NOPASSWD: /usr/local/bin/resticprofile
|
||||
validate: /usr/sbin/visudo -cf %s
|
||||
mode: "0440"
|
||||
|
||||
# Drop-in конфиг — не трогаем основной sshd_config.
|
||||
# Требует Debian 12+ (OpenSSH 8.9+).
|
||||
- name: Harden SSH
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/ssh/sshd_config.d/99-hardening.conf
|
||||
content: |
|
||||
PasswordAuthentication no
|
||||
PermitRootLogin no
|
||||
PubkeyAuthentication yes
|
||||
mode: "0644"
|
||||
notify: restart sshd
|
||||
|
||||
- name: Ensure sshd_config.d is included
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/ssh/sshd_config
|
||||
line: Include /etc/ssh/sshd_config.d/*.conf
|
||||
state: present
|
||||
insertbefore: BOF
|
||||
validate: /usr/sbin/sshd -t -f %s
|
||||
notify: restart sshd
|
||||
@@ -0,0 +1,46 @@
|
||||
services:
|
||||
adguard:
|
||||
image: adguard/adguardhome:latest
|
||||
container_name: adguard
|
||||
#network_mode: "host" # DHCP server - optional, only if AdGuard handles DHCP
|
||||
restart: always
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
reservations:
|
||||
memory: 64M
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- /opt/adguardhome/AdGuardHome --check-config -w /opt/adguardhome/work
|
||||
-c /opt/adguardhome/conf/AdGuardHome.yaml
|
||||
interval: 45s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=Europe/Moscow
|
||||
volumes:
|
||||
- /opt/data/adguard/work:/opt/adguardhome/work:rw
|
||||
- /opt/configs/adguard:/opt/adguardhome/conf:rw
|
||||
- /etc/hosts:/etc/hosts:ro
|
||||
ports:
|
||||
- 53:53/tcp # DNS - **mandatory**
|
||||
- 53:53/udp # DNS - **mandatory**
|
||||
#- "67:67/udp" # DHCP server - optional, only if AdGuard handles DHCP
|
||||
#- "68:68/udp" # DHCP server - optional
|
||||
- 8088:80/tcp # Dashboard HTTP - optional, only if not using HTTPS
|
||||
- 4438:443/tcp # DNS-over-HTTPS / dashboard HTTPS - optional but recommended if using DoH
|
||||
- 784:784/udp # DNS-over-QUIC (beta) - optional, experimental
|
||||
- 853:853/tcp # DNS-over-TLS - optional
|
||||
- 3015:3000/tcp # Dashboard initial config - optional, only for initial setup
|
||||
- 5443:5443/tcp # DNSCrypt / alternative DoH - optional
|
||||
- 5443:5443/udp # DNSCrypt depends on TCP - optional
|
||||
#- "6060:6060/tcp" # Internal API - optional, do not expose
|
||||
#- "8853:8853/udp" # DNS mTLS (beta) - optional, experimental
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
networks: {}
|
||||
@@ -0,0 +1,2 @@
|
||||
LEGO_EMAIL=you@example.com
|
||||
TIMEWEBCLOUD_AUTH_TOKEN=changeme
|
||||
@@ -0,0 +1,19 @@
|
||||
git.ada-dev.ru {
|
||||
tls /config/lego/certificates/ada-dev.ru.crt /config/lego/certificates/ada-dev.ru.key
|
||||
reverse_proxy 192.168.1.5:3002
|
||||
}
|
||||
|
||||
cloud.ada-dev.ru {
|
||||
tls /config/lego/certificates/ada-dev.ru.crt /config/lego/certificates/ada-dev.ru.key
|
||||
reverse_proxy 192.168.1.5:8081
|
||||
}
|
||||
|
||||
router.ada-dev.ru {
|
||||
tls /config/lego/certificates/ada-dev.ru.crt /config/lego/certificates/ada-dev.ru.key
|
||||
reverse_proxy 192.168.1.1:80
|
||||
}
|
||||
|
||||
dns.ada-dev.ru {
|
||||
tls /config/lego/certificates/ada-dev.ru.crt /config/lego/certificates/ada-dev.ru.key
|
||||
reverse_proxy 192.168.1.10:8088
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:2-alpine
|
||||
container_name: caddy
|
||||
restart: unless-stopped
|
||||
dns:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- /opt/data/caddy:/data
|
||||
- /opt/configs/caddy:/config
|
||||
entrypoint: /bin/sh
|
||||
command:
|
||||
- -c
|
||||
- |
|
||||
while [ ! -f /config/lego/certificates/ada-dev.ru.crt ] || [ ! -f /config/lego/certificates/ada-dev.ru.key ]; do
|
||||
sleep 10
|
||||
done
|
||||
exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||
|
||||
lego:
|
||||
image: git.ada-dev.ru/ada/lego:latest
|
||||
container_name: caddy-lego
|
||||
dns:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
env_file:
|
||||
- .env
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /opt/configs/caddy/lego:/lego-data
|
||||
entrypoint: /bin/sh
|
||||
command:
|
||||
- -c
|
||||
- |
|
||||
while true; do
|
||||
if [ -f /lego-data/certificates/ada-dev.ru.crt ]; then
|
||||
/lego renew \
|
||||
--email "$$LEGO_EMAIL" \
|
||||
--dns timewebcloud \
|
||||
--dns.resolvers 1.1.1.1:53 \
|
||||
--dns.resolvers 8.8.8.8:53 \
|
||||
--dns.propagation-timeout 5m \
|
||||
--domains ada-dev.ru \
|
||||
--domains '*.ada-dev.ru' \
|
||||
--path /lego-data \
|
||||
--days 30
|
||||
sleep 24h
|
||||
else
|
||||
/lego run \
|
||||
--email "$$LEGO_EMAIL" \
|
||||
--accept-tos \
|
||||
--dns timewebcloud \
|
||||
--dns.resolvers 1.1.1.1:53 \
|
||||
--dns.resolvers 8.8.8.8:53 \
|
||||
--dns.propagation-timeout 5m \
|
||||
--domains ada-dev.ru \
|
||||
--domains '*.ada-dev.ru' \
|
||||
--path /lego-data
|
||||
sleep 10m
|
||||
fi
|
||||
done
|
||||
networks: {}
|
||||
@@ -0,0 +1,4 @@
|
||||
FROM gitea/act_runner:latest
|
||||
|
||||
USER root
|
||||
RUN apk add --no-cache docker-cli docker-cli-compose openssh-client
|
||||
@@ -0,0 +1,16 @@
|
||||
services:
|
||||
gitea-runner:
|
||||
build: .
|
||||
restart: always
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /opt/services:/opt/services
|
||||
- /opt/data/gitea-runner:/data
|
||||
environment:
|
||||
GITEA_INSTANCE_URL: https://git.ada-dev.ru
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: ${TOKEN}
|
||||
GITEA_RUNNER_NAME: mini-pc-runner
|
||||
GITEA_RUNNER_LABELS: mini-pc
|
||||
dns:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
@@ -0,0 +1,13 @@
|
||||
services:
|
||||
memoir-bot:
|
||||
image: git.ada-dev.ru/ada/memoir_bot:0.1
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
OBSIDIAN_VAULT_PATH: /vault
|
||||
TZ: ${TIMEZONE:-Europe/Moscow}
|
||||
volumes:
|
||||
- /opt/data/memoir_bot:/vault
|
||||
- /home/ada/.ssh:/root/.ssh:ro
|
||||
network_mode: host
|
||||
@@ -0,0 +1,38 @@
|
||||
version = "1"
|
||||
|
||||
[global]
|
||||
scheduler = "systemd"
|
||||
|
||||
[default]
|
||||
password-file = "/etc/restic/password"
|
||||
initialize = true
|
||||
|
||||
[default.forget]
|
||||
keep-daily = 7
|
||||
keep-weekly = 4
|
||||
keep-monthly = 6
|
||||
schedule-permission = "system"
|
||||
schedule-after-backup = true
|
||||
prune = true
|
||||
|
||||
[default.check]
|
||||
schedule = "Sun 04:00"
|
||||
schedule-permission = "system"
|
||||
schedule-after-network-online = true
|
||||
|
||||
[services]
|
||||
inherit = "default"
|
||||
repository = "rclone:yadisk:System/Backups/mini-pc/restic/services"
|
||||
|
||||
[services.backup]
|
||||
source = ["/opt/data", "/opt/configs"]
|
||||
tag = ["mini-pc", "services"]
|
||||
exclude-caches = true
|
||||
one-file-system = true
|
||||
schedule = "03:00"
|
||||
schedule-permission = "system"
|
||||
schedule-after-network-online = true
|
||||
schedule-log = "/var/log/resticprofile/services.log"
|
||||
|
||||
[services.forget]
|
||||
schedule = "03:30"
|
||||
@@ -0,0 +1,13 @@
|
||||
services:
|
||||
uptime-kuma:
|
||||
image: louislam/uptime-kuma:2
|
||||
container_name: uptime-kuma
|
||||
hostname: uptime-kuma
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3001:3001"
|
||||
environment:
|
||||
TZ: Europe/Moscow
|
||||
volumes:
|
||||
- /opt/data/uptime-kuma:/app/data
|
||||
networks: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
v2raya:
|
||||
image: mzz2017/v2raya:latest
|
||||
container_name: v2raya
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
privileged: true
|
||||
volumes:
|
||||
- /opt/data/v2raya:/etc/v2raya
|
||||
- /opt/data/v2raya-extra:/etc/v2raya-extra
|
||||
environment:
|
||||
- V2RAYA_LOG_FILE=/tmp/v2raya.log
|
||||
- V2RAYA_V2RAY_BIN_PATH=/usr/local/bin/v2ray
|
||||
- V2RAYA_V2RAY_CONFDIR=/etc/v2raya-extra
|
||||
@@ -0,0 +1,8 @@
|
||||
ADMIN_TOKEN=changeme
|
||||
SMTP_HOST=smtp.yandex.ru
|
||||
SMTP_PORT=465
|
||||
SMTP_SECURITY=force_tls
|
||||
SMTP_USERNAME=info.ada-dev@yandex.ru
|
||||
SMTP_PASSWORD=changeme
|
||||
SMTP_FROM=info.ada-dev@yandex.ru
|
||||
SMTP_FROM_NAME=Vaultwarden
|
||||
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
vaultwarden:
|
||||
hostname: vaultwarden
|
||||
image: vaultwarden/server:latest
|
||||
ports:
|
||||
- target: 80
|
||||
published: "10380"
|
||||
protocol: tcp
|
||||
restart: unless-stopped
|
||||
env_file: .env
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /opt/data/vaultwarden
|
||||
target: /data
|
||||
networks:
|
||||
default:
|
||||
name: vaultwarden_default
|
||||
@@ -0,0 +1,15 @@
|
||||
services:
|
||||
zerotier:
|
||||
container_name: zerotier
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
volumes:
|
||||
- /opt/data/zerotier:/var/lib/zerotier-one
|
||||
image: zerotier/zerotier:latest
|
||||
command: ["743993800fa5a34c"]
|
||||
networks: {}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
description = "Homelab NixOS hosts";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, ... }: {
|
||||
nixosConfigurations.cloud-pc = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
./hosts/cloud-pc
|
||||
];
|
||||
};
|
||||
|
||||
nixosConfigurations.mini-pc = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
./hosts/mini-pc
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../../modules/base.nix
|
||||
../../modules/docker.nix
|
||||
../../modules/libvirtd.nix
|
||||
../../modules/zerotier.nix
|
||||
./firewall.nix
|
||||
./hardware.nix
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = "cloud-pc";
|
||||
useDHCP = false;
|
||||
defaultGateway = "192.168.1.1";
|
||||
nameservers = [
|
||||
"192.168.1.1"
|
||||
"1.1.1.1"
|
||||
];
|
||||
|
||||
interfaces.enp2s0.ipv4.addresses = [
|
||||
{
|
||||
address = "192.168.1.5";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
fileSystems."/opt/data" = {
|
||||
device = "/dev/disk/by-uuid/ae278333-4116-4225-9b95-595496fadd26";
|
||||
fsType = "ext4";
|
||||
options = [ "nofail" ];
|
||||
};
|
||||
|
||||
fileSystems."/opt/samba" = {
|
||||
device = "/dev/disk/by-uuid/89024d30-1ab6-4b2e-b23b-62837455b24a";
|
||||
fsType = "ext4";
|
||||
options = [ "nofail" ];
|
||||
};
|
||||
|
||||
fileSystems."/mnt/backup" = {
|
||||
device = "/dev/disk/by-uuid/940a9a4e-10cf-4380-9d22-a71549066561";
|
||||
fsType = "ext4";
|
||||
options = [ "nofail" ];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /opt/data/postgres 0755 ada users - -"
|
||||
"d /opt/data/nextcloud 0755 ada users - -"
|
||||
"d /opt/data/gitea 0755 ada users - -"
|
||||
"d /opt/data/gitea-runner 0755 ada users - -"
|
||||
"d /opt/data/syncthing 0755 ada users - -"
|
||||
"d /opt/data/zerotier 0755 ada users - -"
|
||||
"d /opt/configs/nextcloud 0755 ada users - -"
|
||||
"d /opt/configs/nextcloud/app 0755 ada users - -"
|
||||
"d /opt/configs/syncthing 0755 ada users - -"
|
||||
"d /opt/samba 0755 ada users - -"
|
||||
"d /opt/samba/media 0755 ada users - -"
|
||||
"d /opt/samba/documents 0755 ada users - -"
|
||||
"d /opt/samba/backups_win 0755 ada users - -"
|
||||
"d /mnt/backup 0755 ada users - -"
|
||||
"d /mnt/backup/restic 0755 ada users - -"
|
||||
"d /mnt/backup/restic/services 0755 ada users - -"
|
||||
"d /mnt/backup/restic/samba 0755 ada users - -"
|
||||
"d /mnt/backup/devices 0755 ada users - -"
|
||||
"d /mnt/backup/devices/proxmox 0755 ada users - -"
|
||||
"d /mnt/backup/devices/ada-x1 0755 ada users - -"
|
||||
"d /mnt/yandex 0755 ada users - -"
|
||||
];
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [
|
||||
22 # SSH
|
||||
139 # Samba (NetBIOS session)
|
||||
445 # Samba (SMB)
|
||||
2222 # Gitea SSH
|
||||
3002
|
||||
4567
|
||||
5432 # PostgreSQL
|
||||
7080
|
||||
8081
|
||||
8384 # Syncthing web UI
|
||||
22000 # Syncthing data transfer
|
||||
];
|
||||
allowedUDPPorts = [
|
||||
137 # Samba (NetBIOS name)
|
||||
138 # Samba (NetBIOS datagram)
|
||||
9993 # ZeroTier
|
||||
21027 # Syncthing discovery
|
||||
22000 # Syncthing data transfer
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/f729e8cb-5c37-45fe-bd0a-e511d79bb49c";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/8BA8-38FE";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" ];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../../modules/base.nix
|
||||
../../modules/docker.nix
|
||||
../../modules/libvirtd.nix
|
||||
../../modules/zerotier.nix
|
||||
./firewall.nix
|
||||
./hardware.nix
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = "mini-pc";
|
||||
useDHCP = false;
|
||||
};
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
networks."10-lan" = {
|
||||
matchConfig.Name = "en*";
|
||||
networkConfig = {
|
||||
Address = "192.168.1.10/24";
|
||||
Gateway = "192.168.1.1";
|
||||
DNS = [
|
||||
"192.168.1.1"
|
||||
"1.1.1.1"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.resolved = {
|
||||
enable = true;
|
||||
fallbackDns = [ "1.1.1.1" "8.8.8.8" ];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /opt/data/adguard 0755 ada users - -"
|
||||
"d /opt/data/adguard/work 0755 ada users - -"
|
||||
"d /opt/data/caddy 0755 ada users - -"
|
||||
"d /opt/data/gitea-runner 0755 ada users - -"
|
||||
"d /opt/data/uptime-kuma 0755 ada users - -"
|
||||
"d /opt/data/vaultwarden 0755 ada users - -"
|
||||
"d /opt/data/zerotier 0755 ada users - -"
|
||||
"d /opt/configs/adguard 0755 ada users - -"
|
||||
"d /opt/configs/caddy 0755 ada users - -"
|
||||
"d /opt/configs/caddy/lego 0755 ada users - -"
|
||||
];
|
||||
|
||||
programs.bash.interactiveShellInit = ''
|
||||
proxy_on() {
|
||||
export http_proxy=http://192.168.1.10:10172
|
||||
export https_proxy=http://192.168.1.10:10172
|
||||
export HTTP_PROXY=http://192.168.1.10:10172
|
||||
export HTTPS_PROXY=http://192.168.1.10:10172
|
||||
export all_proxy=socks5://192.168.1.10:10171
|
||||
export ALL_PROXY=socks5://192.168.1.10:10171
|
||||
export ftp_proxy=http://192.168.1.10:10172
|
||||
export FTP_PROXY=http://192.168.1.10:10172
|
||||
export no_proxy=localhost,127.0.0.0/8,::1,192.168.1.0/24
|
||||
export NO_PROXY=localhost,127.0.0.0/8,::1,192.168.1.0/24
|
||||
}
|
||||
proxy_off() {
|
||||
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
|
||||
unset all_proxy ALL_PROXY ftp_proxy FTP_PROXY
|
||||
unset no_proxy NO_PROXY
|
||||
}
|
||||
'';
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [
|
||||
22 # SSH
|
||||
53 # DNS (AdGuard)
|
||||
80 # HTTP
|
||||
443 # HTTPS
|
||||
784 # DNS-over-QUIC
|
||||
853 # DNS-over-TLS
|
||||
3001 # Uptime Kuma
|
||||
3015
|
||||
4438
|
||||
5443
|
||||
8088
|
||||
10171 # v2raya SOCKS5 LAN
|
||||
10172 # v2raya HTTP proxy LAN
|
||||
10380
|
||||
];
|
||||
allowedUDPPorts = [
|
||||
53 # DNS
|
||||
443 # QUIC
|
||||
784 # DNS-over-QUIC
|
||||
9993 # ZeroTier
|
||||
5443
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "sdhci_pci" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/a2fc1626-3301-44dd-9d00-fa7e8d216d25";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/73C2-3F45";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" ];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
nix = {
|
||||
settings = {
|
||||
experimental-features = [ "nix-command" "flakes" ];
|
||||
auto-optimise-store = true;
|
||||
};
|
||||
gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 30d";
|
||||
};
|
||||
};
|
||||
|
||||
boot = {
|
||||
tmp.cleanOnBoot = true;
|
||||
loader.systemd-boot.enable = true;
|
||||
loader.efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
systemd.network.wait-online.anyInterface = true;
|
||||
|
||||
systemd.services.nix-daemon.environment = {
|
||||
HTTPS_PROXY = "http://192.168.1.10:10172";
|
||||
HTTP_PROXY = "http://192.168.1.10:10172";
|
||||
NO_PROXY = "localhost,127.0.0.0/8,::1,192.168.1.0/24";
|
||||
};
|
||||
|
||||
time.timeZone = "Europe/Moscow";
|
||||
|
||||
i18n.defaultLocale = "ru_RU.UTF-8";
|
||||
i18n.supportedLocales = [
|
||||
"ru_RU.UTF-8/UTF-8"
|
||||
"en_US.UTF-8/UTF-8"
|
||||
];
|
||||
|
||||
users.users.ada = {
|
||||
isNormalUser = true;
|
||||
shell = pkgs.bashInteractive;
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"docker"
|
||||
];
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIWNsUQmppB6cQccXX1ZaBbFIcmM6RmghsTVbG9TgoZB ada@ada-x1"
|
||||
];
|
||||
};
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
KbdInteractiveAuthentication = false;
|
||||
PermitRootLogin = "no";
|
||||
PubkeyAuthentication = true;
|
||||
};
|
||||
};
|
||||
|
||||
security.sudo.extraRules = [
|
||||
{
|
||||
users = [ "ada" ];
|
||||
commands = [
|
||||
{
|
||||
command = "/run/current-system/sw/bin/nixos-rebuild";
|
||||
options = [ "NOPASSWD" ];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
git
|
||||
restic
|
||||
resticprofile
|
||||
htop
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /opt/services 0755 ada users - -"
|
||||
"Z /opt/services - ada users - -"
|
||||
"d /opt/data 0755 ada users - -"
|
||||
"d /opt/configs 0755 ada users - -"
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
daemon.settings = {
|
||||
registry-mirrors = [
|
||||
"https://mirror.gcr.io"
|
||||
"https://dockerhub.timeweb.cloud"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
docker-compose
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
virtualisation.libvirtd = {
|
||||
enable = true;
|
||||
qemu.package = pkgs.qemu_kvm;
|
||||
};
|
||||
|
||||
users.users.ada.extraGroups = [ "libvirtd" ];
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
services.zerotierone = {
|
||||
enable = true;
|
||||
joinNetworks = [ "743993800fa5a34c" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
ada-dev.ru {
|
||||
reverse_proxy 10.122.62.51:7080
|
||||
}
|
||||
|
||||
cloud.ada-dev.ru {
|
||||
reverse_proxy 10.122.62.51:8081
|
||||
}
|
||||
|
||||
git.ada-dev.ru {
|
||||
reverse_proxy 10.122.62.51:3002
|
||||
}
|
||||
|
||||
pass.ada-dev.ru {
|
||||
reverse_proxy 10.122.62.95:10380
|
||||
}
|
||||
|
||||
uptime.ada-dev.ru {
|
||||
reverse_proxy 10.122.62.95:3001
|
||||
}
|
||||
|
||||
|
||||
projects.ada-dev.ru {
|
||||
handle_path /neural* {
|
||||
reverse_proxy 10.122.62.51:4567
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:2-alpine
|
||||
container_name: caddy
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- /opt/data/caddy:/data
|
||||
- /opt/configs/caddy:/config
|
||||
networks: {}
|
||||
@@ -0,0 +1,4 @@
|
||||
FROM gitea/act_runner:latest
|
||||
|
||||
USER root
|
||||
RUN apk add --no-cache docker-cli docker-cli-compose
|
||||
@@ -0,0 +1,13 @@
|
||||
services:
|
||||
gitea-runner:
|
||||
build: .
|
||||
restart: always
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /opt/services:/opt/services
|
||||
- /opt/data/gitea-runner:/data
|
||||
environment:
|
||||
GITEA_INSTANCE_URL: https://git.ada-dev.ru
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: ${TOKEN}
|
||||
GITEA_RUNNER_NAME: ru-vps-runner
|
||||
GITEA_RUNNER_LABELS: ru-vps
|
||||
@@ -0,0 +1,56 @@
|
||||
mixed-port: 7890
|
||||
http-port: 7892
|
||||
socks-port: 7891
|
||||
allow-lan: true # Меняем с false на true
|
||||
bind-address: "0.0.0.0" # Добавляем - слушаем все интерфейсы
|
||||
mode: rule
|
||||
|
||||
external-controller: 127.0.0.1:9090
|
||||
external-ui: /root/.config/mihomo/ui
|
||||
# secret: "changeme"
|
||||
|
||||
authentication:
|
||||
- "ada:Holivarr588856"
|
||||
|
||||
proxy-providers:
|
||||
main:
|
||||
type: http
|
||||
url: "https://491b5056.withblancvpn.online/s/c1b50e857b4e41a59ea80bcf6d1953d3"
|
||||
interval: 3600
|
||||
health-check:
|
||||
enable: true
|
||||
url: https://www.gstatic.com/generate_204
|
||||
interval: 300
|
||||
|
||||
proxy-groups:
|
||||
- name: "URL-Test"
|
||||
type: url-test
|
||||
use: [main]
|
||||
url: "https://www.gstatic.com/generate_204"
|
||||
interval: 300 # Тестировать каждые 5 минут
|
||||
tolerance: 50
|
||||
|
||||
rules:
|
||||
- DOMAIN-SUFFIX,local,DIRECT
|
||||
- DOMAIN-SUFFIX,lan,DIRECT
|
||||
- DOMAIN-SUFFIX,ru,DIRECT
|
||||
- DOMAIN-SUFFIX,su,DIRECT
|
||||
- DOMAIN-SUFFIX,xn--p1ai,DIRECT
|
||||
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
|
||||
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
|
||||
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
|
||||
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
|
||||
- IP-CIDR,169.254.0.0/16,DIRECT,no-resolve
|
||||
- IP-CIDR6,::1/128,DIRECT,no-resolve
|
||||
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
|
||||
- IP-CIDR6,fe80::/10,DIRECT,no-resolve
|
||||
- GEOIP,RU,DIRECT
|
||||
- MATCH,URL-Test
|
||||
|
||||
# tun:
|
||||
# enable: true
|
||||
# stack: mixed
|
||||
# auto-route: true
|
||||
# auto-detect-interface: true
|
||||
# dns-hijack:
|
||||
# - "any:53"
|
||||
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"><script type="importmap">{"imports":{"#entry":"./_nuxt/Bmqvg1eR.js"}}</script><title>MetaCubeXD</title><script src="config.js" onerror="window.__METACUBEXD_CONFIG__={defaultBackendURL:''}"></script><script>window.__METACUBEXD_CONFIG__ = window.__METACUBEXD_CONFIG__ || { defaultBackendURL: '' }</script><link rel="stylesheet" href="./_nuxt/entry.B_k74qUh.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="./_nuxt/Bmqvg1eR.js"><link rel="modulepreload" as="script" crossorigin href="./_nuxt/CaGtQlYh.js"><link rel="modulepreload" as="script" crossorigin href="./_nuxt/QTnfLwEv.js"><script type="module" src="./_nuxt/Bmqvg1eR.js" crossorigin></script><meta name="theme-color" content="#000000"><link rel="icon" type="image/svg+xml" href="favicon.svg"><link rel="apple-touch-icon" href="pwa-192x192.png"><link rel="manifest" href="manifest.webmanifest"><script id="unhead:payload" type="application/json">{"title":"MetaCubeXD"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{appVersion:"1.251.3",mockMode:false,defaultBackendURL:"",i18n:{baseUrl:"",defaultLocale:"en",rootRedirect:"",redirectStatusCode:302,skipSettingLocaleOnNavigate:false,locales:[{code:"en",name:"English",language:""},{code:"zh",name:"简体中文",language:""},{code:"ru",name:"Русский",language:""}],detectBrowserLanguage:{alwaysRedirect:false,cookieCrossOrigin:false,cookieDomain:"",cookieKey:"metacubexd_lang",cookieSecure:false,fallbackLocale:"en",redirectOn:"root",useCookie:true},experimental:{localeDetector:"",typedPages:true,typedOptionsAndMessages:false,alternateLinkCanonicalQueries:true,devCache:false,cacheLifetime:"",stripMessagesPayload:false,preload:false,strictSeo:false,nitroContextDetection:true,httpCacheDuration:10,compactRoutes:false,prerenderMessages:false},domainLocales:{en:{domain:""},zh:{domain:""},ru:{domain:""}}}},app:{baseURL:"./",buildId:"cdc84ee9-d7c0-44a7-96d3-b0595bcf2138",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1780682638349,false]</script></body></html>
|
||||
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"><script type="importmap">{"imports":{"#entry":"./_nuxt/Bmqvg1eR.js"}}</script><title>MetaCubeXD</title><script src="config.js" onerror="window.__METACUBEXD_CONFIG__={defaultBackendURL:''}"></script><script>window.__METACUBEXD_CONFIG__ = window.__METACUBEXD_CONFIG__ || { defaultBackendURL: '' }</script><link rel="stylesheet" href="./_nuxt/entry.B_k74qUh.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="./_nuxt/Bmqvg1eR.js"><link rel="modulepreload" as="script" crossorigin href="./_nuxt/CaGtQlYh.js"><link rel="modulepreload" as="script" crossorigin href="./_nuxt/QTnfLwEv.js"><script type="module" src="./_nuxt/Bmqvg1eR.js" crossorigin></script><meta name="theme-color" content="#000000"><link rel="icon" type="image/svg+xml" href="favicon.svg"><link rel="apple-touch-icon" href="pwa-192x192.png"><link rel="manifest" href="manifest.webmanifest"><script id="unhead:payload" type="application/json">{"title":"MetaCubeXD"}</script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{appVersion:"1.251.3",mockMode:false,defaultBackendURL:"",i18n:{baseUrl:"",defaultLocale:"en",rootRedirect:"",redirectStatusCode:302,skipSettingLocaleOnNavigate:false,locales:[{code:"en",name:"English",language:""},{code:"zh",name:"简体中文",language:""},{code:"ru",name:"Русский",language:""}],detectBrowserLanguage:{alwaysRedirect:false,cookieCrossOrigin:false,cookieDomain:"",cookieKey:"metacubexd_lang",cookieSecure:false,fallbackLocale:"en",redirectOn:"root",useCookie:true},experimental:{localeDetector:"",typedPages:true,typedOptionsAndMessages:false,alternateLinkCanonicalQueries:true,devCache:false,cacheLifetime:"",stripMessagesPayload:false,preload:false,strictSeo:false,nitroContextDetection:true,httpCacheDuration:10,compactRoutes:false,prerenderMessages:false},domainLocales:{en:{domain:""},zh:{domain:""},ru:{domain:""}}}},app:{baseURL:"./",buildId:"cdc84ee9-d7c0-44a7-96d3-b0595bcf2138",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1780682638350,false]</script></body></html>
|
||||
@@ -0,0 +1 @@
|
||||
d.metacubex.one
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{a as e,i as t,r as n}from"./DhTvfVif.js";import{t as r}from"./CuyTkb7v.js";var i=`[object Symbol]`;function a(e){return typeof e==`symbol`||n(e)&&t(e)==i}var o=/\s/;function s(e){for(var t=e.length;t--&&o.test(e.charAt(t)););return t}var c=/^\s+/;function l(e){return e&&e.slice(0,s(e)+1).replace(c,``)}var u=NaN,d=/^[-+]0x[0-9a-f]+$/i,f=/^0b[01]+$/i,p=/^0o[0-7]+$/i,m=parseInt;function h(e){if(typeof e==`number`)return e;if(a(e))return u;if(r(e)){var t=typeof e.valueOf==`function`?e.valueOf():e;e=r(t)?t+``:t}if(typeof e!=`string`)return e===0?e:+e;e=l(e);var n=f.test(e);return n||p.test(e)?m(e.slice(2),n?2:8):d.test(e)?u:+e}var g=function(){return e.Date.now()},_=`Expected a function`,v=Math.max,y=Math.min;function b(e,t,n){var i,a,o,s,c,l,u=0,d=!1,f=!1,p=!0;if(typeof e!=`function`)throw TypeError(_);t=h(t)||0,r(n)&&(d=!!n.leading,f=`maxWait`in n,o=f?v(h(n.maxWait)||0,t):o,p=`trailing`in n?!!n.trailing:p);function m(t){var n=i,r=a;return i=a=void 0,u=t,s=e.apply(r,n),s}function b(e){return u=e,c=setTimeout(C,t),d?m(e):s}function x(e){var n=e-l,r=e-u,i=t-n;return f?y(i,o-r):i}function S(e){var n=e-l,r=e-u;return l===void 0||n>=t||n<0||f&&r>=o}function C(){var e=g();if(S(e))return w(e);c=setTimeout(C,x(e))}function w(e){return c=void 0,p&&i?m(e):(i=a=void 0,s)}function T(){c!==void 0&&clearTimeout(c),u=0,i=l=a=c=void 0}function E(){return c===void 0?s:w(g())}function D(){var e=g(),n=S(e);if(i=arguments,a=this,l=e,n){if(c===void 0)return b(l);if(f)return clearTimeout(c),c=setTimeout(C,t),m(l)}return c===void 0&&(c=setTimeout(C,t)),s}return D.cancel=T,D.flush=E,D}var x=`Expected a function`;function S(e,t,n){var i=!0,a=!0;if(typeof e!=`function`)throw TypeError(x);return r(n)&&(i=`leading`in n?!!n.leading:i,a=`trailing`in n?!!n.trailing:a),b(e,t,{leading:i,maxWait:t,trailing:a})}export{S as t};
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{D as e,G as t,H as n,T as r,b as i,d as a,v as o,vt as s,wt as c,x as l,xt as u}from"./CaGtQlYh.js";import{J as d,X as f,Y as p,q as m}from"#entry";var h={class:`flex shrink-0 items-center overflow-hidden rounded-lg border border-base-content/12`},g=[`disabled`],_=[`disabled`],v={key:0,class:`flex items-center border-r border-r-base-content/10 bg-base-200/80 px-1 text-xs text-base-content/40`},y=[`onClick`],b=[`disabled`],x=[`disabled`],S=Object.assign(e({__name:`ConnectionsPagination`,props:{currentPage:{},totalPages:{},visiblePages:{}},emits:[`goToPage`,`previous`,`next`],setup(e,{emit:S}){let C=S;return(S,w)=>(n(),l(`div`,h,[o(`button`,{class:`flex h-7 min-w-7 cursor-pointer items-center justify-center border-r border-none border-r-base-content/10 bg-base-200/80 px-1.5 text-xs text-base-content transition-all duration-150 ease-out hover:not-disabled:bg-base-content/10 disabled:cursor-not-allowed disabled:opacity-40`,disabled:e.currentPage===0,onClick:w[0]||=e=>C(`goToPage`,0)},[r(s(d),{size:14})],8,g),o(`button`,{class:`flex h-7 min-w-7 cursor-pointer items-center justify-center border-r border-none border-r-base-content/10 bg-base-200/80 px-1.5 text-xs text-base-content transition-all duration-150 ease-out hover:not-disabled:bg-base-content/10 disabled:cursor-not-allowed disabled:opacity-40`,disabled:e.currentPage===0,onClick:w[1]||=e=>C(`previous`)},[r(s(f),{size:14})],8,_),(n(!0),l(a,null,t(e.visiblePages,(t,r)=>(n(),l(a,{key:t},[r>0&&e.visiblePages[r-1]!==t-1?(n(),l(`span`,v,` ··· `)):i(``,!0),o(`button`,{class:u([`flex h-7 min-w-8 cursor-pointer items-center justify-center border-r border-none border-r-base-content/10 bg-base-200/80 px-1.5 text-xs text-base-content transition-all duration-150 ease-out last:border-r-0 hover:not-disabled:bg-base-content/10 disabled:cursor-not-allowed disabled:opacity-40`,{"bg-primary! text-primary-content! hover:bg-primary!":e.currentPage===t}]),onClick:e=>C(`goToPage`,t)},c(t+1),11,y)],64))),128)),o(`button`,{class:`flex h-7 min-w-7 cursor-pointer items-center justify-center border-r border-none border-r-base-content/10 bg-base-200/80 px-1.5 text-xs text-base-content transition-all duration-150 ease-out last:border-r-0 hover:not-disabled:bg-base-content/10 disabled:cursor-not-allowed disabled:opacity-40`,disabled:e.currentPage>=e.totalPages-1,onClick:w[2]||=e=>C(`next`)},[r(s(p),{size:14})],8,b),o(`button`,{class:`flex h-7 min-w-7 cursor-pointer items-center justify-center border-none bg-base-200/80 px-1.5 text-xs text-base-content transition-all duration-150 ease-out last:border-r-0 hover:not-disabled:bg-base-content/10 disabled:cursor-not-allowed disabled:opacity-40`,disabled:e.currentPage>=e.totalPages-1,onClick:w[3]||=t=>C(`goToPage`,e.totalPages-1)},[r(s(m),{size:14})],8,x)]))}}),{__name:`ConnectionsPagination`});export{S as t};
|
||||
@@ -0,0 +1,2 @@
|
||||
try{self[`workbox:window:7.4.0`]&&_()}catch{}function e(e,t){return new Promise((function(n){var r=new MessageChannel;r.port1.onmessage=function(e){n(e.data)},e.postMessage(t,[r.port2])}))}function t(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function n(e,t,n){return t&&function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,`value`in r&&(r.writable=!0),Object.defineProperty(e,a(r.key),r)}}(e.prototype,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function r(e,n){var r=typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(r)return(r=r.call(e)).next.bind(r);if(Array.isArray(e)||(r=function(e,n){if(e){if(typeof e==`string`)return t(e,n);var r={}.toString.call(e).slice(8,-1);return r===`Object`&&e.constructor&&(r=e.constructor.name),r===`Map`||r===`Set`?Array.from(e):r===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?t(e,n):void 0}}(e))||n){r&&(e=r);var i=0;return function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}}}throw TypeError(`Invalid attempt to iterate non-iterable instance.
|
||||
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function i(e,t){return i=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},i(e,t)}function a(e){var t=function(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return String(e)}(e,`string`);return typeof t==`symbol`?t:t+``}try{self[`workbox:core:7.4.0`]&&_()}catch{}var o=function(){var e=this;this.promise=new Promise((function(t,n){e.resolve=t,e.reject=n}))};function s(e,t){var n=location.href;return new URL(e,n).href===new URL(t,n).href}var c=function(e,t){this.type=e,Object.assign(this,t)};function l(e,t,n){return e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e}function u(){}var d={type:`SKIP_WAITING`};function f(e,t){return e&&e.then?e.then(u):Promise.resolve()}var p=function(t){function r(e,n){var r,i;return n===void 0&&(n={}),(r=t.call(this)||this).nn={},r.tn=0,r.rn=new o,r.en=new o,r.on=new o,r.un=0,r.an=new Set,r.cn=function(){var e=r.fn,t=e.installing;r.tn>0||!s(t.scriptURL,r.sn.toString())||performance.now()>r.un+6e4?(r.vn=t,e.removeEventListener(`updatefound`,r.cn)):(r.hn=t,r.an.add(t),r.rn.resolve(t)),++r.tn,t.addEventListener(`statechange`,r.ln)},r.ln=function(e){var t=r.fn,n=e.target,i=n.state,a=n===r.vn,o={sw:n,isExternal:a,originalEvent:e};!a&&r.mn&&(o.isUpdate=!0),r.dispatchEvent(new c(i,o)),i===`installed`?r.wn=self.setTimeout((function(){i===`installed`&&t.waiting===n&&r.dispatchEvent(new c(`waiting`,o))}),200):i===`activating`&&(clearTimeout(r.wn),a||r.en.resolve(n))},r.yn=function(e){var t=r.hn,n=t!==navigator.serviceWorker.controller;r.dispatchEvent(new c(`controlling`,{isExternal:n,originalEvent:e,sw:t,isUpdate:r.mn})),n||r.on.resolve(t)},r.gn=(i=function(e){var t=e.data,n=e.ports,i=e.source;return l(r.getSW(),(function(){r.an.has(i)&&r.dispatchEvent(new c(`message`,{data:t,originalEvent:e,ports:n,sw:i}))}))},function(){var e=[...arguments];try{return Promise.resolve(i.apply(this,e))}catch(e){return Promise.reject(e)}}),r.sn=e,r.nn=n,navigator.serviceWorker.addEventListener(`message`,r.gn),r}var a,u=t;(a=r).prototype=Object.create(u.prototype),a.prototype.constructor=a,i(a,u);var p=r.prototype;return p.register=function(e){var t=(e===void 0?{}:e).immediate,n=t!==void 0&&t;try{var r=this;return l(function(e,t){var n=e();return n&&n.then?n.then(t):t(n)}((function(){if(!n&&document.readyState!==`complete`)return f(new Promise((function(e){return window.addEventListener(`load`,e)})))}),(function(){return r.mn=!!navigator.serviceWorker.controller,r.dn=r.pn(),l(r.bn(),(function(e){r.fn=e,r.dn&&(r.hn=r.dn,r.en.resolve(r.dn),r.on.resolve(r.dn),r.dn.addEventListener(`statechange`,r.ln,{once:!0}));var t=r.fn.waiting;return t&&s(t.scriptURL,r.sn.toString())&&(r.hn=t,Promise.resolve().then((function(){r.dispatchEvent(new c(`waiting`,{sw:t,wasWaitingBeforeRegister:!0}))})).then((function(){}))),r.hn&&(r.rn.resolve(r.hn),r.an.add(r.hn)),r.fn.addEventListener(`updatefound`,r.cn),navigator.serviceWorker.addEventListener(`controllerchange`,r.yn),r.fn}))})))}catch(e){return Promise.reject(e)}},p.update=function(){try{return this.fn?l(f(this.fn.update())):l()}catch(e){return Promise.reject(e)}},p.getSW=function(){return this.hn===void 0?this.rn.promise:Promise.resolve(this.hn)},p.messageSW=function(t){try{return l(this.getSW(),(function(n){return e(n,t)}))}catch(e){return Promise.reject(e)}},p.messageSkipWaiting=function(){this.fn&&this.fn.waiting&&e(this.fn.waiting,d)},p.pn=function(){var e=navigator.serviceWorker.controller;return e&&s(e.scriptURL,this.sn.toString())?e:void 0},p.bn=function(){try{var e=this;return l(function(e,t){try{var n=e()}catch(e){return t(e)}return n&&n.then?n.then(void 0,t):n}((function(){return l(navigator.serviceWorker.register(e.sn,e.nn),(function(t){return e.un=performance.now(),t}))}),(function(e){throw e})))}catch(e){return Promise.reject(e)}},n(r,[{key:`active`,get:function(){return this.en.promise}},{key:`controlling`,get:function(){return this.on.promise}}])}(function(){function e(){this.Pn=new Map}var t=e.prototype;return t.addEventListener=function(e,t){this.jn(e).add(t)},t.removeEventListener=function(e,t){this.jn(e).delete(t)},t.dispatchEvent=function(e){e.target=this;for(var t,n=r(this.jn(e.type));!(t=n()).done;)(0,t.value)(e)},t.jn=function(e){return this.Pn.has(e)||this.Pn.set(e,new Set),this.Pn.get(e)},e}());export{p as Workbox};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user