Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
autoradio
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ale
autoradio
Commits
f67cdadd
Commit
f67cdadd
authored
9 years ago
by
ale
Browse files
Options
Downloads
Patches
Plain Diff
golint fixes
parent
5fd13b53
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
api.go
+35
-16
35 additions, 16 deletions
api.go
etcd_client.go
+5
-3
5 additions, 3 deletions
etcd_client.go
with
40 additions
and
19 deletions
api.go
+
35
−
16
View file @
f67cdadd
...
@@ -14,12 +14,12 @@ import (
...
@@ -14,12 +14,12 @@ import (
)
)
const
(
const
(
//
P
ath to the mount configuration in
etcd. This should never
//
MountPrefix stores the p
ath to the mount configuration in
//
change, upgrades to the configuration format should be
//
etcd. This should never change between releases, upgrades
// backwards-compatible.
//
to the configuration format should be
backwards-compatible.
MountPrefix
=
"/icecast/mounts/"
MountPrefix
=
"/icecast/mounts/"
// Path for the cluster runtime data. Whenever the format of
// Path
s
for the cluster runtime data. Whenever the format of
// this data changes, the ABIVersion should be increased. A
// this data changes, the ABIVersion should be increased. A
// rolling restart of the cluster will then seamlessly cause a
// rolling restart of the cluster will then seamlessly cause a
// transition to the new consensus (the cluster will be
// transition to the new consensus (the cluster will be
...
@@ -33,13 +33,16 @@ const (
...
@@ -33,13 +33,16 @@ const (
)
)
var
(
var
(
// IcecastPort is the port that the Icecast server will listen
// on. Since we fully manage the system-wide Icecast instance,
// there's not much point in making this configurable.
IcecastPort
=
8000
IcecastPort
=
8000
ErrIsDirectory
=
errors
.
New
(
"key is a directory"
)
ErrIsDirectory
=
errors
.
New
(
"key is a directory"
)
ErrIsFile
=
errors
.
New
(
"key is a file"
)
ErrIsFile
=
errors
.
New
(
"key is a file"
)
)
)
// Encoding
p
aram
eter
s used to re-encode a stream.
// Encoding
P
arams used to re-encode a stream.
type
EncodingParams
struct
{
type
EncodingParams
struct
{
// Path to the source mountpoint.
// Path to the source mountpoint.
SourceName
string
SourceName
string
...
@@ -55,7 +58,8 @@ type EncodingParams struct {
...
@@ -55,7 +58,8 @@ type EncodingParams struct {
Quality
float64
Quality
float64
}
}
// NewEncodingParams sets some default values.
// NewEncodingParams creates an EncodingParams object with the right
// default values.
func
NewEncodingParams
()
*
EncodingParams
{
func
NewEncodingParams
()
*
EncodingParams
{
return
&
EncodingParams
{
return
&
EncodingParams
{
SampleRate
:
44100
,
SampleRate
:
44100
,
...
@@ -85,6 +89,8 @@ func (p *EncodingParams) String() string {
...
@@ -85,6 +89,8 @@ func (p *EncodingParams) String() string {
return
strings
.
Join
(
out
,
", "
)
return
strings
.
Join
(
out
,
", "
)
}
}
// Valid returns true if the EncodingParams seem to make sense. We try
// to be as close to the liquidsoap capabilities as possible.
func
(
p
*
EncodingParams
)
Valid
()
error
{
func
(
p
*
EncodingParams
)
Valid
()
error
{
switch
p
.
Format
{
switch
p
.
Format
{
case
"mp3"
,
"mp3.cbr"
,
"mp3.abr"
,
"vorbis.cbr"
,
"vorbis.abr"
:
case
"mp3"
,
"mp3.cbr"
,
"mp3.abr"
,
"vorbis.cbr"
,
"vorbis.abr"
:
...
@@ -120,7 +126,7 @@ func (p *EncodingParams) Valid() error {
...
@@ -120,7 +126,7 @@ func (p *EncodingParams) Valid() error {
return
nil
return
nil
}
}
//
A m
ount
point for a stream
.
//
M
ount
stores the configuration for a stream (mount, in Icecast lingo)
.
type
Mount
struct
{
type
Mount
struct
{
// Name (path to the mountpoint).
// Name (path to the mountpoint).
Name
string
Name
string
...
@@ -145,6 +151,8 @@ type Mount struct {
...
@@ -145,6 +151,8 @@ type Mount struct {
Transcoding
*
EncodingParams
Transcoding
*
EncodingParams
}
}
// Valid performs a consistency check and returns true if the
// configuration for the stream is correct.
func
(
m
*
Mount
)
Valid
()
error
{
func
(
m
*
Mount
)
Valid
()
error
{
if
!
strings
.
HasPrefix
(
m
.
Name
,
"/"
)
{
if
!
strings
.
HasPrefix
(
m
.
Name
,
"/"
)
{
return
errors
.
New
(
"name does not start with a slash"
)
return
errors
.
New
(
"name does not start with a slash"
)
...
@@ -166,14 +174,18 @@ func (m *Mount) Valid() error {
...
@@ -166,14 +174,18 @@ func (m *Mount) Valid() error {
return
nil
return
nil
}
}
// Equal returns true if the two mounts have the same configuration.
func
(
m
*
Mount
)
Equal
(
other
*
Mount
)
bool
{
func
(
m
*
Mount
)
Equal
(
other
*
Mount
)
bool
{
return
(
m
.
Name
==
other
.
Name
)
&&
(
m
.
Username
==
other
.
Username
)
&&
(
m
.
Password
==
other
.
Password
)
&&
(
m
.
RelayUrl
==
other
.
RelayUrl
)
&&
(
m
.
Fallback
==
other
.
Fallback
)
&&
((
m
.
Transcoding
==
nil
&&
other
.
Transcoding
==
nil
)
||
(
m
.
Transcoding
!=
nil
&&
other
.
Transcoding
!=
nil
&&
*
m
.
Transcoding
==
*
other
.
Transcoding
))
return
(
m
.
Name
==
other
.
Name
)
&&
(
m
.
Username
==
other
.
Username
)
&&
(
m
.
Password
==
other
.
Password
)
&&
(
m
.
RelayUrl
==
other
.
RelayUrl
)
&&
(
m
.
Fallback
==
other
.
Fallback
)
&&
((
m
.
Transcoding
==
nil
&&
other
.
Transcoding
==
nil
)
||
(
m
.
Transcoding
!=
nil
&&
other
.
Transcoding
!=
nil
&&
*
m
.
Transcoding
==
*
other
.
Transcoding
))
}
}
// IsRelay returns true if the stream is configured as a relay of an
// external source.
func
(
m
*
Mount
)
IsRelay
()
bool
{
func
(
m
*
Mount
)
IsRelay
()
bool
{
return
m
.
RelayUrl
!=
""
return
m
.
RelayUrl
!=
""
}
}
// HasTranscoder returns true if the stream has transcoding sub-streams.
func
(
m
*
Mount
)
HasTranscoder
()
bool
{
func
(
m
*
Mount
)
HasTranscoder
()
bool
{
return
m
.
Transcoding
!=
nil
return
m
.
Transcoding
!=
nil
}
}
...
@@ -183,17 +195,22 @@ func mountEtcdPath(mountName string) string {
...
@@ -183,17 +195,22 @@ func mountEtcdPath(mountName string) string {
return
MountPrefix
+
mountName
[
1
:
]
return
MountPrefix
+
mountName
[
1
:
]
}
}
// Return the Icecast mount path for the given public mount name.
// MountNameToIcecastPath returns the Icecast mount path for the given
// public mount name.
func
MountNameToIcecastPath
(
mountName
string
)
string
{
func
MountNameToIcecastPath
(
mountName
string
)
string
{
return
IcecastMountPrefix
+
mountName
return
IcecastMountPrefix
+
mountName
}
}
// Return the public mount name from an Icecast mount path.
// IcecastPathToMountName returns the public mount name from an
// Icecast mount path. If 'path' does not start with
// IcecastMountPrefix, it is returned unchanged (though arguably this
// should be an error).
func
IcecastPathToMountName
(
path
string
)
string
{
func
IcecastPathToMountName
(
path
string
)
string
{
return
strings
.
TrimPrefix
(
path
,
IcecastMountPrefix
)
return
strings
.
TrimPrefix
(
path
,
IcecastMountPrefix
)
}
}
// Status of a mount on an individual Icecast server.
// IcecastMountStatus has information about a mount on an individual
// Icecast server, as provided by Icecast itself.
type
IcecastMountStatus
struct
{
type
IcecastMountStatus
struct
{
Name
string
Name
string
Listeners
int
Listeners
int
...
@@ -204,7 +221,8 @@ type IcecastMountStatus struct {
...
@@ -204,7 +221,8 @@ type IcecastMountStatus struct {
FrameRate
float64
FrameRate
float64
}
}
// Status of a node. This is used to report load and stream status.
// NodeStatus stores runtime information about an autoradio node. This
// is used to report load and stream status.
type
NodeStatus
struct
{
type
NodeStatus
struct
{
// Short name of this node.
// Short name of this node.
Name
string
Name
string
...
@@ -278,6 +296,7 @@ type Client struct {
...
@@ -278,6 +296,7 @@ type Client struct {
activeNodesCache
*
nodesCache
activeNodesCache
*
nodesCache
}
}
// NewClient creates and returns a new Client.
func
NewClient
(
client
EtcdClient
)
*
Client
{
func
NewClient
(
client
EtcdClient
)
*
Client
{
return
&
Client
{
client
,
newNodesCache
()}
return
&
Client
{
client
,
newNodesCache
()}
}
}
...
@@ -341,15 +360,15 @@ func (r *Client) ListMounts() ([]*Mount, error) {
...
@@ -341,15 +360,15 @@ func (r *Client) ListMounts() ([]*Mount, error) {
return
result
,
nil
return
result
,
nil
}
}
//
L
ocation data for the master node. Having the
IP address here saves
//
MasterNodeInfo stores l
ocation data for the master node. Having the
// another round-trip to etcd to retrieve the
node info in the most
//
IP address here saves
another round-trip to etcd to retrieve the
// common case.
//
node info in the most
common case.
type
MasterNodeInfo
struct
{
type
MasterNodeInfo
struct
{
Name
string
Name
string
IP
[]
net
.
IP
IP
[]
net
.
IP
}
}
// GetMaster
Addr
returns the address of the current master server.
// GetMaster
Info
returns the address of the current master server.
func
(
r
*
Client
)
GetMasterInfo
()
(
*
MasterNodeInfo
,
error
)
{
func
(
r
*
Client
)
GetMasterInfo
()
(
*
MasterNodeInfo
,
error
)
{
response
,
err
:=
r
.
client
.
Get
(
MasterElectionPath
,
false
,
false
)
response
,
err
:=
r
.
client
.
Get
(
MasterElectionPath
,
false
,
false
)
if
err
!=
nil
||
response
.
Node
==
nil
{
if
err
!=
nil
||
response
.
Node
==
nil
{
...
@@ -365,7 +384,6 @@ func (r *Client) GetMasterInfo() (*MasterNodeInfo, error) {
...
@@ -365,7 +384,6 @@ func (r *Client) GetMasterInfo() (*MasterNodeInfo, error) {
return
&
m
,
nil
return
&
m
,
nil
}
}
// GetNodes returns the list of active cluster nodes.
func
(
r
*
Client
)
doGetNodes
()
([]
*
NodeStatus
,
error
)
{
func
(
r
*
Client
)
doGetNodes
()
([]
*
NodeStatus
,
error
)
{
response
,
err
:=
r
.
client
.
Get
(
NodePrefix
,
false
,
false
)
response
,
err
:=
r
.
client
.
Get
(
NodePrefix
,
false
,
false
)
if
err
!=
nil
||
response
.
Node
==
nil
{
if
err
!=
nil
||
response
.
Node
==
nil
{
...
@@ -384,6 +402,7 @@ func (r *Client) doGetNodes() ([]*NodeStatus, error) {
...
@@ -384,6 +402,7 @@ func (r *Client) doGetNodes() ([]*NodeStatus, error) {
return
result
,
nil
return
result
,
nil
}
}
// GetNodes returns the list of active cluster nodes.
func
(
r
*
Client
)
GetNodes
()
([]
*
NodeStatus
,
error
)
{
func
(
r
*
Client
)
GetNodes
()
([]
*
NodeStatus
,
error
)
{
return
r
.
activeNodesCache
.
Get
(
r
.
doGetNodes
)
return
r
.
activeNodesCache
.
Get
(
r
.
doGetNodes
)
}
}
...
...
This diff is collapsed.
Click to expand it.
etcd_client.go
+
5
−
3
View file @
f67cdadd
...
@@ -27,7 +27,7 @@ func mustLoadFile(path string) string {
...
@@ -27,7 +27,7 @@ func mustLoadFile(path string) string {
// Resolve a list of etcd host:port specs, returning URLs.
// Resolve a list of etcd host:port specs, returning URLs.
func
resolveAll
(
input
[]
string
,
proto
string
)
[]
string
{
func
resolveAll
(
input
[]
string
,
proto
string
)
[]
string
{
result
:=
make
(
[]
string
,
0
)
var
result
[]
string
for
_
,
hostport
:=
range
input
{
for
_
,
hostport
:=
range
input
{
host
,
port
,
err
:=
net
.
SplitHostPort
(
hostport
)
host
,
port
,
err
:=
net
.
SplitHostPort
(
hostport
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -45,6 +45,8 @@ func resolveAll(input []string, proto string) []string {
...
@@ -45,6 +45,8 @@ func resolveAll(input []string, proto string) []string {
return
result
return
result
}
}
// NewEtcdClient creates a new etcd client. It uses command-line flags
// to find servers and connection parameters.
func
NewEtcdClient
(
strongReads
bool
)
EtcdClient
{
func
NewEtcdClient
(
strongReads
bool
)
EtcdClient
{
proto
:=
"http"
proto
:=
"http"
if
*
etcdCertFile
!=
""
&&
*
etcdKeyFile
!=
""
{
if
*
etcdCertFile
!=
""
&&
*
etcdKeyFile
!=
""
{
...
@@ -81,8 +83,8 @@ func NewEtcdClient(strongReads bool) EtcdClient {
...
@@ -81,8 +83,8 @@ func NewEtcdClient(strongReads bool) EtcdClient {
return
c
return
c
}
}
// Etcd client interface
. U
sed
to decouple our code from the actual
// Etcd
Client is the etcd
client interface
u
sed
by autoradio. Used to
// etcd API, for testing purposes.
//
decouple our code from the actual
etcd API, for testing purposes.
type
EtcdClient
interface
{
type
EtcdClient
interface
{
Create
(
string
,
string
,
uint64
)
(
*
etcd
.
Response
,
error
)
Create
(
string
,
string
,
uint64
)
(
*
etcd
.
Response
,
error
)
CompareAndSwap
(
string
,
string
,
uint64
,
string
,
uint64
)
(
*
etcd
.
Response
,
error
)
CompareAndSwap
(
string
,
string
,
uint64
,
string
,
uint64
)
(
*
etcd
.
Response
,
error
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment