prepare: configures snapcast server and client
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
979040227e
commit
9af55ee991
@ -1,10 +1,12 @@
|
|||||||
proc /proc proc defaults 0 0
|
proc /proc proc defaults 0 0
|
||||||
/dev/mmcblk0p1 /boot vfat ro,defaults 0 2
|
/dev/mmcblk0p1 /boot vfat ro,defaults 0 2
|
||||||
/dev/mmcblk0p2 / ext4 ro,defaults,noatime 0 1
|
/dev/mmcblk0p2 / ext4 ro,defaults,noatime 0 1
|
||||||
tmpfs /var/log tmpfs nodev,nosuid 0 0
|
tmpfs /var/log tmpfs nodev,nosuid 0 0
|
||||||
tmpfs /var/tmp tmpfs nodev,nosuid 0 0
|
tmpfs /var/tmp tmpfs nodev,nosuid 0 0
|
||||||
tmpfs /tmp tmpfs nodev,nosuid 0 0
|
tmpfs /tmp tmpfs nodev,nosuid 0 0
|
||||||
tmpfs /var/lib/systemd/timesync tmpfs auto,noatime,size=5m,mode=0755,uid={{.TimesyncUID}},gid={{.TimesyncGID}} 0 0
|
tmpfs /var/lib/systemd/timesync tmpfs auto,noatime,size=5m,mode=0755,uid={{.TimesyncUID}},gid={{.TimesyncGID}} 0 0
|
||||||
tmpfs /var/cache/mopidy tmpfs auto,noatime,size=5m,mode=0755,uid={{.MopidyUID}},gid={{.MopidyGID}} 0 0
|
tmpfs /var/cache/mopidy tmpfs auto,noatime,size=5m,mode=0755,uid={{.MopidyUID}},gid={{.MopidyGID}} 0 0
|
||||||
tmpfs /var/cache/upmpdcli tmpfs auto,noatime,size=5m,mode=0755,uid={{.UpmpdcliUID}},gid={{.UpmpdcliGID}} 0 0
|
tmpfs /var/cache/upmpdcli tmpfs auto,noatime,size=5m,mode=0755,uid={{.UpmpdcliUID}},gid={{.UpmpdcliGID}} 0 0
|
||||||
tmpfs /var/lib/ntp tmpfs nosuid,nodev 0 0
|
tmpfs /var/lib/ntp tmpfs nosuid,nodev 0 0
|
||||||
|
tmpfs /var/lib/snapserver tmpfs nosuid,nodev 0 0
|
||||||
|
tmpfs /var/lib/snapclient tmpfs nosuid,nodev 0 0
|
||||||
|
@ -3,7 +3,7 @@ cache_dir = /var/cache/mopidy
|
|||||||
config_dir = /etc/mopidy/
|
config_dir = /etc/mopidy/
|
||||||
|
|
||||||
[audio]
|
[audio]
|
||||||
output = alsasink
|
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! filesink location=/tmp/snapfifo
|
||||||
mixer = alsamixer
|
mixer = alsamixer
|
||||||
mixer_volume = 100
|
mixer_volume = 100
|
||||||
|
|
||||||
@ -11,7 +11,6 @@ mixer_volume = 100
|
|||||||
card = 0
|
card = 0
|
||||||
control= Headphone
|
control= Headphone
|
||||||
|
|
||||||
|
|
||||||
[mpd]
|
[mpd]
|
||||||
hostname = 0.0.0.0
|
hostname = 0.0.0.0
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@ const (
|
|||||||
schnutboxConfigDir = "/etc/schnutibox"
|
schnutboxConfigDir = "/etc/schnutibox"
|
||||||
upmpdcliUser = "upmpdcli"
|
upmpdcliUser = "upmpdcli"
|
||||||
upmpdcliGroup = "nogroup"
|
upmpdcliGroup = "nogroup"
|
||||||
|
snapserverUser = "snapserver"
|
||||||
|
snapserverGroup = "snapserver"
|
||||||
|
snapclientUser = "snapclient"
|
||||||
|
snapclientGroup = "snapclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Cfg = struct {
|
var Cfg = struct {
|
||||||
@ -41,11 +45,11 @@ var Cfg = struct {
|
|||||||
System string
|
System string
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
// BoxService creates a systemd service for schnutibox.
|
// boxService creates a systemd service for schnutibox.
|
||||||
func BoxService(filename string, enable bool) error {
|
func boxService(filename string, enable bool) error {
|
||||||
logger := log.With().Str("stage", "BoxService").Logger()
|
logger := log.With().Str("stage", "BoxService").Logger()
|
||||||
|
|
||||||
if err := CreateUser(); err != nil {
|
if err := createUser(); err != nil {
|
||||||
return fmt.Errorf("could not create user: %w", err)
|
return fmt.Errorf("could not create user: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +87,7 @@ func BoxService(filename string, enable bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NTP() error {
|
func ntp() error {
|
||||||
logger := log.With().Str("stage", "NTP").Logger()
|
logger := log.With().Str("stage", "NTP").Logger()
|
||||||
|
|
||||||
cmd := exec.Command("apt-get", "install", "-y", "ntp", "ntpdate")
|
cmd := exec.Command("apt-get", "install", "-y", "ntp", "ntpdate")
|
||||||
@ -119,9 +123,9 @@ func NTP() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fstab creates a fstab for a read-only system.
|
// fstab creates a fstab for a read-only system.
|
||||||
// nolint:funlen
|
// nolint:funlen
|
||||||
func Fstab(system string) error {
|
func fstab(system string) error {
|
||||||
logger := log.With().Str("stage", "Fstab").Logger()
|
logger := log.With().Str("stage", "Fstab").Logger()
|
||||||
|
|
||||||
// Getting timesync user and group informations.
|
// Getting timesync user and group informations.
|
||||||
@ -163,6 +167,31 @@ func Fstab(system string) error {
|
|||||||
|
|
||||||
logger.Debug().Str("uid", upmpdcliUser.Uid).Str("gid", upmpdcliGroup.Gid).Msg("upmpdcli")
|
logger.Debug().Str("uid", upmpdcliUser.Uid).Str("gid", upmpdcliGroup.Gid).Msg("upmpdcli")
|
||||||
|
|
||||||
|
// Getting snapserver user and group informations.
|
||||||
|
snapserverUser, err := user.Lookup(snapserverUser)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not lookup snapserver user: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
snapserverGroup, err := user.LookupGroup(snapserverGroup)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not lookup snapserver group: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debug().Str("uid", snapserverUser.Uid).Str("gid", snapserverGroup.Gid).Msg("snapserver")
|
||||||
|
|
||||||
|
snapclientUser, err := user.Lookup(snapclientUser)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not lookup snapclient user: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
snapclientGroup, err := user.LookupGroup(snapclientGroup)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not lookup snapclient group: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debug().Str("uid", snapclientUser.Uid).Str("gid", snapclientGroup.Gid).Msg("snapclient")
|
||||||
|
|
||||||
// Chose the right template.
|
// Chose the right template.
|
||||||
// In future it should be a switch statement.
|
// In future it should be a switch statement.
|
||||||
tmpl, err := assets.Assets.ReadFile("templates/fstab.raspbian.tmpl")
|
tmpl, err := assets.Assets.ReadFile("templates/fstab.raspbian.tmpl")
|
||||||
@ -182,12 +211,16 @@ func Fstab(system string) error {
|
|||||||
|
|
||||||
// Create and write.
|
// Create and write.
|
||||||
if err := t.Execute(f, struct {
|
if err := t.Execute(f, struct {
|
||||||
TimesyncUID string
|
TimesyncUID string
|
||||||
TimesyncGID string
|
TimesyncGID string
|
||||||
MopidyUID string
|
MopidyUID string
|
||||||
MopidyGID string
|
MopidyGID string
|
||||||
UpmpdcliUID string
|
UpmpdcliUID string
|
||||||
UpmpdcliGID string
|
UpmpdcliGID string
|
||||||
|
SnapserverUID string
|
||||||
|
SnapserverGID string
|
||||||
|
SnapclientUID string
|
||||||
|
SnapclientGID string
|
||||||
}{
|
}{
|
||||||
timesyncUser.Uid,
|
timesyncUser.Uid,
|
||||||
timesyncGroup.Gid,
|
timesyncGroup.Gid,
|
||||||
@ -195,6 +228,10 @@ func Fstab(system string) error {
|
|||||||
mopidyGroup.Gid,
|
mopidyGroup.Gid,
|
||||||
upmpdcliUser.Uid,
|
upmpdcliUser.Uid,
|
||||||
upmpdcliGroup.Gid,
|
upmpdcliGroup.Gid,
|
||||||
|
snapserverUser.Uid,
|
||||||
|
snapserverGroup.Gid,
|
||||||
|
snapclientUser.Uid,
|
||||||
|
snapclientGroup.Gid,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("could not write templated fstab: %w", err)
|
return fmt.Errorf("could not write templated fstab: %w", err)
|
||||||
}
|
}
|
||||||
@ -202,8 +239,8 @@ func Fstab(system string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemovePkgs removes not needed software in read-only mode.
|
// removePkgs removes not needed software in read-only mode.
|
||||||
func RemovePkgs(system string) error {
|
func removePkgs(system string) error {
|
||||||
logger := log.With().Str("stage", "RemovePkgs").Logger()
|
logger := log.With().Str("stage", "RemovePkgs").Logger()
|
||||||
if system != "raspbian" {
|
if system != "raspbian" {
|
||||||
logger.Info().Msg("nothing to do")
|
logger.Info().Msg("nothing to do")
|
||||||
@ -240,7 +277,7 @@ func RemovePkgs(system string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateUDEVrules() error {
|
func udevRules() error {
|
||||||
logger := log.With().Str("stage", "CreateUDEVrules").Logger()
|
logger := log.With().Str("stage", "CreateUDEVrules").Logger()
|
||||||
logger.Info().Msg("writing udev rule file")
|
logger.Info().Msg("writing udev rule file")
|
||||||
|
|
||||||
@ -271,8 +308,8 @@ func CreateUDEVrules() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates schnutibox system user and group.
|
// createUser creates schnutibox system user and group.
|
||||||
func CreateUser() error {
|
func createUser() error {
|
||||||
logger := log.With().Str("stage", "CreateUser").Logger()
|
logger := log.With().Str("stage", "CreateUser").Logger()
|
||||||
|
|
||||||
cmd := exec.Command("adduser", "--system", "--group", "--no-create-home", schnutiboxUser)
|
cmd := exec.Command("adduser", "--system", "--group", "--no-create-home", schnutiboxUser)
|
||||||
@ -285,8 +322,8 @@ func CreateUser() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateSymlinks creates all needed symlinks.
|
// symlinks creates all needed symlinks.
|
||||||
func CreateSymlinks(system string) error {
|
func symlinks(system string) error {
|
||||||
logger := log.With().Str("stage", "Symlinks").Logger()
|
logger := log.With().Str("stage", "Symlinks").Logger()
|
||||||
|
|
||||||
links := []struct {
|
links := []struct {
|
||||||
@ -365,17 +402,17 @@ func cmdlineTxt() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeReadOnly executes stuff if a read-only system is wanted.
|
// readOnly executes stuff if a read-only system is wanted.
|
||||||
func makeReadOnly(system string) error {
|
func readOnly(system string) error {
|
||||||
if err := RemovePkgs(system); err != nil {
|
if err := removePkgs(system); err != nil {
|
||||||
return fmt.Errorf("could not remove pkgs: %w", err)
|
return fmt.Errorf("could not remove pkgs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CreateSymlinks(system); err != nil {
|
if err := symlinks(system); err != nil {
|
||||||
return fmt.Errorf("could not create symlinks: %w", err)
|
return fmt.Errorf("could not create symlinks: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := Fstab(system); err != nil {
|
if err := fstab(system); err != nil {
|
||||||
return fmt.Errorf("could not create fstab: %w", err)
|
return fmt.Errorf("could not create fstab: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,9 +423,9 @@ func makeReadOnly(system string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mopidy setups mopidy.
|
// mopidy setups mopidy.
|
||||||
//nolint:funlen,cyclop
|
//nolint:funlen,cyclop
|
||||||
func Mopidy() error {
|
func mopidy() error {
|
||||||
logger := log.With().Str("stage", "Mopidy").Logger()
|
logger := log.With().Str("stage", "Mopidy").Logger()
|
||||||
|
|
||||||
// GPG Key.
|
// GPG Key.
|
||||||
@ -501,7 +538,7 @@ func Mopidy() error {
|
|||||||
|
|
||||||
// Upmpdcli setups upmpdcli.
|
// Upmpdcli setups upmpdcli.
|
||||||
//nolint:funlen
|
//nolint:funlen
|
||||||
func Upmpdcli() error {
|
func upmpdcli() error {
|
||||||
logger := log.With().Str("stage", "Upmpdcli").Logger()
|
logger := log.With().Str("stage", "Upmpdcli").Logger()
|
||||||
|
|
||||||
// GPG Key.
|
// GPG Key.
|
||||||
@ -584,8 +621,73 @@ func Upmpdcli() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SchnutiboxConfig() error {
|
// nolint:funlen
|
||||||
logger := log.With().Str("stage", "Upmpdcli").Logger()
|
func snapcast() error {
|
||||||
|
logger := log.With().Str("stage", "snapcast").Logger()
|
||||||
|
|
||||||
|
// Download deb.
|
||||||
|
cmd := exec.Command(
|
||||||
|
"wget",
|
||||||
|
"https://github.com/badaix/snapcast/releases/download/v0.24.0/snapclient_0.24.0-1_without-pulse_armhf.deb",
|
||||||
|
"-O", "/tmp/snapclient.deb",
|
||||||
|
)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
logger.Debug().Str("cmd", cmd.String()).Msg("running")
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("could not download snapclient deb: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install deb
|
||||||
|
cmd = exec.Command(
|
||||||
|
"/bin/sh", "-c",
|
||||||
|
"dpkg -i /tmp/snapclient.deb; apt --fix-broken install -y; rm /tmp/snapclient.deb",
|
||||||
|
)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
logger.Debug().Str("cmd", cmd.String()).Msg("running")
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("could not install snapclient deb: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download deb.
|
||||||
|
cmd = exec.Command(
|
||||||
|
"wget",
|
||||||
|
"https://github.com/badaix/snapcast/releases/download/v0.24.0/snapserver_0.24.0-1_armhf.deb",
|
||||||
|
"-O", "/tmp/snapserver.deb",
|
||||||
|
)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
logger.Debug().Str("cmd", cmd.String()).Msg("running")
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("could not download snapserver deb: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install deb
|
||||||
|
cmd = exec.Command(
|
||||||
|
"/bin/sh", "-c",
|
||||||
|
"dpkg -i /tmp/snapserver.deb; apt --fix-broken install -y; rm /tmp/snapserver.deb",
|
||||||
|
)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
logger.Debug().Str("cmd", cmd.String()).Msg("running")
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("could not install snapserver deb: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func schnutiboxConfig() error {
|
||||||
|
logger := log.With().Str("stage", "schnutiboxConfig").Logger()
|
||||||
logger.Info().Msg("writing schnutibox config")
|
logger.Info().Msg("writing schnutibox config")
|
||||||
|
|
||||||
// Parse template.
|
// Parse template.
|
||||||
@ -615,38 +717,43 @@ func Run(cmd *cobra.Command, args []string) {
|
|||||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||||
|
|
||||||
// Install schnutibox service.
|
// Install schnutibox service.
|
||||||
if err := BoxService(serviceLocation+"/"+serviceFileName, true); err != nil {
|
if err := boxService(serviceLocation+"/"+serviceFileName, true); err != nil {
|
||||||
log.Fatal().Err(err).Msg("could not create schnutibox service")
|
log.Fatal().Err(err).Msg("could not create schnutibox service")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create schnutibox config.
|
// Create schnutibox config.
|
||||||
if err := SchnutiboxConfig(); err != nil {
|
if err := schnutiboxConfig(); err != nil {
|
||||||
log.Fatal().Err(err).Msg("could not create schnutibox config.")
|
log.Fatal().Err(err).Msg("could not create schnutibox config.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install udev file.
|
// Install udev file.
|
||||||
if err := CreateUDEVrules(); err != nil {
|
if err := udevRules(); err != nil {
|
||||||
log.Fatal().Err(err).Msg("could not install udev rules")
|
log.Fatal().Err(err).Msg("could not install udev rules")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup NTP.
|
// Setup NTP.
|
||||||
if err := NTP(); err != nil {
|
if err := ntp(); err != nil {
|
||||||
log.Fatal().Err(err).Msg("could not setup ntp")
|
log.Fatal().Err(err).Msg("could not setup ntp")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup mopidy.
|
// Setup mopidy.
|
||||||
if err := Mopidy(); err != nil {
|
if err := mopidy(); err != nil {
|
||||||
log.Fatal().Err(err).Msg("could not setup mopidy")
|
log.Fatal().Err(err).Msg("could not setup mopidy")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup upmpdcli.
|
// Setup upmpdcli.
|
||||||
if err := Upmpdcli(); err != nil {
|
if err := upmpdcli(); err != nil {
|
||||||
log.Fatal().Err(err).Msg("could not setup upmpdcli")
|
log.Fatal().Err(err).Msg("could not setup upmpdcli")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup snapcast.
|
||||||
|
if err := snapcast(); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("could not setup snapclient")
|
||||||
|
}
|
||||||
|
|
||||||
// Making system read-only.
|
// Making system read-only.
|
||||||
if Cfg.ReadOnly {
|
if Cfg.ReadOnly {
|
||||||
if err := makeReadOnly(Cfg.System); err != nil {
|
if err := readOnly(Cfg.System); err != nil {
|
||||||
log.Fatal().Err(err).Msg("could not make system read-only")
|
log.Fatal().Err(err).Msg("could not make system read-only")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user