This commit is contained in:
zhaojing1987 2023-11-04 16:08:54 +08:00
parent c84fda10ff
commit d206f075cf
37 changed files with 563 additions and 137 deletions

View file

@ -0,0 +1,3 @@
Metadata-Version: 2.1
Name: apphub
Version: 0.2

View file

@ -0,0 +1,10 @@
README.md
setup.py
src/apphub.egg-info/PKG-INFO
src/apphub.egg-info/SOURCES.txt
src/apphub.egg-info/dependency_links.txt
src/apphub.egg-info/entry_points.txt
src/apphub.egg-info/requires.txt
src/apphub.egg-info/top_level.txt
src/cli/__init__.py
src/cli/apphub_cli.py

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,2 @@
[console_scripts]
apphub = cli.apphub_cli:cli

View file

@ -0,0 +1 @@
click

View file

@ -0,0 +1 @@
cli

View file

@ -22,7 +22,7 @@ path = /websoft9/library/apps
path = /websoft9/media/json/
[api_key]
key = 9deeaf0d9f6f78c289f199a2631dc793b823d24024258385faaf833ea31e4ff6
key = d0a4996ad7819ae91a80c05c0d21800b610b5bf9fd53745db16e2f2ad9ae193c
[domain]
wildcard_domain = test.websoft9.cn

View file

