Skip to content

Commit

Permalink
Activate stopping and starting of Plex
Browse files Browse the repository at this point in the history
See #6 (comment)
for a write-up of the thinking behind this change. Resolves #5,
resolves #6.
  • Loading branch information
gebn committed Jan 9, 2019
1 parent c3329ba commit e0febd8
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
18 changes: 15 additions & 3 deletions README.md
Expand Up @@ -3,12 +3,22 @@
[![Build Status](https://travis-ci.org/gebn/plexbackup.svg?branch=master)](https://travis-ci.org/gebn/plexbackup)
[![GoDoc](https://godoc.org/github.com/gebn/plexbackup?status.svg)](https://godoc.org/github.com/gebn/plexbackup)

This tool backs up [Plex](https://www.plex.tv)'s server data to S3.
The entire `Plex Media Server` directory (sans `Cache`) is snapshotted, stopping the server beforehand and restarting it after to ensure consistency.
It is `tar`red, `gz`ipped then piped to S3 without writing to disk.
This tool backs up the [`Plex Media Server`](https://www.plex.tv) directory (sans `Cache`) to S3.
It is `tar`red, `gz`ipped and uploaded without writing to disk.
The tool is envisaged to be run as a cron job, preferably soon after the configured maintenance period.
The process is usually CPU-bound on the compression, so [`pigz`](https://zlib.net/pigz/) will be used in place of `gz` if available on the `$PATH`.

## Setup

In order to ensure consistency of the backup, Plex is stopped then started once the process is complete.
This tool effectively runs `sudo systemctl stop|start <unit>` to do this (Polkit was also considered but [ultimately rejected](https://github.com/gebn/plexbackup/issues/6#issuecomment-452899467)).
Assuming a vanilla installation, this can be made to work by allowing the `plex` user to execute the two required commands without having to re-authenticate:

# cat <<EOF > /etc/sudoers.d/10-plex-backup
plex ALL=NOPASSWD: /bin/systemctl stop plexmediaserver.service
plex ALL=NOPASSWD: /bin/systemctl start plexmediaserver.service
EOF

## Usage

$ plexbackup --help
Expand All @@ -21,6 +31,8 @@ The process is usually CPU-bound on the compression, so [`pigz`](https://zlib.ne
--prefix="plex/" Location within the bucket to upload to; a trailing slash is added if not present.
The backup object is stored under this prefix as <RFC3339 date>.tar.xz, e.g.
"2019-01-06T22:38:21Z.tar.xz".
--no-pause Do not stop Plex while the backup is performed. This is not recommended, as it risks
an inconsistent backup.
--service="plexmediaserver.service"
Name of the Plex systemd unit to stop while the backup is performed.
--directory=/var/lib/plexmediaserver/Library/Application Support/Plex Media Server
Expand Down
22 changes: 16 additions & 6 deletions backup/backup.go
Expand Up @@ -17,6 +17,12 @@ import (
// Opts encapsulates parameters for backing up Plex's database.
type Opts struct {

// NoPause takes the backup without stopping Plex. The server will remain
// available throughout, but the backup may be unusable.
// It is specified negatively in order to default to false, which is the
// recommended setting.
NoPause bool

// Service is the name of Plex's systemd unit, e.g. plexmediaserver.service
Service string

Expand Down Expand Up @@ -83,9 +89,11 @@ func (o *Opts) Run(svc *s3.S3) error {
return fmt.Errorf("failed to retrieve oldest backup: %v", err)
}

//if err = exec.Command("systemctl", "stop", plexService).Run(); err != nil {
// return fmt.Errorf("failed to stop plex: %v", err)
//}
if !o.NoPause {
if err = exec.Command("sudo", "systemctl", "stop", o.Service).Run(); err != nil {
return fmt.Errorf("failed to stop plex: %v", err)
}
}

tar := exec.Command(
"tar", "-cf", "-",
Expand Down Expand Up @@ -125,9 +133,11 @@ func (o *Opts) Run(svc *s3.S3) error {
}{gzStdout},
})

//if err = exec.Command("systemctl", "start", plexService).Run(); err != nil {
// return fmt.Errorf("failed to start plex: %v", err)
//}
if !o.NoPause {
if err = exec.Command("sudo", "systemctl", "start", o.Service).Run(); err != nil {
return fmt.Errorf("failed to start plex: %v", err)
}
}

// TODO unclear whether this is necessary; the example uses it
if err = tar.Wait(); err != nil {
Expand Down
3 changes: 3 additions & 0 deletions main.go
Expand Up @@ -23,6 +23,8 @@ var (
Default("plex/").
String()

noPause = kingpin.Flag("no-pause", "Do not stop Plex while the backup is performed. This is not recommended, as it risks an inconsistent backup.").
Bool()
service = kingpin.Flag("service", "Name of the Plex systemd unit to stop while the backup is performed.").
Default("plexmediaserver.service").
String()
Expand All @@ -39,6 +41,7 @@ func main() {
svc := s3.New(sess)

opts := &backup.Opts{
NoPause: !*noPause,
Service: *service,
Directory: *directory,
Bucket: *bucket,
Expand Down

0 comments on commit e0febd8

Please sign in to comment.