Skip to content

Commit

Permalink
Version:0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
cmq2080 committed Jun 20, 2022
2 parents 9aeff4c + cd40e42 commit 993e414
Show file tree
Hide file tree
Showing 13 changed files with 1,319 additions and 2 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# 除php-cgi-spawner之外的应用程序
*.exe
!php-cgi-spawner.exe

# 配置文件
*.json
*.conf

# 中间文件
rsrc.syso
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,40 @@
# liansu-server
适用于Windows上的PHP运行环境管理工具
# 连速Server

连速Server(liansu-server)是一个PHP集成环境管理工具。现仅有Windows版本,可通过GUI管理。

## 起源&历程

我在开发连速PHP框架时曾思考过:

> 要不要顺便也把底层的运行环境管理工具也开发出来一个?
>
> W/LMP的运管工具有很多的,像Linux的LNMP、宝塔,Windows的phpStudy、WampServer,所以也没太大的需求。
>
> 但是,真的是这样吗?
>
> 我是LNMP的老用户,每次给新服务器装系统的时候都很痛苦,因为编译的过程很长
>
> 宝塔倒是挺好,周围朋友也有用的,然而功能太多了,我就要起个Nginx+PHP的环境而已,别的什么的我都可以自己配,而且,宝塔本身耗多少系统资源呢?
>
> ……
>
> 就这么决定了,要做一个功能简单、体积小、系统损耗小、主要通过命令行交互的运管工具
于是,就有了XServer计划。这一天是2022年2月23日。

2022年3月4日,正式确定产品名称为连速Server。

2022年3月7日,原型版本正式投入试用,基本功能使用正常。

2022年6月20日,正式发布0.0.1版本。

## 用法(Windows版本)

* --gui: 启动图形界面窗口
* start: 启动环境(包括启动Nginx和php-cgi)
* stop: 终止环境(包括终止Nginx和php-cgi的运行)
* restart: 重启环境
* save: 保存当前配置
* export: 导出当前Nginx应用配置,重新生成Nginx扩展配置文件(先保存再导出)
* status: 查看当前环境运行状态
* -h/--help: 获取帮助信息
6 changes: 6 additions & 0 deletions build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@echo off
del liansu-server.exe
%GOPATH%/bin/rsrc.exe -manifest main.manifest -o rsrc.syso
rem go build -o liansu-server.exe -ldflags="-H windowsgui"
%GOROOT%/bin/go.exe build -o liansu-server.exe
@echo on
4 changes: 4 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
rm -rf liansu-server.exe
$GOPATH/bin/rsrc.exe -manifest main.manifest -o rsrc.syso
# go build -o liansu-server.exe -ldflags="-H windowsgui"
go build -o liansu-server.exe
93 changes: 93 additions & 0 deletions cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package main

import (
"fmt"

"github.com/spf13/cobra"
)

var (
gui bool
)

func getRootCmd() *cobra.Command {
rootCmd := &cobra.Command{
Use: "",
Run: func(cmd *cobra.Command, args []string) {
reloadCfg()
runApp()
},
}
rootCmd.Flags().BoolVarP(&gui, "gui", "g", false, "is gui?")
rootCmd.Flags().StringVarP(&cfgFilepath, "config", "c", "", "custom config file")

startCmd := &cobra.Command{
Use: "start",
Short: "start PHP Running Environment",
Run: func(cmd *cobra.Command, args []string) {
reloadCfg()
fmt.Println("启动环境...")
startEnv()
},
}
startCmd.Flags().StringVarP(&cfgFilepath, "config", "c", "", "custom config file")
rootCmd.AddCommand(startCmd)

var stopCmd = &cobra.Command{
Use: "stop",
Short: "Stop PHP Running Environment",
Run: func(cmd *cobra.Command, args []string) {
// 进程直接杀死就好,不需要用到配置的
fmt.Println("终止环境...")
stopEnv()
},
}
rootCmd.AddCommand(stopCmd)

var restartCmd = &cobra.Command{
Use: "restart",
Short: "restart PHP Running Environment",
Run: func(cmd *cobra.Command, args []string) {
reloadCfg()
fmt.Println("重启环境...")
stopEnv()
},
}
restartCmd.Flags().StringVarP(&cfgFilepath, "config", "c", "", "custom config file")
rootCmd.AddCommand(restartCmd)

var saveCmd = &cobra.Command{
Use: "save",
Short: "Save Current Config",
Run: func(cmd *cobra.Command, args []string) {
reloadCfg()
saveConfig()
},
}
saveCmd.Flags().StringVarP(&cfgFilepath, "config", "c", "", "custom config file")
rootCmd.AddCommand(saveCmd)

var exportCmd = &cobra.Command{
Use: "export",
Short: "Export Current Config",
Run: func(cmd *cobra.Command, args []string) {
reloadCfg()
exportNginx()
},
}
exportCmd.Flags().StringVarP(&cfgFilepath, "config", "c", "", "custom config file")
rootCmd.AddCommand(exportCmd)

var statusCmd = &cobra.Command{
Use: "status",
Short: "Check the status of NGINX and PHP",
Run: func(cmd *cobra.Command, args []string) {
// 进程直接查看就好,不需要调用配置信息的
nginxStatus, phpStatus := checkStatus()
showStatus(nginxStatus, phpStatus)
},
}
rootCmd.AddCommand(statusCmd)

return rootCmd
}
124 changes: 124 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"encoding/json"
"os"
"runtime"
"strings"
)