@ -14,11 +14,6 @@ from fastapi.responses import HTMLResponse
from fastapi.security.api_key import APIKeyHeader
uvicorn_logger = logging.getLogger("uvicorn")
# for handler in uvicorn_logger.handlers:
# uvicorn_logger.removeHandler(handler)
# for handler in logger._error_logger.handlers:
# uvicorn_logger.addHandler(handler)
# 创建一个日志处理器,将日志发送到 stdout
stdout_handler = logging.StreamHandler(sys.stdout)
@ -28,11 +23,13 @@ uvicorn_logger.addHandler(stdout_handler)
uvicorn_logger.setLevel(logging.INFO)
API_KEY_NAME = "api_key"
API_KEY_NAME = "x-api-key"
api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)
async def verify_key(request: Request, api_key_header: str = Security(api_key_header)):
if request.url.path == "/docs":
logger.access(request.headers)
logger.access(request.url.path)
if request.url.path == "/api/docs":
return None
if api_key_header is None:
@ -59,7 +56,9 @@ app = FastAPI(
description="This documentation describes the AppHub API.",
version="0.0.1",
docs_url=None,
dependencies=[Depends(verify_key)]
root_path="/api",
servers=[{"url": "/api"}],
dependencies=[Depends(verify_key)],
)
app.mount("/static", StaticFiles(directory="swagger-ui"), name="static")
@ -71,14 +70,14 @@ async def custom_swagger_ui_html():
<html>
<head>
<title>Websoft9 API</title>
<link rel="stylesheet" type="text/css" href="/static/swagger-ui.css">
<script src="/static/swagger-ui-bundle.js"></script>
<link rel="stylesheet" type="text/css" href="/api/static/swagger-ui.css">
<script src="/api/static/swagger-ui-bundle.js"></script>
</head>
<body>
<div id="swagger-ui"></div>
<script>
const ui = SwaggerUIBundle({
url: "/openapi.json",
url: "/api/openapi.json",
dom_id: '#swagger-ui',
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
layout: "BaseLayout"

View file

@ -1,6 +1,21 @@
## 0.8.22 release on 2023-09-27
## 0.8.29-rc1 release on 2023-11-04
1. add systemd to websoft9 artifacts
1. gitea,myapps,appstore update
2. apphub domains
## 0.8.28 release on 2023-11-01
1. improve dockerfile to reduce image size
2. fixed update_zip.sh
3. hide websoft9 containers
## 0.8.27 release on 2023-10-31
1. new websoft9 init
## 0.8.26 release on 2023-09-27
1. appmanage change to apphub
## 0.8.20 release on 2023-08-23

View file

@ -1 +1,2 @@
1. Add install: developer mode at install.sh
1. gitea,myapps,appstore update
2. apphub domains

View file

@ -1,55 +1,59 @@
# modify time: 202310231530, you can modify here to trigger Docker Build action
# modify time: 202311040940, you can modify here to trigger Docker Build action
FROM python:3.10-bullseye AS buildstage
FROM python:3.10-slim-bullseye
LABEL maintainer="Websoft9<help@websoft9.com>"
LABEL version="0.0.6"
ENV LIBRARY_VERSION=v0.5.8
# Prepare library
RUN wget https://github.com/Websoft9/docker-library/archive/refs/tags/$LIBRARY_VERSION.zip -O ./library.zip && \
unzip library.zip && \
mv docker-library-* library && \
mkdir credentials && \
echo "This folder stored the credentials of other services that apphub will connect" > credentials/readme && \
# Prepare Media and master data from Contentful
git clone --depth=1 https://github.com/swagger-api/swagger-ui.git && \
wget https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js && \
cp redoc.standalone.js swagger-ui/dist && \
git clone --depth=1 https://github.com/Websoft9/plugin-appstore && \
mv -f plugin-appstore/data ./media && \
git clone --depth=1 https://github.com/Websoft9/websoft9
FROM python:3.10-slim-bullseye
WORKDIR /websoft9
COPY --from=buildstage /media/data ./media
COPY --from=buildstage /library ./library
COPY --from=buildstage /websoft9/apphub ./apphub
COPY --from=buildstage /swagger-ui/dist ./apphub/swagger-ui
ENV LIBRARY_VERSION=0.5.8
ENV MEDIA_VERSION=0.0.3
ENV websoft9_repo="https://github.com/Websoft9/websoft9"
ENV docker_library_repo="https://github.com/Websoft9/docker-library"
ENV media_repo="https://github.com/Websoft9/media"
ENV source_github_pages="https://websoft9.github.io/websoft9"
RUN apt update && apt install git jq iproute2 supervisor -y && \
mkdir credentials && \
echo "This folder stored the credentials of other services that integrated with apphub" > credentials/readme
RUN pip install --no-cache-dir --upgrade -r apphub/requirements.txt
RUN pip install -e ./apphub
RUN apt update && apt install -y --no-install-recommends curl git jq cron iproute2 supervisor rsync wget unzip zip && \
# Prepare source files
wget $docker_library_repo/archive/refs/tags/$LIBRARY_VERSION.zip -O ./library.zip && \
unzip library.zip && \
mv docker-library-* w9library && \
rm -rf w9library/.github && \
wget $media_repo/archive/refs/tags/$MEDIA_VERSION.zip -O ./media.zip && \
unzip media.zip && \
mv media-* w9media && \
rm -rf w9media/.github && \
git clone --depth=1 https://github.com/swagger-api/swagger-ui.git && \
wget https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js && \
cp redoc.standalone.js swagger-ui/dist && \
git clone --depth=1 $websoft9_repo ./w9source && \
cp -r ./w9media ./media && \
cp -r ./w9library ./library && \
cp -r ./w9source/apphub ./apphub && \
cp -r ./swagger-ui/dist ./apphub/swagger-ui && \
cp -r ./w9source/apphub/src/config ./config && \
cp -r ./w9source/docker/apphub/script ./script && \
curl -o ./script/update_zip.sh $source_github_pages/scripts/update_zip.sh && \
pip install --no-cache-dir --upgrade -r apphub/requirements.txt && \
pip install -e ./apphub && \
# Clean cache and install files
rm -rf apphub/docs apphub/tests library.zip media.zip redoc.standalone.js swagger-ui w9library w9media w9source && \
apt clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/man /usr/share/doc /usr/share/doc-base
# supervisor
COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN chmod +r /etc/supervisor/conf.d/supervisord.conf
COPY config/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# cron
COPY config/cron /etc/cron.d/cron
RUN echo "" >> /etc/cron.d/cron && crontab /etc/cron.d/cron
# chmod for all .sh script
RUN find /websoft9/script -name "*.sh" -exec chmod +x {} \;
VOLUME /websoft9/apphub/logs
VOLUME /websoft9/apphub/src/config
VOLUME /websoft9/media
# Clean cache and install files
RUN rm -rf apphub/docs apphub/tests library.zip plugin-appstore && \
apt clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/man /usr/share/doc /usr/share/doc-base
EXPOSE 8080
ENTRYPOINT ["/entrypoint.sh"]
ENTRYPOINT ["/websoft9/script/entrypoint.sh"]

View file

@ -1,6 +1,4 @@
ARG APPHUB_VERSION
FROM websoft9dev/apphub:${APPHUB_VERSION} as buildstage
RUN mkdir -p /websoft9/apphub-dev
COPY apphub/config/developer.sh /developer.sh
RUN chmod +x /developer.sh
RUN sed -i '/supervisorctl start apphub/c\supervisorctl start apphubdev' /entrypoint.sh
RUN sed -i '/supervisorctl start apphub/c\supervisorctl start apphubdev' /websoft9/script/entrypoint.sh

View file

@ -0,0 +1 @@
0 2 * * * /websoft9/script/update.sh

View file

@ -17,7 +17,7 @@ stderr_logfile=/var/log/supervisord.log
stderr_logfile_maxbytes=0
[program:apphubdev]
command=/developer.sh
command=/websoft9/script/developer.sh
autostart=false
user=root
stdout_logfile=/var/log/supervisord.log
@ -25,6 +25,15 @@ stdout_logfile_maxbytes=0
stderr_logfile=/var/log/supervisord.log
stderr_logfile_maxbytes=0
[program:cron]
command=cron -f
autostart=true
user=root
stdout_logfile=/var/log/supervisord.log
stdout_logfile_maxbytes=0
stderr_logfile=/var/log/supervisord.log
stderr_logfile_maxbytes=0
[program:media]
command=uvicorn src.media:app --host 0.0.0.0 --port 8081
autostart=true

View file

@ -0,0 +1,17 @@
#!/bin/bash
source_path="/websoft9/apphub-dev"
echo "Start to cp source code"
if [ ! "$(ls -A $source_path)" ]; then
cp -r /websoft9/apphub/* $source_path
fi
cp -r /websoft9/apphub/swagger-ui $source_path
echo "Install apphub cli"
pip uninstall apphub -y
pip install -e $source_path
echo "Running the apphub"
cd $source_path
exec uvicorn src.main:app --reload --host 0.0.0.0 --port 8080

View file

@ -0,0 +1,56 @@
#!/bin/bash
# Define PATH
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
# Export PATH
export PATH
set -e
bash /websoft9/script/migration.sh
try_times=5
supervisord
supervisorctl start apphub
# set git user and email
for ((i=0; i<$try_times; i++)); do
set +e
username=$(apphub getconfig --section gitea --key user_name 2>/dev/null)
email=$(apphub getconfig --section gitea --key user_email 2>/dev/null)
set -e
if [ -n "$username" ] && [ -n "$email" ]; then
break
fi
echo "Wait for service running, retrying..."
sleep 3
done
if [[ -n "$username" ]]; then
echo "git config --global user.name $username"
git config --global user.name "$username"
else
echo "username is null, git config username failed"
exit 1
fi
regex="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
if [[ $email =~ $regex ]]; then
echo "git config --global user.email $email"
git config --global user.email "$email"
else
echo "Not have correct email, git config email failed"
exit 1
fi
create_apikey() {
if [ ! -f /websoft9/apphub/src/config/initialized ] || [ -z "$(apphub getkey)" ]; then
echo "Create new apikey"
apphub genkey
touch /websoft9/apphub/src/config/initialized 2>/dev/null
fi
}
create_apikey
tail -n 1000 -f /var/log/supervisord.log

View file

@ -0,0 +1,51 @@
#!/bin/bash
echo "start to migrate config.ini"
migrate_ini() {
# Define file paths, use template ini and syn exsit items from target ini
export target_ini="$1"
export template_ini="$2"
python3 - <<EOF
import configparser
import os
import sys
target_ini = os.environ['target_ini']
template_ini = os.environ['template_ini']
# Create two config parsers
target_parser = configparser.ConfigParser()
template_parser = configparser.ConfigParser()
try:
target_parser.read(target_ini)
template_parser.read(template_ini)
except configparser.MissingSectionHeaderError:
print("Error: The provided files are not valid INI files.")
sys.exit(1)
# use target_parser to override template_parser
for section in target_parser.sections():
if template_parser.has_section(section):
for key, value in target_parser.items(section):
if template_parser.has_option(section, key):
template_parser.set(section, key, value)
with open(target_ini, 'w') as f:
template_parser.write(f)
EOF
}
migrate_ini "/websoft9/apphub/src/config/config.ini" "/websoft9/config/config.ini"
if [ $? -eq 0 ]; then
echo "Success to update config.ini"
else
echo "Fail to update config.ini, skip it"
fi

View file

@ -0,0 +1,9 @@
#!/bin/bash
echo "$(date) - Compare remote version and local version." | tee -a /var/log/supervisord.log
echo "$(date) - Download remote packages and replace local data." | tee -a /var/log/supervisord.log
bash /websoft9/script/update_zip.sh --package_name "media-latest.zip" --sync_to "/websoft9/media"
bash /websoft9/script/update_zip.sh --package_name "library-latest.zip" --sync_to "/websoft9/library"
echo "$(date) - Success to update library and media."

View file

@ -1,4 +1,4 @@
# modify time: 202310191733, you can modify here to trigger Docker Build action
# modify time: 202311031633, you can modify here to trigger Docker Build action
# step1: Build entrypoint execute program init_portainer by golang
FROM golang:latest AS builder

View file

@ -12,19 +12,27 @@ import (
func main() {
filePath := "/data/credential"
initPath := "/data/init"
_, err := os.Stat(filePath)
if os.IsNotExist(err) {
fmt.Println("credential is not exist, create it.")
password := generatePassword(16)
err := writeToFile(filePath, password)
if err != nil {
fmt.Println("write file error:", err)
return
_, err := os.Stat(initPath)
if os.IsNotExist(err) {
fmt.Println("credential is not exist, create it.")
password := generatePassword(16)
err := writeToFile(filePath, password)
if err != nil {
fmt.Println("write file error:", err)
return
}
} else {
fmt.Println("credential is exist, skip it.")
}
// call portainer
cmd := exec.Command("./portainer", "--admin-password-file", filePath)
cmd := exec.Command("./portainer", "--admin-password-file", filePath, "--hide-label", "owner=websoft9")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@ -32,10 +40,12 @@ func main() {
if err != nil {
fmt.Println("error running compiled_program:", err)
return
}else{
os.Create(initPath)
}
}else{
fmt.Println("credential is exist, skip it.")
cmd := exec.Command("./portainer")
cmd := exec.Command("./portainer", "--hide-label", "owner=websoft9")
cmd.Run()
}

View file

@ -22,6 +22,9 @@ services:
- deployment
- git
- proxy
labels:
- "owner=websoft9"
- "com.docker.compose.w9_http.port:8080"
deployment:
image: websoft9dev/deployment:$DEPLOYMENT_VERSION
@ -40,7 +43,8 @@ services:
timeout: 30s
retries: 4
labels:
com.docker.compose.w9_http.port: 9000
- "owner=websoft9"
- "com.docker.compose.w9_http.port:9000"
git:
image: websoft9dev/git:$GIT_VERSION
@ -61,7 +65,8 @@ services:
- REQUIRE_SIGNIN_VIEW=false
- ROOT_URL=http://localhost/w9git/
labels:
com.docker.compose.w9_http.port: 3000
- "owner=websoft9"
- "com.docker.compose.w9_http.port:3000"
proxy:
image: websoft9dev/proxy:$PROXY_VERSION
@ -75,9 +80,10 @@ services:
- nginx_data:/data
- nginx_letsencrypt:/etc/letsencrypt
labels:
com.docker.compose.w9_http.port: 80
com.docker.compose.w9_https.port: 443
com.docker.compose.w9_console.port: 81
- "owner=websoft9"
- "com.docker.compose.w9_http.port: 80"
- "com.docker.compose.w9_https.port: 443"
- "com.docker.compose.w9_console.port: 81"
networks:
default:

View file

@ -7,14 +7,14 @@ services:
restart: always
volumes:
- apphub_logs:/websoft9/apphub/logs
- apphub_media:/websoft9/media
- apphub_config:/websoft9/apphub/src/config
depends_on:
- deployment
- git
- proxy
labels:
com.docker.compose.w9_http.port: 8080
- "owner=websoft9"
- "com.docker.compose.w9_http.port:8080"
deployment:
image: websoft9dev/deployment:$DEPLOYMENT_VERSION
@ -31,7 +31,8 @@ services:
timeout: 30s
retries: 4
labels:
com.docker.compose.w9_http.port: 9000
- "owner=websoft9"
- "com.docker.compose.w9_http.port:9000"
git:
image: websoft9dev/git:$GIT_VERSION
@ -50,7 +51,8 @@ services:
- REQUIRE_SIGNIN_VIEW=false
- ROOT_URL=http://localhost/w9git/
labels:
com.docker.compose.w9_http.port: 3000
- "owner=websoft9"
- "com.docker.compose.w9_http.port:3000"
proxy:
image: websoft9dev/proxy:$PROXY_VERSION
@ -63,9 +65,10 @@ services:
- nginx_data:/data
- nginx_letsencrypt:/etc/letsencrypt
labels:
com.docker.compose.w9_http.port: 80
com.docker.compose.w9_https.port: 443
com.docker.compose.w9_console.port: 81
- "owner=websoft9"
- "com.docker.compose.w9_http.port: 80"
- "com.docker.compose.w9_https.port: 443"
- "com.docker.compose.w9_console.port: 81"
networks:
default:
@ -74,7 +77,6 @@ networks:
volumes:
apphub_logs:
apphub_media:
apphub_config:
portainer:
gitea:

View file

@ -1,4 +1,4 @@
# modify time: 202310181524, you can modify here to trigger Docker Build action
# modify time: 202310250925, you can modify here to trigger Docker Build action
# Dockerfile refer to: https://github.com/go-gitea/gitea/blob/main/Dockerfile
FROM gitea/gitea:1.20.4

View file

@ -8,7 +8,6 @@ response=""
cred_path="/data/gitea/credential"
admin_username="websoft9"
admin_email="help@websoft9.com"
user_exist=0
while [ "$response" != "200" ]; do
response=$(curl -s -o /dev/null -w "%{http_code}" localhost:3000)
@ -35,11 +34,11 @@ su -c "
exit 0
else
gitea admin user create --admin --username '$admin_username' --random-password --email '$admin_email' > /tmp/credential
user_exist=1
touch /data/gitea/create_user 2>/dev/null
fi
" git
if [ "$user_exist" -eq 1 ]; then
if [ -f /data/gitea/create_user ]; then
echo "Read credential from tmp"
username=$(grep -o "New user '[^']*" /tmp/credential | sed "s/New user '//")
if [ -z "$username" ] || [ "$username" != "websoft9" ]; then

View file

@ -1,13 +1,23 @@
# modify time: 202310181524, you can modify here to trigger Docker Build action
# Dockerfile refer to:https://github.com/NginxProxyManager/nginx-proxy-manager/blob/develop/docker/Dockerfile
# modify time: 202310261640, you can modify here to trigger Docker Build action
# from Dockerfile: https://github.com/NginxProxyManager/nginx-proxy-manager/blob/develop/docker/Dockerfile
# from image: https://hub.docker.com/r/jc21/nginx-proxy-manager
FROM jc21/nginx-proxy-manager:2.10.4
LABEL maintainer="Websoft9<help@websoft9.com>"
LABEL version="2.10.4"
RUN apt-get update && apt-get install -y curl jq
COPY ./config/initproxy.conf /data/nginx/proxy_host/
RUN apt-get update && apt-get install --no-install-recommends -y curl jq && rm -rf /var/lib/apt/lists/*
COPY ./config/initproxy.conf /etc/
COPY ./s6/w9init/setuser.sh /app/setuser.sh
COPY ./s6/w9init/migration.sh /app/migration.sh
RUN chmod +x /app/setuser.sh /app/migration.sh
COPY ./s6/init_user/init_user.sh /app/init_user.sh
RUN chmod +x /app/init_user.sh
CMD ["/bin/sh", "-c", "/app/init_user.sh && tail -f /dev/null"]
RUN export add_ip_data="const ipDataFile={[CLOUDFRONT_URL]:'ip-ranges.json',[CLOUDFARE_V4_URL]:'ips-v4',[CLOUDFARE_V6_URL]:'ips-v6'}[url];logger.info(ipDataFile);if(ipDataFile){return fs.readFile(__dirname+'/../lib/ipData/'+ipDataFile,'utf8',(error,data)=>{if(error){logger.error('fetch '+ipDataFile+' error');reject(error);return}logger.info('fetch '+ipDataFile+' success');resolve(data)})}" && \
sed -i "s#url);#&${add_ip_data}#g" /app/internal/ip_ranges.js && \
mkdir -p /app/lib/ipData && cd /app/lib/ipData && \
curl -O https://ip-ranges.amazonaws.com/ip-ranges.json && \
curl -O https://www.cloudflare.com/ips-v4 && \
curl -O https://www.cloudflare.com/ips-v6
CMD ["/bin/sh", "-c", "/app/migration.sh && /app/setuser.sh && tail -f /dev/null"]

View file

@ -102,20 +102,35 @@ server {
}
}
location /apidocs/static {
proxy_pass http://websoft9-apphub:8080/static;
location /apidocs/ {
proxy_pass http://websoft9-apphub:8080/docs;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
sub_filter 'spec-url="/apidocs/openapi.json' 'spec-url="/openapi.json';
}
location /apidocs/openapi.json {
proxy_pass http://websoft9-apphub:8080/;
location /static/ {
proxy_pass http://websoft9-apphub:8080/static/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /apidocs/ {
proxy_pass http://websoft9-apphub:8080/redoc;
sub_filter 'src="/static' 'src="/apidocs/static';
sub_filter 'spec-url="/' 'spec-url="/apidocs/openapi.json';
location = /openapi.json {
proxy_pass http://websoft9-apphub:8080/openapi.json;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /media/ {
proxy_pass http://websoft9-apphub:8081/images/;
}
# Custom
include /data/nginx/custom/server_proxy[.]conf;
}

View file

@ -0,0 +1,5 @@
# S6
S6 is a mulitply process management tools at Nginx Proxy Manager.
- nginx_proxy() at migration.sh: Migration initproxy.conf to Nginx, condition is compare Container created time and Named Volumes created time

View file

@ -0,0 +1,23 @@
#!/bin/bash
set +e
nginx_proxy(){
current_time=$(date +%s)
shadow_modified_time=$(stat -c %Y /etc/shadow)
time_difference=$((current_time - shadow_modified_time))
if [ ! -f /data/nginx/proxy_host/initproxy.conf ] || [ $time_difference -le 60 ]
then
cp /etc/initproxy.conf /data/nginx/proxy_host/
echo "Update initproxy.conf to Nginx"
else
echo "Don't need to update initproxy.conf to Nginx"
fi
}
nginx_proxy
set -e

View file

@ -0,0 +1,61 @@
#!/bin/bash
set +e
username="help@websoft9.com"
password=$(openssl rand -base64 16 | tr -d '/+' | cut -c1-16)
token=""
cred_path="/data/credential"
max_attempts=10
echo "Start to change nginxproxymanage users"
if [ -e "$cred_path" ]; then
echo "File $cred_path exists. Exiting script."
exit 0
fi
echo "create diretory"
mkdir -p "$(dirname "$cred_path")"
sleep 10
while [ -z "$token" ]; do
sleep 5
login_data=$(curl -X POST -H "Content-Type: application/json" -d '{"identity":"admin@example.com","scope":"user", "secret":"changeme"}' http://localhost:81/api/tokens)
token=$(echo $login_data | jq -r '.token')
done
echo "Change username(email)"
for attempt in $(seq 1 $max_attempts); do
response=$(curl -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d '{"email": "'$username'", "nickname": "admin", "is_disabled": false, "roles": ["admin"]}' http://localhost:81/api/users/1)
if [ $? -eq 0 ]; then
echo "Set username successful"
break
else
echo "Set username failed, retrying..."
sleep 5
if [ $attempt -eq $max_attempts ]; then
echo "Failed to set username after $max_attempts attempts. Exiting."
exit 1
fi
fi
done
echo "Update password"
for attempt in $(seq 1 $max_attempts); do
response=$(curl -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d '{"type":"password","current":"changeme","secret":"'$password'"}' http://localhost:81/api/users/1/auth)
if [ $? -eq 0 ]; then
echo "Set password successful"
echo "Save to credential"
json="{\"username\":\"$username\",\"password\":\"$password\"}"
echo "$json" > "$cred_path"
break
else
echo "Set password failed, retrying..."
sleep 5
if [ $attempt -eq $max_attempts ]; then
echo "Failed to set password after $max_attempts attempts. Exiting."
exit 1
fi
fi
done
set -e

View file

@ -198,18 +198,14 @@ check_ports() {
echo "Stop Websoft9 Proxy and Cockpit service for reserve ports..."
sudo docker stop websoft9-proxy 2>/dev/null || echo "docker stop websoft9-proxy not need "
sudo systemctl stop cockpit 2>/dev/null || echo "systemctl stop cockpit not need"
sudo systemctl stop cockpit.socket 2>/dev/null || echo "systemctl stop cockpit.socket not need"
for port in "${ports[@]}"; do
if ss -tuln | grep ":$port " >/dev/null; then
echo "Port $port is in use, install failed"
if ss -tuln | grep ":$port " >/dev/null && ! systemctl status cockpit.socket | grep "$port" >/dev/null; then
echo "Port $port is in use or not in cockpit.socket, install failed"
exit
fi
done
echo "All ports are available"
}
@ -334,8 +330,9 @@ install_backends() {
install_systemd() {
echo -e "\n\n-------- Systemd --------"
echo_prefix_systemd=$'\n[Systemd] - '
echo "$echo_prefix_systemdInstall Systemd service"
echo "$echo_prefix_systemd Install Systemd service"
if [ ! -d "$systemd_path" ]; then
sudo mkdir -p "$systemd_path"
@ -372,34 +369,17 @@ install_systemd() {
#--------------- main-----------------------------------------
check_ports $http_port $https_port $port
install_tools
download_source
bash $install_path/install/install_docker.sh
if [ $? -ne 0 ]; then
echo "install_docker failed with error $?. Exiting."
exit 1
fi
install_backends
bash $install_path/install/install_cockpit.sh
if [ $? -ne 0 ]; then
echo "install_cockpit failed with error $?. Exiting."
exit 1
fi
install_systemd
bash $install_path/install/install_plugins.sh
if [ $? -ne 0 ]; then
echo "install_plugins failed with error $?. Exiting."
exit 1
fi
echo "Restart Docker for Firewalld..."
sudo systemctl restart docker
install_systemd
endtime=$(date +%s)
runtime=$((endtime-starttime))
echo "Script execution time: $runtime seconds"

View file

@ -82,7 +82,7 @@ echo "install_path:$install_path"
related_containers=("websoft9-apphub")
echo_prefix_cockpit=$'\n[Cockpit] - '
# package cockpit depends_on [cockpit-bridge,cockpit-ws,cockpit-system], but update cockpit the depends don't update
cockpit_packages="cockpit cockpit-ws cockpit-bridge cockpit-system cockpit-pcp cockpit-storaged cockpit-networkmanager cockpit-session-recording cockpit-doc cockpit-packagekit cockpit-sosreport"
cockpit_packages="cockpit cockpit-ws cockpit-bridge cockpit-system cockpit-pcp cockpit-networkmanager cockpit-session-recording cockpit-doc cockpit-packagekit cockpit-sosreport"
menu_overrides_github_page_url="https://websoft9.github.io/websoft9/cockpit/menu_override"
cockpit_config_github_page_url="https://websoft9.github.io/websoft9/cockpit/cockpit.conf"
cockpit_menu_overrides=()

View file

@ -51,6 +51,7 @@ docker_exist() {
}
Install_Docker(){
echo "$echo_prefix_docker Installing Docker for your system"
# For redhat family
@ -73,7 +74,6 @@ Install_Docker(){
fi
}
Upgrade_Docker(){
if docker_exist; then
echo "$echo_prefix_docker Upgrading Docker for your system..."
@ -101,7 +101,7 @@ else
while ((retry_count < max_retries)); do
Install_Docker
if [ $? -ne 0 ]; then
if ! docker_exist; then
echo "Installation timeout or failed, retrying..."
((retry_count++))
sleep 3

View file

@ -106,4 +106,6 @@ while not q.empty():
sys.exit(1) # Exit the program if an error occurred
END
find /usr/share/cockpit -type f -name "*.py3" -exec chmod +x {} \;
echo "Plugins install successfully..."

View file

@ -0,0 +1,118 @@
#!/bin/bash
## This script is used for download zip files to a target directory
## apphub dockerfile is depends on this script
# Command-line options
# ==========================================================
#
# --channel <release|dev>
# Use the --channel option to install a release(production) or dev distribution. default is release, for example:
#
# $ sudo bash install.sh --channel release
#
# --package_name
# Use the --package_name option to define a zip file, for example:
#
# $ sudo bash install.sh --package_name media.zip
#
# --sync_to
# Use the sync_to option to define the target directory which zip file will unzip, for example:
#
# $ sudo bash install.sh --sync_to "/websoft9/media"
channel="release"
while [[ $# -gt 0 ]]; do
case $1 in
--channel)
channel="$2"
shift 2
;;
--package_name)
package_name="$2"
shift 2
;;
--sync_to)
sync_to="$2"
shift 2
;;
*)
shift
;;
esac
done
if [ -z "$package_name" ] || [ -z "$sync_to" ]; then
echo "Parameter package_name and sync_to is necessary"
exit 1
fi
# Define the artifact URL as a global variable
artifact_url="https://w9artifact.blob.core.windows.net/$channel/websoft9/plugin"
upgrade_zip() {
# Create the full URL by appending the package name to the artifact URL
local plugin_name=${package_name%%-*}
local url="$artifact_url/$plugin_name/$package_name"
# Initialize download attempts
local attempts=0
local max_attempts=2
# Download the package using wget
while [ $attempts -lt $max_attempts ]; do
wget --timeout=120 --no-clobber "$url" -O "/tmp/$package_name"
# Check if the download was successful
if [ $? -eq 0 ]; then
break
fi
attempts=$((attempts+1))
echo "Download attempt $attempts failed. Retrying in 5 seconds..."
sleep 5
done
# If the download still failed after max attempts, report an error and exit
if [ $attempts -eq $max_attempts ]; then
echo "Download failed for package: $package_name after $max_attempts attempts."
return 1
fi
# Unzip the downloaded package
unzip "/tmp/$package_name" -d "/tmp"
# Check if the unzip was successful
if [ $? -ne 0 ]; then
echo "Unzip failed for package: $package_name"
return 1
fi
# Get the name of the package without the .zip extension for syncing
local package_directory="${package_name%.zip}"
package_directory="${package_directory%%-*}"
if [ "$unzipped_folder" != "/tmp/$package_directory/" ]; then
mv "$unzipped_folder" "/tmp/$package_directory"
else
echo "The unzipped folder has the same name as the target folder."
fi
# Sync the unzipped package to the desired location
rsync -av "/tmp/$package_directory/" "$sync_to"
# Check if the sync was successful
if [ $? -ne 0 ]; then
echo "Sync failed for package: $package_name"
return 1
fi
echo "Successfully downloaded, unzipped, and synced package: $package_name"
# Remove the downloaded .zip file and the unzipped directory
rm -f "/tmp/$package_name"
rm -rf "/tmp/$package_directory"
return 0
}
upgrade_zip

View file

@ -1,9 +1,22 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
# 监控的文件
FILES="/lib/systemd/system/cockpit.socket /var/lib/docker/volumes/websoft9_apphub_config/_data/config.ini"
cockpit_port="9000"
container_name="websoft9-apphub"
volume_name="websoft9_apphub_config"
# get volume from container
function get_volume_path() {
local container_name="$1"
local volume_name="$2"
local mounts=$(docker inspect -f '{{ json .Mounts }}' "$container_name" | jq -r '.[] | select(.Name == "'$volume_name'") | .Source')
echo "$mounts"
}
volume_path=$(get_volume_path "$container_name" "$volume_name")
config_path="$volume_path/config.ini"
cockpit_service_path="/lib/systemd/system/cockpit.socket"
FILES="$cockpit_service_path $config_path"
# 监控文件发生变动时需要做的事情
on_change() {
@ -30,5 +43,4 @@ inotifywait -e modify -m $FILES | while read PATH EVENT FILE; do
echo "Set cockpit port by config.ini..."
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
on_change
done
done

View file

@ -60,8 +60,13 @@ set -e # Stop ignoring errors
length=${#containers[@]}
for ((i=0; i<$length; i++)); do
container=${containers[$i]}
section=${sections[$i]}
echo "$container:"
docker exec -i websoft9-apphub apphub setconfig --section $section --key user_pwd --value ${passwords[$container]}
if [[ -n ${passwords[$container]} ]]; then
echo "$container start to set password"
docker exec -i websoft9-apphub apphub setconfig --section $section --key user_pwd --value ${passwords[$container]}
else
echo "Password for $container is not set or empty. Skipping..."
fi
done

View file

@ -1,11 +1,11 @@
{
"version": "0.8.26-rc81",
"version": "0.8.29-rc1",
"plugins": {
"portainer": "0.0.7",
"nginx": "0.0.5",
"gitea": "0.0.1",
"myapps": "0.0.8",
"appstore": "0.0.7",
"gitea": "0.0.2",
"myapps": "0.0.9",
"appstore": "0.0.8",
"settings": "0.0.5",
"navigator": "0.5.10"
},