Commit e2473df0 authored by ale's avatar ale

slight refactoring of the icecast configuration to increase object reuse

parent f1c2310a
......@@ -2,6 +2,8 @@ package radioai
import (
"bytes"
"crypto/rand"
"encoding/base64"
"encoding/json"
"errors"
"strings"
......@@ -119,3 +121,10 @@ func (r *RadioAPI) GetMasterAddr() (string, error) {
}
return response[0].Value, nil
}
// GeneratePassword returns a new random password.
func GeneratePassword() string {
b := make([]byte, 6)
rand.Read(b)
return base64.StdEncoding.EncodeToString(b)
}
package main
import (
"crypto/rand"
"encoding/base64"
"flag"
"fmt"
"hash/crc32"
......@@ -104,12 +102,6 @@ func generateUsername(path string) string {
return fmt.Sprintf("source%d", crc32.ChecksumIEEE([]byte(path)))
}
func generatePassword() string {
b := make([]byte, 6)
rand.Read(b)
return base64.StdEncoding.EncodeToString(b)
}
func createMount(args []string) {
path := args[0]
if !strings.HasPrefix(path, "/") {
......@@ -125,7 +117,7 @@ func createMount(args []string) {
// Create the new mount, randomly generate source authentication.
username := generateUsername(path)
password := generatePassword()
password := radioai.GeneratePassword()
m := &radioai.Mount{
Name: path,
Username: username,
......
......@@ -6,16 +6,18 @@ import (
)
type IcecastController struct {
PublicIp string
ConfigFile string
InitScript string
PublicIp string
ConfigFile string
InitScript string
config *icecastConfig
}
func NewIcecastController(publicIp string) *IcecastController {
return &IcecastController{
PublicIp: publicIp,
ConfigFile: "/etc/icecast2/icecast.conf",
InitScript: "/etc/init.d/icecast2",
PublicIp: publicIp,
ConfigFile: "/etc/icecast2/icecast.conf",
InitScript: "/etc/init.d/icecast2",
config: newIcecastConfig(publicIp),
}
}
......@@ -31,8 +33,8 @@ func (ic *IcecastController) Update(conf *ClusterConfig, isMaster bool, masterAd
tmpf := ic.ConfigFile + ".tmp"
defer os.Remove(tmpf)
iconfig := NewIcecastConfig(conf, ic.PublicIp, isMaster, masterAddr)
if err := iconfig.EncodeToFile(tmpf); err != nil {
ic.config.Update(conf, isMaster, masterAddr)
if err := ic.config.EncodeToFile(tmpf); err != nil {
return err
}
......
......@@ -79,7 +79,7 @@ type iceMountConfig struct {
OnDisconnect string `xml:"on-disconnect,omitempty"`
}
type IcecastConfig struct {
type icecastConfig struct {
XMLName xml.Name
Limits iceLimitsConfig `xml:"limits"`
Auth iceAuthenticationConfig `xml:"authentication"`
......@@ -93,11 +93,13 @@ type IcecastConfig struct {
Mounts []iceMountConfig `xml:"mount"`
}
func defaultDebianConfig() *IcecastConfig {
sourcePw := "x"
adminPw := "password"
func defaultDebianConfig(publicIp string) *icecastConfig {
// Pick some random passwords on startup. We don't use them,
// but icecast is happier if they're set.
sourcePw := GeneratePassword()
adminPw := GeneratePassword()
return &IcecastConfig{
return &icecastConfig{
XMLName: xml.Name{"", "icecast"},
Limits: iceLimitsConfig{
Clients: maxClients,
......@@ -115,6 +117,7 @@ func defaultDebianConfig() *IcecastConfig {
AdminUser: "admin",
AdminPassword: adminPw,
},
Hostname: publicIp,
Fileserve: 1,
Paths: icePathsConfig{
Basedir: "/usr/share/icecast2",
......@@ -133,12 +136,14 @@ func defaultDebianConfig() *IcecastConfig {
{"0.0.0.0", baseHttpPort, 0},
{"0.0.0.0", shoutHttpPort, 1},
},
Relays: []iceRelayConfig{},
Mounts: []iceMountConfig{},
}
}
func (c *IcecastConfig) Encode() ([]byte, error) {
func newIcecastConfig(publicIp string) *icecastConfig {
return defaultDebianConfig(publicIp)
}
func (c *icecastConfig) Encode() ([]byte, error) {
var buf bytes.Buffer
output, err := xml.MarshalIndent(c, "", " ")
......@@ -152,7 +157,7 @@ func (c *IcecastConfig) Encode() ([]byte, error) {
return buf.Bytes(), nil
}
func (c *IcecastConfig) EncodeToFile(path string) error {
func (c *icecastConfig) EncodeToFile(path string) error {
file, err := os.Create(path)
if err != nil {
return err
......@@ -196,15 +201,20 @@ func mountToRelay(masterAddr string, m *Mount) iceRelayConfig {
}
}
func NewIcecastConfig(config *ClusterConfig, publicIp string, isMaster bool, masterAddr string) *IcecastConfig {
iconf := defaultDebianConfig()
iconf.Hostname = publicIp
for _, m := range config.ListMounts() {
if isMaster {
iconf.Mounts = append(iconf.Mounts, mountToConfig(m))
} else {
iconf.Relays = append(iconf.Relays, mountToRelay(masterAddr, m))
func (ic *icecastConfig) Update(config *ClusterConfig, isMaster bool, masterAddr string) {
ic.Mounts = nil
ic.Relays = nil
if isMaster {
mounts := make([]iceMountConfig, 0)
for _, m := range config.ListMounts() {
mounts = append(mounts, mountToConfig(m))
}
ic.Mounts = mounts
} else {
relays := make([]iceRelayConfig, 0)
for _, m := range config.ListMounts() {
relays = append(relays, mountToRelay(masterAddr, m))
}
ic.Relays = relays
}
return iconf
}
......@@ -15,7 +15,8 @@ func TestIcecastConfig(t *testing.T) {
c.setMount(mount)
// Test a relay config.
ice := NewIcecastConfig(c, "1.2.3.4", false, "2.3.4.5")
ice := newIcecastConfig("1.2.3.4")
ice.Update(c, false, "2.3.4.5")
output, err := ice.Encode()
if err != nil {
t.Fatal(err)
......@@ -29,7 +30,8 @@ func TestIcecastConfig(t *testing.T) {
}
// Test a master config.
ice = NewIcecastConfig(c, "1.2.3.4", true, "2.3.4.5")
ice = newIcecastConfig("1.2.3.4")
ice.Update(c, true, "2.3.4.5")
output, err = ice.Encode()
if err != nil {
t.Fatal(err)
......
......@@ -110,7 +110,13 @@ func (w *ConfigSyncer) syncer() {
continue
}
// Update the 'last seen' index, so that if
// the Watcher dies, it knows where to start
// from and we do not have to download the
// full configuration again.
w.index = response.Index
// Trigger an update.
trigger(w.upch)
case <-w.stop:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment