Работа над конфигом repko, работа над интеграцией в deb пакет repko
This commit is contained in:
parent
58b258be29
commit
d3fd4f5858
7 changed files with 101 additions and 11 deletions
|
|
@ -10,12 +10,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ConfDir = "./confs/"
|
|
||||||
|
|
||||||
func LoadApplications() []types.PackageApplication {
|
func LoadApplications() []types.PackageApplication {
|
||||||
var apps []types.PackageApplication
|
var apps []types.PackageApplication
|
||||||
|
|
||||||
err := filepath.WalkDir(ConfDir, func(path string, d fs.DirEntry, err error) error {
|
err := filepath.WalkDir(types.ConfsDir, func(path string, d fs.DirEntry, err error) error {
|
||||||
if err != nil || d == nil || d.IsDir() {
|
if err != nil || d == nil || d.IsDir() {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package bootstrap
|
package bootstrap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bubble/types"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"gopkg.in/natefinch/lumberjack.v2"
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -14,7 +15,7 @@ func Logs() {
|
||||||
PadLevelText: true,
|
PadLevelText: true,
|
||||||
}
|
}
|
||||||
logWriter := &lumberjack.Logger{
|
logWriter := &lumberjack.Logger{
|
||||||
Filename: "log.txt",
|
Filename: types.LogFile,
|
||||||
Compress: true,
|
Compress: true,
|
||||||
MaxSize: 50,
|
MaxSize: 50,
|
||||||
LocalTime: true,
|
LocalTime: true,
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,15 @@ variables:
|
||||||
- name: "gpg_mail"
|
- name: "gpg_mail"
|
||||||
type: "string"
|
type: "string"
|
||||||
default: "admin@repko.com"
|
default: "admin@repko.com"
|
||||||
|
- name: "gpg_key_id"
|
||||||
|
type: "string"
|
||||||
|
default: "123ABCD"
|
||||||
|
- name: "repko_login"
|
||||||
|
type: "string"
|
||||||
|
default: "admin_repko"
|
||||||
|
- name: "repko_pass"
|
||||||
|
type: "string"
|
||||||
|
default: "admin_repko"
|
||||||
- name: "debian_root"
|
- name: "debian_root"
|
||||||
type: "string"
|
type: "string"
|
||||||
default: "/var/www/repko/debian"
|
default: "/var/www/repko/debian"
|
||||||
|
|
@ -181,7 +190,7 @@ sections:
|
||||||
- name: "Set rights 750"
|
- name: "Set rights 750"
|
||||||
type: "command"
|
type: "command"
|
||||||
command: "chmod 750 /opt/repko/repko"
|
command: "chmod 750 /opt/repko/repko"
|
||||||
error: "Ошибка установки прав 640"
|
error: "Ошибка установки прав 750"
|
||||||
- name: "Set rights 640"
|
- name: "Set rights 640"
|
||||||
type: "command"
|
type: "command"
|
||||||
command: "chmod 640 /opt/repko/.env /etc/repko/config.ini"
|
command: "chmod 640 /opt/repko/.env /etc/repko/config.ini"
|
||||||
|
|
@ -415,8 +424,59 @@ sections:
|
||||||
error: "Не удалось создать ключ"
|
error: "Не удалось создать ключ"
|
||||||
- name: "get gpg key id"
|
- name: "get gpg key id"
|
||||||
type: "command"
|
type: "command"
|
||||||
command: "sudo -u {{.repko_user}} gpg --homedir /var/lib/repko/gnupg --list-keys --with-colons | grep pub | cut -d: -f5 > /etc/repko/keyid"
|
command: "sudo -u {{.repko_user}} gpg --homedir /var/lib/repko/gnupg --list-keys --with-colons | grep pub | cut -d: -f5"
|
||||||
error: "Не удалось получить и сохранить id gpg ключа"
|
error: "Не удалось получить и сохранить id gpg ключа"
|
||||||
|
assign-to: "gpg_key_id"
|
||||||
|
- name: "export gpg key"
|
||||||
|
type: "command"
|
||||||
|
command: "sudo -u {{.repko_user}} gpg --homedir /var/lib/repko/gnupg --armor --export {{.gpg_key_id}} > /usr/share/keyrings/repko.asc"
|
||||||
|
error: "Не удалось экспортировать gpg ключ"
|
||||||
|
- name: "write gpg key id"
|
||||||
|
type: "command"
|
||||||
|
command: "echo {{.gpg_key_id}} > /etc/repko/keyid"
|
||||||
|
error: "не удалось записать gpg key id в файл keyid"
|
||||||
|
- name: "set owner for exported key"
|
||||||
|
type: "command"
|
||||||
|
command: "chown -R root:root /usr/share/keyrings/repko.asc"
|
||||||
|
error: "Ошибка установки владельца файла экспортированного ключа"
|
||||||
|
- name: "set owner for keyid file"
|
||||||
|
type: "command"
|
||||||
|
command: "chown -R {{.repko_user}}:{{.repko_user}} /etc/repko/keyid"
|
||||||
|
error: "Ошибка установки владельца файла id ключа"
|
||||||
|
- name: "set rights for keys"
|
||||||
|
type: "command"
|
||||||
|
command: "chmod 644 /usr/share/keyrings/repko.asc /etc/repko/keyid"
|
||||||
|
error: "Ошибка установки прав для ключей"
|
||||||
|
- name: "basic auth"
|
||||||
|
description: "Настройка базовой аутентификации"
|
||||||
|
fields:
|
||||||
|
- name: "repko login"
|
||||||
|
variable-name: "repko_login"
|
||||||
|
field-type: "input"
|
||||||
|
description: "Логин для входа на сайт"
|
||||||
|
validate:
|
||||||
|
- rule: "regex_match(repko_login,`^[a-zA-Z0-9_-]+$`"
|
||||||
|
message: "Только строчные латинские буквы, цифры, _, -"
|
||||||
|
- name: "repko pass"
|
||||||
|
variable-name: "repko_pass"
|
||||||
|
field-type: "input"
|
||||||
|
description: "Пароль для входа на сайт"
|
||||||
|
validate:
|
||||||
|
- rule: "repko_pass!=''"
|
||||||
|
message: "Пароль не должен быть пустым"
|
||||||
|
actions:
|
||||||
|
- name: "generate htpasswd"
|
||||||
|
type: "command"
|
||||||
|
command: "htpasswd -c -b /etc/repko/.htpasswd {{.repko_login}} {{.repko_pass}}"
|
||||||
|
error: "Не удалось создать файл htpasswd"
|
||||||
|
- name: "set htpasswd owner"
|
||||||
|
type: "command"
|
||||||
|
command: "chown {{.repko_user}}:{{.repko_user}} /etc/repko/.htpasswd"
|
||||||
|
error: "Ошибка установки владельца файла "
|
||||||
|
- name: "set rights for htpasswd "
|
||||||
|
type: "command"
|
||||||
|
command: "chmod 640 /etc/repko/.htpasswd"
|
||||||
|
error: "Ошибку установки прав для файла"
|
||||||
- name: "paths"
|
- name: "paths"
|
||||||
description: "Настройка директорий"
|
description: "Настройка директорий"
|
||||||
fields:
|
fields:
|
||||||
|
|
@ -427,6 +487,13 @@ sections:
|
||||||
validate:
|
validate:
|
||||||
- rule: "dir_exists(debian_root)"
|
- rule: "dir_exists(debian_root)"
|
||||||
message: "Папка не существует"
|
message: "Папка не существует"
|
||||||
|
- name: "archive_root"
|
||||||
|
variable-name: "archive_root"
|
||||||
|
field-type: "directory"
|
||||||
|
description: "Директория архива debian"
|
||||||
|
validate:
|
||||||
|
- rule: "dir_exists(archive_root)"
|
||||||
|
message: "Папка не существует"
|
||||||
- name: "finale"
|
- name: "finale"
|
||||||
description: "Последний этап, проверьте правильность введенных данных"
|
description: "Последний этап, проверьте правильность введенных данных"
|
||||||
type: "final"
|
type: "final"
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
func Start() {
|
func Start() {
|
||||||
//Создаем новый объект Main для настройки.
|
//Создаем новый объект Main для настройки.
|
||||||
|
//todo работа внутри apt, вывод интерфейса во время выполнения apt
|
||||||
m := NewMain()
|
m := NewMain()
|
||||||
p := tea.NewProgram(m, tea.WithAltScreen()) //Запускаем через bubble tea программу
|
p := tea.NewProgram(m, tea.WithAltScreen()) //Запускаем через bubble tea программу
|
||||||
m.Program = p //Указываем объекту настроек, программу в которой запущен, чтобы передавать туда сигналы
|
m.Program = p //Указываем объекту настроек, программу в которой запущен, чтобы передавать туда сигналы
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,26 @@ func ExecuteAction(action *types.SectionAction, application *types.PackageApplic
|
||||||
if cmdErr != nil {
|
if cmdErr != nil {
|
||||||
return fmt.Errorf("не удалось создать шаблон команды: %v", cmdErr)
|
return fmt.Errorf("не удалось создать шаблон команды: %v", cmdErr)
|
||||||
}
|
}
|
||||||
return RunCommand(cmdStr, action.RunAs)
|
output, err := RunCommand(cmdStr, action.RunAs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if action.AssignTo != "" {
|
||||||
|
assigned := false
|
||||||
|
for i := range application.Variables {
|
||||||
|
v := &application.Variables[i]
|
||||||
|
if v.Name == action.AssignTo {
|
||||||
|
v.Value = output
|
||||||
|
assigned = true
|
||||||
|
logrus.Infof("Присвоение значения '%s' переменной '%s'", output, v.Name)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !assigned {
|
||||||
|
return fmt.Errorf("переменная '%s' для присвоения не найдена", action.AssignTo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
case "file_template":
|
case "file_template":
|
||||||
//Формируем 2 строки пути, с подставленными значениями и передаем её для выполнения
|
//Формируем 2 строки пути, с подставленными значениями и передаем её для выполнения
|
||||||
source, sourceErr := RenderTemplate(action.FileSource, vars)
|
source, sourceErr := RenderTemplate(action.FileSource, vars)
|
||||||
|
|
@ -75,9 +94,9 @@ func ExecuteAction(action *types.SectionAction, application *types.PackageApplic
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunCommand запускает выполнение переданной команды от указанного лица
|
// RunCommand запускает выполнение переданной команды от указанного лица
|
||||||
func RunCommand(cmdStr, runAs string) error {
|
func RunCommand(cmdStr, runAs string) (string, error) {
|
||||||
if cmdStr == "" {
|
if cmdStr == "" {
|
||||||
return nil
|
return "", nil
|
||||||
}
|
}
|
||||||
var cmd *exec.Cmd
|
var cmd *exec.Cmd
|
||||||
if runAs != "" && runAs != "root" {
|
if runAs != "" && runAs != "root" {
|
||||||
|
|
@ -87,9 +106,9 @@ func RunCommand(cmdStr, runAs string) error {
|
||||||
}
|
}
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ошибка команды: %v\nВывод: %s", err, string(output))
|
return string(output), fmt.Errorf("ошибка выполнения команды: %v\nВывод: %s", err, string(output))
|
||||||
}
|
}
|
||||||
return nil
|
return strings.TrimSpace(string(output)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderFileTemplate создает целевой файл на основе файла источника с подставленными значениями в нем
|
// RenderFileTemplate создает целевой файл на основе файла источника с подставленными значениями в нем
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,6 @@ package types
|
||||||
|
|
||||||
const SectionAbout = "about"
|
const SectionAbout = "about"
|
||||||
const SectionFinal = "final"
|
const SectionFinal = "final"
|
||||||
|
|
||||||
|
const ConfsDir = "/opt/gosetup/confs"
|
||||||
|
const LogFile = "/opt/gosetup/log.txt"
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ type SectionAction struct {
|
||||||
RunAs string `yaml:"run-as"` //Пользователь для запуска
|
RunAs string `yaml:"run-as"` //Пользователь для запуска
|
||||||
RequirePackages []string `yaml:"require-packages"` //Требуемые пакеты
|
RequirePackages []string `yaml:"require-packages"` //Требуемые пакеты
|
||||||
Error string `yaml:"error"` //Ошибка выполнения
|
Error string `yaml:"error"` //Ошибка выполнения
|
||||||
|
AssignTo string `yaml:"assign-to"` //Переменная, которой надо присвоить значение
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoolValidateFunc функция, которая возвращает ошибку, если данные checkbox неверны
|
// BoolValidateFunc функция, которая возвращает ошибку, если данные checkbox неверны
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue