LINUX.ORG.RU

Какой выдумать или создать формат для конфигов?

 , , ,


1

3

Хочу для своего упражнения использовать yaml. Вроде голанг его умеет читать и писать. Что говорит на эту тему духовенство? Уместен ли такой формат или же лучше взять что-то другое?

json не хочу по той причине, что в него нельзя вставлять комментарии, xml слишком многословен.

==========================================

Решение: взят обычный json, который читает - пишет структуру. Для комментария в структуре предусмотрено специальное поле Comment. Это не так удобно, зато гомоиконно.

Если в конфиге задано поле, отсутствующее в структуре, например, если название поля написано с опечаткой, то будет ошибка чтения конфига. Это важно, поскольку толерантность многих программ к опечаткам в конфигах приводит к тому, что можно часами сидеть и искать ответ на вопрос «ну почему же это дерьмо не работает»?

Код такой:

package main

import (
	"strings"; "fmt"; "os"
	"encoding/json"
	"io/ioutil"
	// "github.com/flynn/json5"
)

type SecretConfigDataStruct struct {
	Comment       string
	RecieverEMail string
	SMTPServer    string
	SMTPUser      string
	SMTPPassword  string
	SenderEMail   string }

var SecretConfigData SecretConfigDataStruct

func (sds *SecretConfigDataStruct) SaveToFile(filename string) (err error) {
	var text []byte
	text, err = json.MarshalIndent(sds,""," ")
	if err != nil { return	}	
	err = ioutil.WriteFile(filename, text, 0600)
	return }

const ConfigFileName = "secret-data.config.json"

// for development
func saveSecretConfigDataExample() {
	sds := SecretConfigDataStruct{
		Comment:       "Example config file. Copy this one to the secret-data.config.json and edit",
		SenderEMail:   "den@example.net",
		RecieverEMail: "world@example.net",
		SMTPServer:    "smtp.example.net",
		SMTPUser:      "Кирилл",
		SMTPPassword:  "bla-bla-bla"}
	err := sds.SaveToFile(ConfigFileName + ".example")
	if err != nil {	panic(err)	}}

func loadSecretConfigData() (err error) {
	sds := &SecretConfigData
	fn := ConfigFileName
	if _, err = os.Stat(fn); os.IsNotExist(err) {
		fmt.Printf("No config file %s found. Create one by copying from %s.example\n",
			fn, fn)
		return	}
	var bytes []byte
	bytes, err = ioutil.ReadFile(fn)
	if err != nil {
		fmt.Printf("Unable to read config %s\n", fn)
		return	}
		dec := json.NewDecoder(strings.NewReader(string(bytes)))
		dec.DisallowUnknownFields() 
		err = dec.Decode(sds)
	if err != nil {
		fmt.Printf("Error reading config file %s: %#v\n", fn, err)
		return	}
	fmt.Printf("playWithSecretConfigData returned %#v\n", sds)
	return }

★★★★★

Последнее исправление: den73 (всего исправлений: 4)

Ответ на: YAML or TOML от DukeNukem

Если нормального нет, надо использовать самое простое.

den73 ★★★★★
() автор топика
Ответ на: комментарий от beastie

В частности pf.conf, smtpd.conf, cwmrc и иже с ними.

У всех конфигов есть нечто общее. Это общее должно и быть реализовано как общее, а частности должны быть реализованы как микро-DSL-и в рамках общего. Т.е. даже не DSL-и, а отдельные макросы или команды. В противном случае пользователю нужно учить весь зоопарк. Хотя как посмотреть. Если задача состоит в том, чтобы раздуть сложность и сделать администрирование востребованной работой, то всё сделано правильно.

den73 ★★★★★
() автор топика
Ответ на: комментарий от hbee

Спасибо, добавил в закладки. Правда, если бы мне был нужен конфиг в виде скрипта, то я бы взял реализацию EcmaScript или groovy (он используется в Jenkins, т.е. нужен, вопрос в том, есть ли реализация). А мой фаворит среди встроенных языков - это https://github.com/cosmos72/gomacro (теоретически, т.е. по замыслу. Что он представляет из себя на практике, я никогда не проверял).

den73 ★★★★★
() автор топика

Использовать языка программирования в ввиде конфига - это очень херовая идея:

  • Сторонние приложения не могут распарсить этот конфиг и прочитать его значения. Так же сторонние приложения (да и не сторонние тоже) не смогут адекватно его модифицировать.
  • Это потенциальная уязвимость, т.к., скорее всего языки в этих конфигах смогут работать с файлами и сетью. Ты не можешь просто скачать конфиг с инета и подложить его, без анализа, что в нем написано.
  • Такие конфиги, зачастую на динамических языках, довольно сильно зависят от внутренней структуры приложения. Тебе придется поддерживать старую структуру приложения, иначе поломаются старые конфиги. И не понятно наксколько глубоко эти конфиги будут лезть в глубину твоего приложения.
  • Проблема с обновлением языка этих конфигов. Если выйдет новая версия, придется решать, переходить на нее, или остаться на старье для совместимости.

Единственный плюс - это довольно легкая и гибкая начальная реализация, когда особо непонятно, как именно будут использовать твое приложение. Но потом это обернется гигантскими проблемами.

Deleted
()
Ответ на: комментарий от Deleted

1 - да, при необходимости придётся писать внешний разбор

2 - tengo имеет API для запрещения лишней функциональности

Остальное пустяки.

А вообще использование Turing-complete-языков для конфигов — хорошая идея. Потому что часто конфиги усложняются, и незаметно оказывается, что нужны условные выражения, циклы и т.д. Есть примеры XML-конфигов, в которых реализован Turing-complete-язык; выглядит чудовищно :).

hbee ★★★★
()
Ответ на: комментарий от hbee

Чтобы написать внешний разбор придется реализовать половину основного приложения.

Модификация этих конфигов автоматизированными инструментами вообще практически невозможна.

Deleted
()
Ответ на: комментарий от hbee

Да и все остальное тоже не пустяки.

Если даже взять два конкурирующих продукта:

- Пользователи awesome, в котором конфиги на lua, постоянно плачут, что с каждой версией их конфиги отваливаются.

- Пользователь i3 о такой проблеме особо даже не слышали.

Если нужна какая-то сложная логика, на кайняк, можно позволить запуск внешних приложений с разбором их stdout.

Deleted
()
Ответ на: комментарий от Deleted

Думаю, что просто «конфиг» - это слишком широкая тема, чтобы было единственное оптимальное решение. Но если нужен ЯП для конфигов, и продукт с открытыми исходниками, то можно, в конце концов, написать конфиг на языке самого приложения. Пример - EMACS.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.