This commit is contained in:
zhaojing1987 2023-10-19 11:36:31 +08:00
parent a122babb95
commit cba08aa047
69 changed files with 769 additions and 187 deletions

0
apphub/build/lib/cli/__init__.py Normal file → Executable file
View file

0
apphub/build/lib/cli/apphub_cli.py Normal file → Executable file
View file

0
apphub/build/lib/src/__init__.py Normal file → Executable file
View file

0
apphub/build/lib/src/cli/__init__.py Normal file → Executable file
View file

0
apphub/build/lib/src/cli/apphub_cli.py Normal file → Executable file
View file

0
apphub/build/lib/src/main.py Normal file → Executable file
View file

407
apphub/install.sh Executable file
View file

@ -0,0 +1,407 @@
#!/bin/bash
# Define PATH
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
# Export PATH
export PATH
# Command-line options
# ==============================================================================
#
# --version
# Use the --version option to install a special version for installation. default is latest, for example:
#
# $ sudo bash install.sh --version "0.8.25"
#
# --port <9000>
# Use the --port option to set Websoft9 cosole port. default is 9000, for example:
#
# $ sudo bash install.sh --port 9001
#
# --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
#
# --path
# Use the --path option to for installation path for example:
#
# $ sudo bash install.sh --path "/data/websoft9/source"
#
# --devto
# Use the --devto option to developer mode, devto is the developer code path, for example:
#
# $ sudo bash install.sh --devto "/data/dev/mycode"
#
# ==============================================================================
# 设置参数的默认值
version="latest"
channel="release"
path="/data/websoft9/source"
# 获取参数值
while [[ $# -gt 0 ]]; do
case $1 in
--version)
version="$2"
shift 2
;;
--port)
port="$2"
shift 2
;;
--channel)
channel="$2"
shift 2
;;
--path)
path="$2"
shift 2
;;
--devto)
devto="$2"
shift 2
;;
*)
shift
;;
esac
done
if [ -n "$port" ]; then
export port
else
export port=9000
fi
starttime=$(date +%s)
# 输出参数值
echo -e "\n------ Welcome to install Websoft9, it will take 3-5 minutes ------"
echo -e "\nYour installation parameters are as follows: "
echo "--version: $version"
echo "--port: $port"
echo "--channel: $channel"
echo "--path: $path"
echo "--devto: $devto"
echo -e "\nYour OS: "
cat /etc/os-release | head -n 3 2>/dev/null
# Define global vars
# export var can send it to subprocess
export http_port=80
export https_port=443
export install_path=$path
export channel
export version
export systemd_path="/opt/websoft9/systemd"
export source_zip="websoft9-$version.zip"
export source_unzip="websoft9"
export source_github_pages="https://websoft9.github.io/websoft9"
# inotify-tools is at epel-release
export tools_yum="git curl wget epel-release yum-utils jq bc unzip inotify-tools"
export tools_apt="git curl wget jq bc unzip inotify-tools"
export docker_network="websoft9"
export artifact_url="https://w9artifact.blob.core.windows.net/$channel/websoft9"
echo Install from url: $artifact_url
# Define common functions
Wait_apt() {
# Function to check if apt is locked
local lock_files=("/var/lib/dpkg/lock" "/var/lib/apt/lists/lock")
for lock_file in "${lock_files[@]}"; do
while fuser "${lock_file}" >/dev/null 2>&1 ; do
echo "${lock_file} is locked by another process. Waiting..."
sleep 5
done
done
echo "APT locks are not held by any processes. You can proceed."
}
export -f Wait_apt
install_tools(){
echo_prefix_tools=$'\n[Tools] - '
echo "$echo_prefix_tools Starting install necessary tool..."
dnf --version >/dev/null 2>&1
dnf_status=$?
yum --version >/dev/null 2>&1
yum_status=$?
apt --version >/dev/null 2>&1
apt_status=$?
if [ $dnf_status -eq 0 ]; then
for package in $tools_yum; do sudo dnf install -y $package > /dev/null; done
elif [ $yum_status -eq 0 ]; then
for package in $tools_yum; do sudo yum install -y $package > /dev/null; done
elif [ $apt_status -eq 0 ]; then
while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do
echo "Waiting for other software managers to finish..."
sleep 5
done
sudo apt update -y 1>/dev/null 2>&1
apt install $tools_apt -y --assume-yes
else
echo "None of the required package managers are installed."
fi
}
download_source() {
echo_prefix_source=$'\n[Download Source] - '
echo "$echo_prefix_source Download Websoft9 source code from $artifact_url/$source_zip"
find . -type f -name "websoft9*.zip*" -exec rm -f {} \;
if [ -d "$install_path" ]; then
echo "Directory $install_path already exists and installation will cover it."
else
mkdir -p "$install_path"
fi
wget "$artifact_url/$source_zip"
if [ $? -ne 0 ]; then
echo "Failed to download source package."
exit 1
fi
sudo unzip -o "$source_zip" -d "$install_path" > /dev/null
if [ $? -ne 0 ]; then
echo "Failed to unzip source package."
exit 1
fi
cp -r $install_path/$source_unzip/* "$install_path"
if [ $? -ne 0 ]; then
echo "Move directory failed"
exit 1
fi
rm -rf "$source_zip" "$install_path/$source_unzip"
}
check_ports() {
local 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"
exit
fi
done
echo "All ports are available"
}
merge_json_files() {
local target_path="/etc/docker/daemon.json"
python3 - <<EOF 2>/dev/null
import json
import urllib.request
import os
def merge_json_files(file1, file2):
print("Merge from local file... ")
with open(file1, 'r') as f1, open(file2, 'r') as f2:
data1 = json.load(f1)
data2 = json.load(f2)
merged_data = {**data1, **data2}
with open(file1, 'w') as f:
json.dump(merged_data, f, indent=4)
def download_and_merge(url, file_path):
print("Download daemon.json from url and merge... ")
with urllib.request.urlopen(url) as response:
data = json.loads(response.read().decode())
with open(file_path, 'r') as f:
local_data = json.load(f)
merged_data = {**local_data, **data}
with open(file_path, 'w') as f:
json.dump(merged_data, f, indent=4)
# Create target file if it does not exist
if not os.path.exists("${target_path}"):
os.makedirs(os.path.dirname("${target_path}"), exist_ok=True)
with open("${target_path}", 'w') as f:
json.dump({}, f)
if os.path.exists("${install_path}/docker/daemon.json"):
merge_json_files("${target_path}", "${install_path}/docker/daemon.json")
elif urllib.request.urlopen("${source_github_pages}/docker/daemon.json").getcode() == 200:
download_and_merge("${source_github_pages}/docker/daemon.json", "${target_path}")
else:
print("No target daemon.json file need to merged")
EOF
if [ $? -ne 0 ]; then
echo "merge daemon.json failed, but install continue running"
fi
}
set_docker(){
echo "Set Docker for Websoft9 backend service..."
merge_json_files
if ! systemctl is-active --quiet firewalld; then
echo "firewalld is not running"
else
echo "Set firewall for Docker..."
sudo sudo firewall-cmd --permanent --new-zone=docker 2> /dev/null
sudo firewall-cmd --permanent --zone=docker --add-interface=docker0 2> /dev/null
sudo firewall-cmd --permanent --zone=docker --set-target=ACCEPT
sudo firewall-cmd --reload
sudo systemctl stop firewalld
sudo systemctl disable firewalld
fi
sudo systemctl restart docker
}
install_backends() {
echo_prefix_backends=$'\n[Backend] - '
echo "$echo_prefix_backends Install backend docker services"
set_docker
cd "$install_path/docker"
if [ $? -ne 0 ]; then
echo "Failed to change directory."
exit 1
fi
sudo docker network inspect $docker_network >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Docker network '$docker_network' already exists."
else
sudo docker network create $docker_network
if [ $? -ne 0 ]; then
echo "Failed to create docker network."
exit 1
fi
fi
# set to devloper mode
if [ -n "$devto" ]; then
sed -i "s|\(- \).*:/websoft9/apphub-dev|\1$devto:/websoft9/apphub-dev|g" docker-compose-dev.yml
composefile=docker-compose-dev.yml
else
composefile=docker-compose.yml
fi
container_names=$(docker ps -a --format "{{.Names}}" --filter "name=websoft9")
sudo docker compose -p websoft9 -f $composefile down
# delete some dead containers that docker compose cannot deleted
if [ ! -z "$container_names" ]; then
echo "Deleting containers:"
echo $container_names
docker rm -f $container_names 2>/dev/null
else
echo "No containers to delete."
fi
sudo docker compose -f $composefile pull
sudo docker compose -p websoft9 -f $composefile up -d --build
if [ $? -ne 0 ]; then
echo "Failed to start docker services."
exit 1
fi
}
install_systemd() {
echo_prefix_systemd=$'\n[Systemd] - '
echo "$echo_prefix_systemdInstall Systemd service"
if [ ! -d "$systemd_path" ]; then
sudo mkdir -p "$systemd_path"
fi
sudo cp -r $install_path/systemd/script/* "$systemd_path"
sudo cp -f "$install_path/systemd/websoft9.service" /lib/systemd/system/
if [ $? -ne 0 ]; then
echo "Failed to copy Systemd service file."
exit 1
fi
sudo systemctl daemon-reload
if [ $? -ne 0 ]; then
echo "Failed to reload Systemd daemon."
exit 1
fi
sudo systemctl enable websoft9.service
if [ $? -ne 0 ]; then
echo "Failed to enable Systemd service."
exit 1
fi
sudo systemctl start websoft9
if [ $? -ne 0 ]; then
echo "Failed to start Systemd service."
exit 1
fi
}
#--------------- 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
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"
echo -e "\n-- Install success! ------"
echo "Access Websoft9 console by: http://Internet IP:$(grep ListenStream /lib/systemd/system/cockpit.socket | cut -d= -f2) and using Linux user for login"

0
apphub/setup.py Normal file → Executable file
View file

View file

@ -5,14 +5,13 @@ from src.schemas.appInstall import appInstall
from src.schemas.appResponse import AppResponse
from src.schemas.errorResponse import ErrorResponse
from src.services.app_manager import AppManger
from src.core.logger import logger
router = APIRouter()
@router.get(
"/apps/catalog/{locale}",
summary="List Catalogsaaaaaaaaaaaaa",
description="List all app's catalogs aaaa",
summary="List Catalogs",
description="List all app's catalogs",
responses={
200: {"model": list[AppCatalogResponse]},
400: {"model": ErrorResponse},

View file

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

View file

@ -1,16 +0,0 @@
README.md
setup.py
/websoft9/apphub/src/apphub.egg-info/PKG-INFO
/websoft9/apphub/src/apphub.egg-info/SOURCES.txt
/websoft9/apphub/src/apphub.egg-info/dependency_links.txt
/websoft9/apphub/src/apphub.egg-info/entry_points.txt
/websoft9/apphub/src/apphub.egg-info/requires.txt
/websoft9/apphub/src/apphub.egg-info/top_level.txt
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

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

View file

@ -1 +0,0 @@
click

View file

@ -1 +0,0 @@
cli

0
apphub/src/cli/apphub.egg-info/PKG-INFO Normal file → Executable file
View file

0
apphub/src/cli/apphub.egg-info/SOURCES.txt Normal file → Executable file
View file

0
apphub/src/cli/apphub.egg-info/dependency_links.txt Normal file → Executable file
View file

0
apphub/src/cli/apphub.egg-info/entry_points.txt Normal file → Executable file
View file

0
apphub/src/cli/apphub.egg-info/requires.txt Normal file → Executable file
View file

0
apphub/src/cli/apphub.egg-info/top_level.txt Normal file → Executable file
View file

View file

@ -1,8 +1,7 @@
# The config for nginx proxy manager
[nginx_proxy_manager]
base_url = http://websoft9-proxy:81/api
user_name = help@websoft9.com
user_pwd = E3cMekM72yPp1pUX
user_pwd = 4yB5fU93GO4wMvxS
nike_name = admin
#The config for gitea.
@ -13,24 +12,20 @@ user_name = websoft9
email = help@websoft9.com
user_pwd = RilXTqVRvEvU
#The config for portainer
[portainer]
base_url = http://websoft9-deployment:9000/api
user_name = admin
user_pwd = k0(t9g:Vnbs)<!ux
user_pwd = u,l8<1*7ZL]$hCAt
#The path of docker library
[docker_library]
path = /websoft9/library/apps
#The path of app media
[app_media]
path = /websoft9/media/json/
#The value of api_key
[api_key]
key = ee30700022f9d1b99e1112a28e6b008be2c2817ec505306120d8a7ea45fb6d5f
key = f1bfb015275683f9fd180a3c9d72421029635fc2f3d5b76a32134f2264cf26ae
#The config for cockpit
[cockpit]
port = 9090
port = 9000

View file

@ -65,7 +65,12 @@ class GiteaManager:
response = self.gitea.create_repo(repo_name)
if response.status_code == 201:
repo_json = response.json()
return repo_json["clone_url"]
# 将repo_json字符串中:localhost/w9git 替换为:websoft9-git:3000
url = repo_json["clone_url"].replace("localhost/w9git","websoft9-git:3000")
# http://localhost/w9git/websoft9/test.git
# http://websoft9-git:3000/websoft9/wp.git
return url
else:
logger.error(f"Create repo:{repo_name} error:{response.status_code}:{response.text}")
raise CustomException()

0
apphub/swagger-ui/favicon-16x16.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 665 B

After

Width:  |  Height:  |  Size: 665 B

0
apphub/swagger-ui/favicon-32x32.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 628 B

After

Width:  |  Height:  |  Size: 628 B

0
apphub/swagger-ui/index.css Normal file → Executable file
View file

0
apphub/swagger-ui/index.html Normal file → Executable file
View file

0
apphub/swagger-ui/oauth2-redirect.html Normal file → Executable file
View file

0
apphub/swagger-ui/redoc.standalone.js Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-initializer.js Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui-bundle.js Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui-bundle.js.map Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui-es-bundle-core.js Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui-es-bundle-core.js.map Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui-es-bundle.js Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui-es-bundle.js.map Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui-standalone-preset.js Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui-standalone-preset.js.map Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui.css Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui.css.map Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui.js Normal file → Executable file
View file

0
apphub/swagger-ui/swagger-ui.js.map Normal file → Executable file
View file

View file

@ -41,11 +41,11 @@ You should have root privileges user to install or upgrade or uninstall Websoft9
```
# Install by default
curl https://websoft9.github.io/websoft9/install/install.sh | bash
wget -O install.sh https://websoft9.github.io/websoft9/install/install.sh && bash install.sh
# Install Websoft9 special version by development artifact and install path at /data/websoft9/source ...
wget -O - https://websoft9.github.io/websoft9/install/install.sh | bash /dev/stdin --port 9000 --channel dev --path "/data/websoft9/source" --version "0.8.25"
# Install Websoft9 with parameters
wget -O install.sh https://websoft9.github.io/websoft9/install/install.sh && bash install.sh --port 9000 --channel release --path "/data/websoft9/source" --version "latest"
```
After installation, access it by: **http://Internet IP:9000** and using **Linux user** for login

View file

@ -1,4 +1,4 @@
APPHUB_VERSION=0.0.5
APPHUB_VERSION=0.0.6
DEPLOYMENT_VERSION=2.19.0
GIT_VERSION=1.20.4
PROXY_VERSION=2.10.4

View file

@ -1,6 +1,8 @@
# modify time: 202310181824, you can modify here to trigger Docker Build action
FROM python:3.10-bullseye AS buildstage
LABEL maintainer="Websoft9<help@websoft9.com>"
LABEL version="0.0.5"
LABEL version="0.0.6"
ENV LIBRARY_VERSION=v0.5.8
@ -39,6 +41,7 @@ RUN chmod +r /etc/supervisor/conf.d/supervisord.conf
COPY config/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
VOLUME /websoft9/apphub/logs
VOLUME /websoft9/apphub/src/config
VOLUME /websoft9/media

View file

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

View file

@ -7,4 +7,5 @@
- use virtualenv for pip install requirements.txt
- create volumes at dockerfile
- EXPOSE port
- process logs should output to docker logs by supervisord
- process logs should output to docker logs by supervisord
- [uvicorn](https://www.uvicorn.org/) load Fastapi

View file

@ -0,0 +1,16 @@
#!/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
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

@ -1,33 +1,43 @@
#!/bin/bash
# check credentials exists
check_file_exists() {
file_path=$1
max_attempts=$2
for ((i=1; i<=max_attempts; i++))
do
if [ -f "$file_path" ]; then
echo "$file_path exists"
return 0
else
echo "$file_path is not exists, wait a moment.."
fi
sleep 1
if ((i==max_attempts)); then
echo "$file_path is not exists, app may be work normally."
return 1
fi
done
}
set +e
check_file_exists "/websoft9/credentials/credential_proxy" 1
check_file_exists "/websoft9/credentials/credential_deployment" 1
check_file_exists "/websoft9/credentials/credential_git" 1
set -e
try_times=3
# start by supervisord
/usr/bin/supervisord
# debug
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)
email=$(apphub getconfig --section gitea --key email)
set -e
if [ -n "$username" ] && [ -n "$email" ]; then
break
fi
echo "Command failed, retrying..."
sleep 3
done
echo $username
echo $email
if [[ -n "$username" ]]; then
git config --global user.name "$username"
else
echo "username is null"
exit 1
fi
regex="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
if [[ $email =~ $regex ]]; then
git config --global user.email "$email"
else
echo "Not have correct email"
exit 1
fi
tail -f /dev/null

View file

@ -3,10 +3,12 @@ nodaemon=false
[program:apphub]
command=uvicorn src.main:app --host 0.0.0.0 --port 8080 --log-level error
autostart=true
autostart=false
directory=/websoft9/apphub
[program:apphubdev]
command=/bin/bash -c '[ -z "$(ls -A /websoft9/apphub-dev)" ] && cp -r /websoft9/apphub/* /websoft9/apphub-dev && uvicorn src.main:app --reload --host 0.0.0.0 --port 8080 --log-level error'
autostart=true
directory=/websoft9/apphub-dev
command=/developer.sh
autostart=false
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

View file

@ -1,14 +1,22 @@
# step1: build entrypoint execute program init_portainer by golang
# modify time: 202310182230, you can modify here to trigger Docker Build action
# step1: Build entrypoint execute program init_portainer by golang
FROM golang:latest AS builder
WORKDIR /
COPY init_portainer.go /
RUN go build -o init_portainer /init_portainer.go
RUN chmod +x /init_portainer
# step2: copy build go program to portainer
COPY environment.go /
RUN go build -o environment /environment.go
RUN chmod +x /environment
# step2: Copy build go program to portainer
# Dockerfile refer to: https://github.com/portainer/portainer/blob/develop/build/linux/Dockerfile
FROM portainer/portainer-ce:2.19.0
LABEL maintainer="websoft9<help@websoft9.com>"
LABEL version="2.19.0"
COPY --from=builder /init_portainer /
COPY --from=builder /environment /
ENTRYPOINT ["/init_portainer"]
ENTRYPOINT ["/init_portainer"]

View file

@ -0,0 +1,140 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
)
const (
AdminUser = "admin"
EndpointURL = "http://localhost:9000/api/endpoints"
AuthURL = "http://localhost:9000/api/auth"
CredentialLoc = "/data/credential"
)
type Endpoint struct {
Name string `json:"Name"`
URL string `json:"URL"`
}
type AuthResponse struct {
Jwt string `json:"jwt"`
}
type Credentials struct {
Username string `json:"Username"`
Password string `json:"Password"`
}
func main() {
var password string
for {
if _, err := os.Stat(CredentialLoc); os.IsNotExist(err) {
fmt.Printf("%s does not exist, waiting for 3 seconds...\n", CredentialLoc)
time.Sleep(3 * time.Second)
} else {
fmt.Printf("%s exists, proceeding...\n", CredentialLoc)
data, err := ioutil.ReadFile(CredentialLoc)
if err != nil {
fmt.Println("Failed to read file:", err)
return
}
password = string(data)
break
}
}
client := &http.Client{}
credentials := Credentials{Username: AdminUser, Password: password}
credentialsJson, err := json.Marshal(credentials)
if err != nil {
fmt.Println("Failed to encode JSON:", err)
return
}
req, err := http.NewRequest("POST", AuthURL, bytes.NewBuffer(credentialsJson))
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Failed to make request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Failed to read response:", err)
return
}
fmt.Printf("Received body: %s\n", string(body))
var authResponse AuthResponse
err = json.Unmarshal(body, &authResponse)
if err != nil {
fmt.Println("Failed to parse JSON:", err)
return
}
fmt.Printf("Received JWT: %s\n", authResponse.Jwt)
req, err = http.NewRequest("GET", EndpointURL, nil)
req.Header.Set("Authorization", "Bearer "+authResponse.Jwt)
resp, err = client.Do(req)
if err != nil {
fmt.Println("Failed to make request:", err)
return
}
defer resp.Body.Close()
body, err = ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Failed to read response:", err)
return
}
var endpoints []Endpoint
err = json.Unmarshal(body, &endpoints)
if err != nil {
fmt.Println("Failed to parse JSON:", err)
return
}
for _, endpoint := range endpoints {
if endpoint.Name == "local" {
fmt.Println("Endpoint exists, exiting...")
return
}
}
fmt.Println("Endpoint does not exist, creating...")
endpoint := Endpoint{
Name: "local",
URL: "/var/run/docker.sock",
}
data, err := json.Marshal(endpoint)
if err != nil {
fmt.Println("Failed to encode JSON:", err)
return
}
req, err = http.NewRequest("POST", EndpointURL, bytes.NewBuffer(data))
req.Header.Set("Authorization", "Bearer "+authResponse.Jwt)
resp, err = client.Do(req)
if err != nil {
fmt.Println("Failed to make request:", err)
return
}
if resp.StatusCode != http.StatusCreated {
fmt.Println("Failed to create endpoint:", resp.Status)
} else {
fmt.Println("Endpoint created successfully")
}
}

View file

@ -11,24 +11,7 @@ import (
func main() {
dirPath := "/var/websoft9"
if _, err := os.Stat("/var"); os.IsNotExist(err) {
err = os.Mkdir("/var", 0755)
if err != nil {
fmt.Println(err)
return
}
}
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
err = os.Mkdir(dirPath, 0755)
if err != nil {
fmt.Println(err)
return
}
}
filePath := "/var/websoft9/credential"
filePath := "/data/credential"
_, err := os.Stat(filePath)
if os.IsNotExist(err) {
@ -40,36 +23,28 @@ func main() {
fmt.Println("write file error:", err)
return
}
// call portainer
cmd := exec.Command("./portainer", "--admin-password-file", filePath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
fmt.Println("error running compiled_program:", err)
return
}
}else{
fmt.Println("credential is exist, skip it.")
fmt.Println("credential is exist, skip it.")
cmd := exec.Command("./portainer")
cmd.Run()
}
content, err := ioutil.ReadFile(filePath)
if err != nil {
fmt.Println("read file error:", err)
return
}
fmt.Println("-----portainer_admin_user: admin, portainer_admin_password: " + string(content) + " ------")
// call portainer
cmd := exec.Command("./portainer", "--admin-password-file", filePath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
fmt.Println("error running compiled_program:", err)
return
}
}
func generatePassword(length int) string {
rand.Seed(time.Now().UnixNano())
charset := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+{}[]:;?.,<>"
charset := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@$()_"
password := make([]byte, length)
for i := range password {

View file

@ -16,7 +16,7 @@ services:
- 9001-9999:8080
restart: always
volumes:
- /data/mysource:/websoft9/apphub-dev
- /data/websoft9/apphub:/websoft9/apphub-dev
- apphub_media:/websoft9/media
depends_on:
- deployment
@ -34,6 +34,11 @@ services:
- /data/compose:/data/compose
- /var/run/docker.sock:/var/run/docker.sock
#- /run/podman/podman.sock:/var/run/docker.sock
healthcheck:
test: ["CMD", "/environment"]
interval: 30s
timeout: 10s
retries: 3
labels:
com.docker.compose.w9_http.port: 9000

View file

@ -25,6 +25,11 @@ services:
- /data/compose:/data/compose
- /var/run/docker.sock:/var/run/docker.sock
#- /run/podman/podman.sock:/var/run/docker.sock
healthcheck:
test: ["CMD", "/environment"]
interval: 30s
timeout: 10s
retries: 3
labels:
com.docker.compose.w9_http.port: 9000

View file

@ -1,3 +1,5 @@
# modify time: 202310181524, 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
LABEL maintainer="Websoft9<help@websoft9.com>"

View file

@ -1,11 +1,14 @@
#!/bin/bash
set -e
echo "start create user shell" >> /tmp/user
set -e
# Confirm gitea is running
count=1
response=""
cred_path="/data/gitea/credential"
admin_username="websoft9"
admin_email="help@websoft9.com"
while [ "$response" != "200" ]; do
response=$(curl -s -o /dev/null -w "%{http_code}" localhost:3000)
if [ "$response" = "200" ]; then
@ -19,29 +22,28 @@ while [ "$response" != "200" ]; do
fi
done
cred_path="/var/websoft9/credential"
admin_username="websoft9"
admin_email="help@websoft9.com"
if [ -e "$cred_path" ]; then
echo "File $cred_path exists. Exiting script."
exit 0
fi
echo "create diretory"
mkdir -p "$(dirname "$cred_path")"
echo "Create admin credential by admin cli"
su -c "
gitea admin user create --admin --username '$admin_username' --random-password --email '$admin_email' > /tmp/credential
if gitea admin user list | grep -q '$admin_username'; then
echo 'User already exists.'
exit 0
else
gitea admin user create --admin --username '$admin_username' --random-password --email '$admin_email' > /tmp/credential
fi
" git
echo "Read credential from tmp"
username=$(grep -o "New user '[^']*" /tmp/credential | sed "s/New user '//")
if [ -z "$username" ]; then
username="websoft9"
if [ -z "$username" ] || [ "$username" != "websoft9" ]; then
echo "username is not websoft9, exit"
fi
password=$(grep -o "generated random password is '[^']*" /tmp/credential | sed "s/generated random password is '//")
rm -rf /tmp/credential
echo "Save to credential"
json="{\"username\":\"$admin_username\",\"password\":\"$password\",\"email\":\"$admin_email\"}"

View file

@ -1,3 +1,5 @@
# 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
FROM jc21/nginx-proxy-manager:2.10.4
LABEL maintainer="Websoft9<help@websoft9.com>"

View file

@ -1,13 +1,12 @@
#!/bin/bash
echo "Start to change nginxproxymanage users" >> /tmp/userlog
set +e
username="help@websoft9.com"
password=$(openssl rand -base64 16 | tr -d '/+' | cut -c1-16)
token=""
cred_path="/var/websoft9/credential"
cred_path="/data/credential"
echo "Start to change nginxproxymanage users"
if [ -e "$cred_path" ]; then
echo "File $cred_path exists. Exiting script."
exit 0
@ -16,32 +15,33 @@ 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)" >> /tmp/userlog
echo "Change username(email)"
while true; 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 "HTTP call successful"
break
else
echo "HTTP call Change username failed, retrying..." >> /tmp/userlog
echo "HTTP call Change username failed, retrying..."
sleep 5
fi
done
echo "Update password" >> /tmp/userlog
echo "Update password"
while true; 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 "HTTP call successful"
break
else
echo "HTTP call Update password failed, retrying..." >> /tmp/userlog
echo "HTTP call Update password failed, retrying..."
sleep 5
fi
done
@ -49,5 +49,4 @@ done
echo "Save to credential"
json="{\"username\":\"$username\",\"password\":\"$password\"}"
echo "$json" > "$cred_path"
set -e

View file

@ -9,10 +9,10 @@
```
# install or upgrade Websoft9
wget -O - https://websoft9.github.io/websoft9/install/install.sh | bash
wget -O install.sh https://websoft9.github.io/websoft9/install/install.sh && bash install.sh
# install or upgrade Websoft9 with parameters
wget -O - https://websoft9.github.io/websoft9/install/install.sh | bash /dev/stdin --port 9000 --channel release --path "/data/websoft9/source" --version "latest"
wget -O install.sh https://websoft9.github.io/websoft9/install/install.sh && bash install.sh --port 9000 --channel release --path "/data/websoft9/source" --version "latest"
# install or upgrade Cockpit with parameters
wget -O - https://websoft9.github.io/websoft9/install/install_cockpit.sh | bash --port 9000

View file

@ -73,10 +73,12 @@ done
if [ -n "$port" ]; then
export port
else
port=9000
export port=9000
fi
starttime=$(date +%s)
# 输出参数值
echo -e "\n------ Welcome to install Websoft9, it will take 3-5 minutes ------"
echo -e "\nYour installation parameters are as follows: "
@ -101,7 +103,8 @@ export systemd_path="/opt/websoft9/systemd"
export source_zip="websoft9-$version.zip"
export source_unzip="websoft9"
export source_github_pages="https://websoft9.github.io/websoft9"
export tools_yum="git curl wget yum-utils jq bc unzip inotify-tools"
# inotify-tools is at epel-release
export tools_yum="git curl wget epel-release yum-utils jq bc unzip inotify-tools"
export tools_apt="git curl wget jq bc unzip inotify-tools"
export docker_network="websoft9"
export artifact_url="https://w9artifact.blob.core.windows.net/$channel/websoft9"
@ -138,9 +141,9 @@ install_tools(){
apt_status=$?
if [ $dnf_status -eq 0 ]; then
dnf install $tools_yum -y
for package in $tools_yum; do sudo dnf install -y $package > /dev/null; done
elif [ $yum_status -eq 0 ]; then
yum install $tools_yum -y
for package in $tools_yum; do sudo yum install -y $package > /dev/null; done
elif [ $apt_status -eq 0 ]; then
while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do
echo "Waiting for other software managers to finish..."
@ -200,20 +203,16 @@ check_ports() {
for port in "${ports[@]}"; do
if netstat -tuln | grep ":$port " >/dev/null; then
if ss -tuln | grep ":$port " >/dev/null; then
echo "Port $port is in use, install failed"
exit
fi
done
echo "All ports are available"
}
source_github_pages="https://websoft9.github.io/websoft9"
install_path="/data/websoft9/source"
merge_json_files() {
local target_path="/etc/docker/daemon.json"
@ -277,6 +276,8 @@ set_docker(){
sudo firewall-cmd --permanent --zone=docker --add-interface=docker0 2> /dev/null
sudo firewall-cmd --permanent --zone=docker --set-target=ACCEPT
sudo firewall-cmd --reload
sudo systemctl stop firewalld
sudo systemctl disable firewalld
fi
sudo systemctl restart docker
}
@ -379,6 +380,8 @@ if [ $? -ne 0 ]; then
exit 1
fi
install_backends
bash $install_path/install/install_cockpit.sh
if [ $? -ne 0 ]; then
echo "install_cockpit failed with error $?. Exiting."
@ -391,8 +394,14 @@ if [ $? -ne 0 ]; then
exit 1
fi
install_backends
echo "Restart Docker for Firewalld..."
sudo systemctl restart docker
install_systemd
endtime=$(date +%s)
runtime=$((endtime-starttime))
echo "Script execution time: $runtime seconds"
echo -e "\n-- Install success! ------"
echo "Access Websoft9 console by: http://Internet IP:$(grep ListenStream /lib/systemd/system/cockpit.socket | cut -d= -f2) and using Linux user for login"

View file

@ -4,7 +4,6 @@ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
# Export PATH
export PATH
## This script is used for install or upgrade Cockpit on Linux
## Cockpit build at redhat family: https://copr.fedorainfracloud.org/coprs/g/cockpit/cockpit-preview/monitor/
## Cockpit reposoitory list: https://pkgs.org/download/cockpit
@ -80,7 +79,7 @@ echo -e "\nYour installation parameters are as follows: "
echo "cockpit_port:$cockpit_port"
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"
@ -162,7 +161,7 @@ Restart_Cockpit(){
echo "$echo_prefix_cockpit Restart Cockpit"
sudo systemctl daemon-reload
sudo systemctl restart cockpit.socket 2> /dev/null
sudo systemctl restart cockpit
sudo systemctl restart cockpit || exit 1
}
Add_Firewalld(){
@ -216,9 +215,19 @@ Set_Cockpit(){
curl -sSL $cockpit_config_github_page_url | sudo tee /etc/cockpit/cockpit.conf > /dev/null
fi
echo "Change cockpit default port to $cockpit_port ..."
sudo sed -i "s/ListenStream=[0-9]*/ListenStream=${cockpit_port}/" /lib/systemd/system/cockpit.socket
if docker ps --format '{{.Names}}' | grep -wq "${related_containers[0]}"; then
echo "Try to change cockpit port at ${related_containers[0]} container..."
sudo docker exec -i ${related_containers[0]} apphub setconfig --section cockpit --key port --value $cockpit_port || true
else
echo "Not found ${related_containers[0]} container"
fi
# fwupd-refresh.service may push error for Cockpit menu, so disable it
if sudo systemctl is-active --quiet fwupd-refresh.service; then
echo "fwupd-refresh.service is already running. Stopping and disabling it..."
@ -342,7 +351,6 @@ Install_Cockpit(){
Test_Cockpit(){
echo "$echo_prefix_cockpit Test Cockpit console accessibility"
test_cmd="curl localhost:$cockpit_port"
echo test_cmd
start_time=$(date +%s)
timeout=30
while true; do
@ -372,4 +380,8 @@ Install_Cockpit
Test_Cockpit
# release package memory
sudo systemctl restart packagekit.service
if systemctl cat packagekit > /dev/null 2>&1; then
sudo systemctl restart packagekit
else
echo "no packagekit"
fi

View file

@ -24,7 +24,9 @@ export PATH
#
# $ sudo sh install_docker.sh
docker_packages="docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin"
# it must export, otherwise Rocky Linux cannot used at yum command
export docker_packages="docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin"
echo_prefix_docker=$'\n[Docker] - '
docker_exist() {

View file

@ -13,4 +13,10 @@ sudo cp -f "$install_path/systemd/websoft9.service" /lib/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable websoft9.service
sudo systemctl start websoft9
```
```
## Develop it
* [systemd.exec — Execution environment configuration](https://www.freedesktop.org/software/systemd/man/systemd.exec.html)
* [systemd.unit — Unit configuration](https://www.freedesktop.org/software/systemd/man/systemd.unit.html)
* [systemd.service — Service unit configuration](https://www.freedesktop.org/software/systemd/man/systemd.service.html)

View file

@ -9,26 +9,26 @@ cockpit_port="9000"
on_change() {
set +e
# 从配置文件中获取端口号
cockpit_port=$(sudo docker exec -i websoft9-apphub apphub getconfig --section cockpit --key port)
sudo sed -i "s/ListenStream=[0-9]*/ListenStream=${cockpit_port}/" /lib/systemd/system/cockpit.socket
sudo systemctl daemon-reload
sudo systemctl restart cockpit
cockpit_port=$(docker exec -i websoft9-apphub apphub getconfig --section cockpit --key port)
sed -i "s/ListenStream=[0-9]*/ListenStream=${cockpit_port}/" /lib/systemd/system/cockpit.socket
systemctl daemon-reload
systemctl restart cockpit.socket 2> /dev/null
systemctl restart cockpit || exit 1
set_Firewalld
set -e
}
set_Firewalld(){
echo "Set cockpit service to Firewalld..."
sudo sed -i "s/port=\"[0-9]*\"/port=\"$cockpit_port\"/g" /etc/firewalld/services/cockpit.xml
sudo sed -i "s/port=\"[0-9]*\"/port=\"$cockpit_port\"/g" /usr/lib/firewalld/services/cockpit.xml
sudo firewall-cmd --reload
sed -i "s/port=\"[0-9]*\"/port=\"$cockpit_port\"/g" /etc/firewalld/services/cockpit.xml 2>/dev/nul
sed -i "s/port=\"[0-9]*\"/port=\"$cockpit_port\"/g" /usr/lib/firewalld/services/cockpit.xml 2>/dev/nul
firewall-cmd --reload 2>/dev/nul
}
# 循环,持续监控
while true; do
# monitor /lib/systemd/system/cockpit.socket and config.ini, make sure config.ini port is the same with cockpit.socket
inotifywait -e modify -m $FILES | while read PATH EVENT FILE; do
echo "Set cockpit port by config.ini..."
on_change
done
# monitor /lib/systemd/system/cockpit.socket and config.ini, make sure config.ini port is the same with cockpit.socket
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

View file

@ -2,7 +2,7 @@
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
deployment_username="admin"
credential_path="/var/websoft9/credential"
credentials=("/data/gitea/credential" "/data/credential" "/data/credential")
containers=("websoft9-git" "websoft9-deployment" "websoft9-proxy")
sections=("gitea" "portainer" "nginx_proxy_manager")
max_retries=20
@ -11,13 +11,14 @@ declare -A usernames passwords
set +e # Ignore errors
for container in ${containers[@]}; do
for i in ${!containers[@]}; do
container=${containers[$i]}
credential_path=${credentials[$i]}
echo "Processing $container"
success=false
counter=0
while [[ $success == false && $counter -lt $max_retries ]]; do
temp_file=$(mktemp)
echo "Attempt $((counter+1)) to copy $credential_path from $container to $temp_file"
if docker cp $container:$credential_path $temp_file; then
# Check if temp_file is JSON format
if jq -e . >/dev/null 2>&1 <<< "$(cat "$temp_file")"; then
@ -62,7 +63,5 @@ for ((i=0; i<$length; i++)); do
container=${containers[$i]}
section=${sections[$i]}
echo "$container:"
echo "Username: ${usernames[$container]}"
echo "Password: ${passwords[$container]}"
sudo docker exec -i websoft9-apphub apphub setconfig --section $section --key user_pwd --value ${passwords[$container]}
docker exec -i websoft9-apphub apphub setconfig --section $section --key user_pwd --value ${passwords[$container]}
done

View file

@ -33,11 +33,11 @@ fi
# 检查 /etc/hosts 文件中是否已经存在一个条目与容器名称相同
if grep -q $container_name /etc/hosts; then
# 如果存在,使用 sed 命令更新这个条目
sudo sed -i "/$container_name/d" /etc/hosts
echo "$container_ip $container_name" | sudo tee -a /etc/hosts > /dev/null
sed -i "/$container_name/d" /etc/hosts
echo "$container_ip $container_name" | tee -a /etc/hosts > /dev/null
echo "Container $container_name IP updated to $container_ip in /etc/hosts"
else
# 如果不存在,添加一个新的条目
echo "$container_ip $container_name" | sudo tee -a /etc/hosts > /dev/null
echo "$container_ip $container_name" | tee -a /etc/hosts > /dev/null
echo "Container $container_name IP $container_ip added to /etc/hosts"
fi

View file

@ -1,7 +1,7 @@
[Unit]
Description=Websoft9 Linux AppStore
Requires=network.target docker
After=network.target docker
Requires=network.target docker.service
After=network.target docker.service
[Service]
WorkingDirectory=/opt/websoft9/systemd
@ -9,7 +9,8 @@ ExecStart=/bin/bash /opt/websoft9/systemd/start_up.sh
Restart=on-failure
Type=simple
NotifyAccess=all
StandardError=syslog
StandardOutput=journal
StandardError=journal
User=root
Group=root

View file

@ -1,7 +1,7 @@
{
"version": "0.8.26-rc33",
"version": "0.8.26-rc68",
"plugins": {
"portainer": "0.0.6",
"portainer": "0.0.7",
"nginx": "0.0.5",
"myapps": "0.0.8",
"appstore": "0.0.7",
@ -44,8 +44,7 @@
"Ubuntu": [
"23.04",
"22.04",
"20.04",
"18.04"
"20.04"
]
}
}
}