3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-13 07:29:30 +01:00

Use docopt for command-line processing and new YAML configuration format

This commit is contained in:
Daniel Oaks 2016-04-12 23:00:09 +10:00
parent c705bdaac5
commit 29d80366a6
6 changed files with 94 additions and 86 deletions

1
.gitignore vendored
View File

@ -0,0 +1 @@
/ircd.*

View File

@ -10,7 +10,7 @@ Discussion at:
* follows the RFCs where possible * follows the RFCs where possible
* UTF-8 nick and channel names * UTF-8 nick and channel names
* [gcfg](https://github.com/go-gcfg/gcfg/tree/v1) gitconfig-style configuration * [yaml](http://yaml.org/) configuration
* server password (PASS command) * server password (PASS command)
* channels with most standard modes * channels with most standard modes
* IRC operators (OPER command) * IRC operators (OPER command)
@ -39,22 +39,24 @@ and channel sync issues created during netsplits.
```sh ```sh
go get go get
go install go install
ergonomadic initdb -conf ergonomadic.conf cp ergonomadic.yaml ircd.yaml
vim ircd.yaml # modify the config file to your liking
ergonomadic initdb
``` ```
# Configuration # Configuration
See the example [`ergonomadic.conf`](ergonomadic.conf). Passwords are base64-encoded bcrypted byte See the example [`ergonomadic.yaml`](ergonomadic.yaml). Passwords are base64-encoded bcrypted byte
strings. You can generate them with the `genpasswd` subcommand. strings. You can generate them with the `genpasswd` subcommand.
```sh ```sh
ergonomadic genpasswd 'hunter2!' ergonomadic genpasswd
``` ```
# Running the server # Running the server
```sh ```sh
ergonomadic run -conf ergonomadic.conf ergonomadic run
``` ```
# Credits # Credits

View File

@ -1,15 +0,0 @@
[server]
name = "irc.example.com" ; required, usually a hostname
database = "ergonomadic.db" ; path relative to this file
listen = "localhost:6667" ; see `net.Listen` for examples
listen = "[::1]:6667" ; multiple `listen`s are allowed.
wslisten = ":8080" ; websocket listen
log = "debug" ; error, warn, info, debug
motd = "motd.txt" ; path relative to this file
password = "JDJhJDA0JHJzVFFlNXdOUXNhLmtkSGRUQVVEVHVYWXRKUmdNQ3FKVTRrczRSMTlSWGRPZHRSMVRzQmtt" ; 'test'
[operator "root"]
password = "JDJhJDA0JEhkcm10UlNFRkRXb25iOHZuSDVLZXVBWlpyY0xyNkQ4dlBVc1VMWVk1LlFjWFpQbGxZNUtl" ; 'toor'
[theater "#ghostbusters"]
password = "JDJhJDA0JG0yY1h4cTRFUHhkcjIzN2p1M2Nvb2VEYjAzSHh4eTB3YkZ0VFRLV1ZPVXdqeFBSRUtmRlBT" ; 'venkman'

View File

@ -1,81 +1,63 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"github.com/edmund-huber/ergonomadic/irc"
"log" "log"
"os" "syscall"
"path/filepath"
"github.com/docopt/docopt-go"
"github.com/edmund-huber/ergonomadic/irc"
"golang.org/x/crypto/ssh/terminal"
) )
func usage() {
fmt.Fprintln(os.Stderr, "ergonomadic <run|genpasswd|initdb|upgradedb> [options]")
fmt.Fprintln(os.Stderr, " run -conf <config> -- run server")
fmt.Fprintln(os.Stderr, " initdb -conf <config> -- initialize database")
fmt.Fprintln(os.Stderr, " upgrade -conf <config> -- upgrade database")
fmt.Fprintln(os.Stderr, " genpasswd <password> -- bcrypt a password")
fmt.Fprintln(os.Stderr)
fmt.Fprintln(os.Stderr, "software version:", irc.SEM_VER)
flag.PrintDefaults()
}
func loadConfig(conf string) *irc.Config {
config, err := irc.LoadConfig(conf)
if err != nil {
log.Fatalln("error loading config:", err)
}
err = os.Chdir(filepath.Dir(conf))
if err != nil {
log.Fatalln("chdir error:", err)
}
return config
}
func genPasswd() {
}
func main() { func main() {
var conf string version := irc.SEM_VER
flag.Usage = usage usage := `ergonomadic.
Usage:
ergonomadic initdb [--conf <filename>]
ergonomadic upgradedb [--conf <filename>]
ergonomadic genpasswd [--conf <filename>]
ergonomadic run [--conf <filename>]
ergonomadic -h | --help
ergonomadic --version
Options:
--conf <filename> Configuration file to use [default: ircd.yaml].
-h --help Show this screen.
--version Show version.`
runFlags := flag.NewFlagSet("run", flag.ExitOnError) arguments, _ := docopt.Parse(usage, nil, true, version, false)
runFlags.Usage = usage
runFlags.StringVar(&conf, "conf", "ergonomadic.conf", "ergonomadic config file")
flag.Parse() // load config now because it's the same process for all
configfile := arguments["--conf"].(string)
config, err := irc.LoadConfig(configfile)
if err != nil {
log.Fatal("Config file did not load successfully:", err.Error())
}
switch flag.Arg(0) { if arguments["genpasswd"].(bool) {
case "genpasswd": fmt.Print("Enter Password: ")
encoded, err := irc.GenerateEncodedPassword(flag.Arg(1)) bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
if err != nil {
log.Fatal("Error reading password:", err.Error())
}
password := string(bytePassword)
encoded, err := irc.GenerateEncodedPassword(password)
if err != nil { if err != nil {
log.Fatalln("encoding error:", err) log.Fatalln("encoding error:", err)
} }
fmt.Print("\n")
fmt.Println(encoded) fmt.Println(encoded)
} else if arguments["initdb"].(bool) {
case "initdb":
runFlags.Parse(flag.Args()[1:])
config := loadConfig(conf)
irc.InitDB(config.Server.Database) irc.InitDB(config.Server.Database)
log.Println("database initialized: ", config.Server.Database) log.Println("database initialized: ", config.Server.Database)
} else if arguments["upgradedb"].(bool) {
case "upgradedb":
runFlags.Parse(flag.Args()[1:])
config := loadConfig(conf)
irc.UpgradeDB(config.Server.Database) irc.UpgradeDB(config.Server.Database)
log.Println("database upgraded: ", config.Server.Database) log.Println("database upgraded: ", config.Server.Database)
} else if arguments["run"].(bool) {
case "run":
runFlags.Parse(flag.Args()[1:])
config := loadConfig(conf)
irc.Log.SetLevel(config.Server.Log) irc.Log.SetLevel(config.Server.Log)
server := irc.NewServer(config) server := irc.NewServer(config)
log.Println(irc.SEM_VER, "running") log.Println(irc.SEM_VER, "running")
defer log.Println(irc.SEM_VER, "exiting") defer log.Println(irc.SEM_VER, "exiting")
server.Run() server.Run()
default:
usage()
} }
} }