type Config struct {
Server ServerConfig `json:"server"`
Nginx NginxConfig `json:"nginx"`
Php PHPConfig `json:"php"`
Apps []AppConfig `json:"apps"`
}

type ServerConfig struct {
Ip string `json:"ip"`
Port string `json:"port"`
Wwwroot string `json:"wwwroot"`
}

type NginxConfig struct {
Dir string `json:"dir"`
Conf string `json:"conf"`
Logs_dir string `json:"logs_dir"`
}

type PHPConfig struct {
Dir string `json:"dir"`
Ini string `json:"ini"`
Port string `json:"port"`
}

type AppConfig struct {
Name string `json:"name"`
Root string `json:"root"`
Server_name string `json:"server_name"`
Listen string `json:"listen"`
Logs_dir string `json:"logs_dir"`
}

func (cfg *Config) Init(filepath string) {
buf, _ := os.ReadFile(filepath)
var res map[string]interface{}

json.Unmarshal(buf, &res)

serverRes := res["server"].(map[string]interface{})
serverCfg := ServerConfig{
Ip: serverRes["ip"].(string),
Port: serverRes["port"].(string),
Wwwroot: getRealDir(serverRes["wwwroot"].(string)),
}
cfg.Server = serverCfg

nginxRes := res["nginx"].(map[string]interface{})
nginxCfg := NginxConfig{
Dir: getRealDir(nginxRes["dir"].(string)),
Conf: getRealDir(nginxRes["conf"].(string)),
Logs_dir: getRealDir(nginxRes["logs_dir"].(string)),
}
if nginxCfg.Conf == "" {
nginxCfg.Conf = nginxCfg.Dir + "/conf/nginx.conf"
}
if nginxCfg.Logs_dir == "" {
nginxCfg.Logs_dir = nginxCfg.Dir + "/logs"
}
cfg.Nginx = nginxCfg

phpRes := res["php"].(map[string]interface{})
phpCfg := PHPConfig{
Dir: getRealDir(phpRes["dir"].(string)),
Ini: getRealDir(phpRes["ini"].(string)),
Port: phpRes["port"].(string),
}
if phpCfg.Ini == "" {
phpCfg.Ini = phpCfg.Dir + "/php.ini"
}
if phpCfg.Port == "" {
phpCfg.Port = "9000"
}
cfg.Php = phpCfg

appRes := res["apps"].([]interface{})
appCfgs := []AppConfig{}
for i := 0; i < len(appRes); i++ {
appRes2 := appRes[i].(map[string]interface{})
appCfg := AppConfig{
Name: appRes2["name"].(string),
Root: getRealDir(appRes2["root"].(string)),
Server_name: appRes2["server_name"].(string),
Listen: appRes2["listen"].(string),
Logs_dir: getRealDir(appRes2["logs_dir"].(string)),
}
if !isAbsoluteDir(appCfg.Root) { // 不是绝对路径?那前面得加wwwroot
appCfg.Root = serverCfg.Wwwroot + "/" + appCfg.Root
}
if appCfg.Listen == "" && appCfg.Server_name != "" {
appCfg.Listen = serverCfg.Port
}
if appCfg.Logs_dir == "" && appCfg.Server_name != "" {
appCfg.Logs_dir = nginxCfg.Logs_dir
}

appCfgs = append(appCfgs, appCfg)
}
cfg.Apps = appCfgs
}

func getRealDir(dir string) string {
dir = strings.Replace(dir, "\\", "/", -1)
dir = strings.TrimRight(dir, "/")

return dir
}

func isAbsoluteDir(dir string) bool {
if runtime.GOOS == "windows" {
return strings.Contains(dir, ":")
} else {
return dir[0:1] == "/"
}
}
33 changes: 33 additions & 0 deletions config.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"server": {
"ip": "127.0.0.1",
"port": "80",
"wwwroot": "D:/wwwroot"
},
"nginx": {
"dir": "D:\\Environment\\PHP\\nginx-1.20.2",
"conf": "",
"logs_dir": ""
},
"php": {
"dir": "D:\\Environment\\PHP\\php-7.4.27-nts-Win32-vc15-x64",
"ini": "",
"port": ""
},
"apps": [
{
"name": "dev",
"root": "_dev",
"server_name": "",
"listen": "",
"logs_dir": ""
},
{
"name": "wenshilian",
"root": "D:\\wwwroot\\wenshilian\\public",
"server_name": "wenshilian.loc",
"listen": "80",
"logs_dir": ""
}
]
}
1 change: 1 addition & 0 deletions expert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package main

0 comments on commit 993e414

Please sign in to comment.