34
ergonomadic.yaml Normal file
View File

@ -0,0 +1,34 @@
# ergonomadic IRCd config
server:
# server name
name: ergonomadic.test
# database filename (sqlite db)
database: ircd.db
# addresses to listen on
listen:
- ":6667"
- "127.0.0.1:6668"
- "[::1]:6668"
# websocket listening port
wslisten: ":8080"
# password to login to the server
# generated using "ergonomadic genpasswd"
#password: ""
# log level, one of error, warn, info, debug
log: debug
# motd filename
motd: ircd.motd
# ircd operators
operator:
# operator named 'dan'
dan:
# password to login with /OPER command
# generated using "ergonomadic genpasswd"
password: JDJhJDA0JE1vZmwxZC9YTXBhZ3RWT2xBbkNwZnV3R2N6VFUwQUI0RUJRVXRBRHliZVVoa0VYMnlIaGsu

View File

@ -1,9 +1,11 @@
package irc package irc
import ( import (
"gopkg.in/gcfg.v1"
"errors" "errors"
"io/ioutil"
"log" "log"
"gopkg.in/yaml.v2"
) )
type PassConfig struct { type PassConfig struct {
@ -55,22 +57,24 @@ func (conf *Config) Theaters() map[Name][]byte {
} }
func LoadConfig(filename string) (config *Config, err error) { func LoadConfig(filename string) (config *Config, err error) {
config = &Config{} data, err := ioutil.ReadFile(filename)
err = gcfg.ReadFileInto(config, filename)
if err != nil { if err != nil {
return return nil, err
} }
err = yaml.Unmarshal(data, &config)
if err != nil {
return nil, err
}
if config.Server.Name == "" { if config.Server.Name == "" {
err = errors.New("server.name missing") return nil, errors.New("Server name missing")
return
} }
if config.Server.Database == "" { if config.Server.Database == "" {
err = errors.New("server.database missing") return nil, errors.New("Server database missing")
return
} }
if len(config.Server.Listen) == 0 { if len(config.Server.Listen) == 0 {
err = errors.New("server.listen missing") return nil, errors.New("Server listening addresses missing")
return
} }
return return config, nil
} }