mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2024-12-24 22:25:55 -05:00
update docs to recommend new Docker setup
and remove the old scripts, to reduce the supported ways of doing things.
This commit is contained in:
parent
9349a2a164
commit
31801e20c3
@ -20,7 +20,7 @@ console-based (rather than web-based) configuration UI.
|
||||
|
||||
![screenshot](screenshot.png)
|
||||
|
||||
This is version 0.1, the initial release. Until version 1.0, there will be no
|
||||
Moonfire NVR is currently at version 0.6. Until version 1.0, there will be no
|
||||
compatibility guarantees: configuration and storage formats may change from
|
||||
version to version. There is an [upgrade procedure](guide/schema.md) but it is
|
||||
not for the faint of heart.
|
||||
|
243
guide/build.md
Normal file
243
guide/build.md
Normal file
@ -0,0 +1,243 @@
|
||||
# Building Moonfire NVR
|
||||
|
||||
This document has notes for software developers on building Moonfire NVR from
|
||||
source code for development. If you just want to install precompiled
|
||||
binaries, see the [Docker installation instructions](install.md) instead.
|
||||
|
||||
This document doesn't spell out as many details as the installation
|
||||
instructions. Please ask on Moonfire NVR's [issue
|
||||
tracker](https://github.com/scottlamb/moonfire-nvr/issues) or
|
||||
[mailing list](https://groups.google.com/d/forum/moonfire-nvr-users) when
|
||||
stuck. Please also send pull requests to improve this doc.
|
||||
|
||||
## Downloading
|
||||
|
||||
See the [github page](https://github.com/scottlamb/moonfire-nvr) (in case
|
||||
you're not reading this text there already). You can download the
|
||||
bleeding-edge version from the commandline via git:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/scottlamb/moonfire-nvr.git
|
||||
```
|
||||
|
||||
## Docker builds
|
||||
|
||||
This command should prepare a deployment image for your local machine:
|
||||
|
||||
```
|
||||
$ docker buildx build --load --tag=moonfire-nvr -f docker/Dockerfile .
|
||||
```
|
||||
|
||||
If you want to iterate on code changes, doing a full Docker build from
|
||||
scratch every time will be painfully slow. You will likely find it more
|
||||
helpful to use the `dev` target. This is a self-contained developer environment
|
||||
which you can use from its shell via `docker run` or via something like
|
||||
Visual Studio Code's Docker plugin.
|
||||
|
||||
```
|
||||
$ docker buildx build --load --tag=moonfire-dev --target=dev
|
||||
...
|
||||
$ docker run \
|
||||
--rm --interactive=true --tty \
|
||||
--mount=type=bind,source=$(pwd),destination=/var/lib/moonfire-nvr/src \
|
||||
moonfire-dev
|
||||
```
|
||||
|
||||
The development image overrides cargo's output directory to
|
||||
`/var/lib/moonfire-nvr/target`. (See `~moonfire-nvr/.buildrc`.) This avoids
|
||||
using a bind filesystem for build products, which can be slow on macOS. It
|
||||
also means that if you sometimes compile directly on the host and sometimes
|
||||
within Docker, they don't trip over each other's target directories.
|
||||
directories.
|
||||
|
||||
You can also cross-compile to a different architecture. Adding a
|
||||
`--platform=linux/arm64/v8,linux/arm/v7,linux/amd64` argument will compile
|
||||
Moonfire NVR for all supported platforms. For the `dev` target, this prepares
|
||||
a build which executes on your local architecture and is capable of building
|
||||
a binary for your desired target architecture.
|
||||
|
||||
On the author's macOS machine with Docker desktop 3.0.4, building for
|
||||
multiple platforms at once will initially fail with the following error:
|
||||
|
||||
```
|
||||
$ docker buildx build ... --platform=linux/arm64/v8,linux/arm/v7,linux/amd64
|
||||
[+] Building 0.0s (0/0)
|
||||
error: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
|
||||
```
|
||||
|
||||
Running `docker buildx create --use` once solves this problem, with a couple
|
||||
caveats:
|
||||
|
||||
* you'll need to specify an additional `--load` argument to make builds
|
||||
available to run locally.
|
||||
* the `--load` argument only works for one platform at a time. With multiple
|
||||
platforms, it gives an error like the following:
|
||||
```
|
||||
error: failed to solve: rpc error: code = Unknown desc = docker exporter does not currently support exporting manifest lists
|
||||
```
|
||||
[A comment on docker/buildx issue
|
||||
#59](https://github.com/docker/buildx/issues/59#issuecomment-667548900)
|
||||
suggests a workaround of building all three then using caching to quickly
|
||||
load the one of immediate interest:
|
||||
```
|
||||
$ docker buildx build --platform=linux/arm64/v8,linux/arm/v7,linux/amd64 ...
|
||||
$ docker buildx build --load --platform=arm64/v8 ...
|
||||
```
|
||||
|
||||
Major caveat: something appears to be making `docker buildx build` frequently
|
||||
redo builds rather than reusing cached results. The author is very annoyed by
|
||||
this and would welcome help in understanding this problem...
|
||||
|
||||
## Non-Docker setup
|
||||
|
||||
You may prefer building without Docker on the host. Moonfire NVR should run
|
||||
natively on any Unix-like system. It's been tested on Linux and macOS.
|
||||
(In theory [Windows Subsystem for
|
||||
Linux](https://docs.microsoft.com/en-us/windows/wsl/about) should also work.
|
||||
Please speak up if you try it.)
|
||||
|
||||
On macOS systems native builds may be noticeably faster than using Docker's
|
||||
Linux VM and filesystem overlay.
|
||||
|
||||
To build the server, you will need the following C libraries installed:
|
||||
|
||||
* [ffmpeg](http://ffmpeg.org/) version 2.x or 3.x, including `libavutil`,
|
||||
`libavcodec` (to inspect H.264 frames), and `libavformat` (to connect to RTSP
|
||||
servers and write `.mp4` files).
|
||||
|
||||
Note ffmpeg library versions older than 55.1.101, along with all versions of
|
||||
the competing project [libav](http://libav.org), don't support socket
|
||||
timeouts for RTSP. For reliable reconnections on error, it's strongly
|
||||
recommended to use ffmpeg library versions >= 55.1.101.
|
||||
|
||||
* [SQLite3](https://www.sqlite.org/).
|
||||
|
||||
* [`ncursesw`](https://www.gnu.org/software/ncurses/), the UTF-8 version of
|
||||
the `ncurses` library.
|
||||
|
||||
On recent Ubuntu or Raspbian Linux, the following command will install
|
||||
all non-Rust dependencies:
|
||||
|
||||
```
|
||||
$ sudo apt-get install \
|
||||
build-essential \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libncurses5-dev \
|
||||
libncursesw5-dev \
|
||||
libsqlite3-dev \
|
||||
pkgconf \
|
||||
sqlite3 \
|
||||
tzdata
|
||||
```
|
||||
|
||||
On macOS with [Homebrew](https://brew.sh/) and Xcode installed, try the
|
||||
following command:
|
||||
|
||||
```
|
||||
$ brew install ffmpeg yarn
|
||||
```
|
||||
|
||||
Next, you need Rust 1.45+ and Cargo. The easiest way to install them is by
|
||||
following the instructions at [rustup.rs](https://www.rustup.rs/).
|
||||
|
||||
Finally, building the UI requires [yarn](https://yarnpkg.com/en/). (On macOS,
|
||||
the `brew` command above installs it for you. On Linux, follow yarn's guide.)
|
||||
|
||||
Once prerequisites are installed, you can build the server and find it in
|
||||
`target/release/moonfire-nvr`:
|
||||
|
||||
```
|
||||
$ cargo test
|
||||
$ cargo build --release
|
||||
```
|
||||
|
||||
You can build the UI via `yarn` and find it in the `ui-dist` directory:
|
||||
|
||||
```
|
||||
$ yarn
|
||||
$ yarn build
|
||||
```
|
||||
|
||||
### Running interactively straight from the working copy
|
||||
|
||||
The author finds it convenient for local development to set up symlinks so that
|
||||
the binaries in the working copy will run via just `nvr`:
|
||||
|
||||
```
|
||||
$ sudo mkdir /usr/local/moonfire-nvr
|
||||
$ sudo ln -s `pwd`/ui-dist /usr/local/moonfire-nvr/ui
|
||||
$ sudo mkdir /var/lib/moonfire-nvr
|
||||
$ sudo chown $USER:$USER /var/lib/moonfire-nvr
|
||||
$ ln -s `pwd`/target/release/moonfire-nvr $HOME/bin/moonfire-nvr
|
||||
$ ln -s moonfire-nvr $HOME/bin/nvr
|
||||
$ nvr init
|
||||
$ nvr config
|
||||
$ nvr run
|
||||
```
|
||||
|
||||
(Alternatively, you could symlink to `target/debug/moonfire-nvr` and compile
|
||||
with `cargo build` rather than `cargo build --release`, for a faster build
|
||||
cycle and slower performance.)
|
||||
|
||||
Note this `nvr` is a little different than the `nvr` shell script you create
|
||||
when following the [install instructions](install.md). With that shell wrapper,
|
||||
`nvr run` will create and run a detached Docker container with some extra
|
||||
arguments specified in the script. This `nvr run` will directly run from the
|
||||
terminal, with no extra arguments, until you abort with Ctrl-C. Likewise,
|
||||
some of the shell script's subcommands that wrap Docker (`start`, `stop`, and
|
||||
`logs`) have no parallel with this `nvr`.
|
||||
|
||||
## Running as a `systemd` service
|
||||
|
||||
If you want to deploy a non-Docker build on Linux, you may want to use
|
||||
`systemd`. Create `/etc/systemd/system/moonfire-nvr.service`:
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=Moonfire NVR
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/moonfire-nvr run \
|
||||
--db-dir=/var/lib/moonfire-nvr/db \
|
||||
--http-addr=0.0.0.0:8080 \
|
||||
--allow-unauthenticated-permissions='view_video: true'
|
||||
Environment=TZ=:/etc/localtime
|
||||
Environment=MOONFIRE_FORMAT=google-systemd
|
||||
Environment=MOONFIRE_LOG=info
|
||||
Environment=RUST_BACKTRACE=1
|
||||
Type=simple
|
||||
User=moonfire-nvr
|
||||
Nice=-20
|
||||
Restart=on-failure
|
||||
CPUAccounting=true
|
||||
MemoryAccounting=true
|
||||
BlockIOAccounting=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Note that the arguments used here are insecure. You can change that via
|
||||
replacing the `--allow-unauthenticated-permissions` argument here as
|
||||
described in [Securing Moonfire NVR and exposing it to the
|
||||
Internet](secure.md).
|
||||
|
||||
Some handy commands:
|
||||
|
||||
```
|
||||
$ sudo systemctl daemon-reload # reload configuration files
|
||||
$ sudo systemctl start moonfire-nvr # start the service now
|
||||
$ sudo systemctl stop moonfire-nvr # stop the service now (but don't wait for it finish stopping)
|
||||
$ sudo systemctl status moonfire-nvr # show if the service is running and the last few log lines
|
||||
$ sudo systemctl enable moonfire-nvr # start the service on boot
|
||||
$ sudo systemctl disable moonfire-nvr # don't start the service on boot
|
||||
$ sudo journalctl --unit=moonfire-nvr --since='-5 min' --follow # look at recent logs and await more
|
||||
```
|
||||
|
||||
See the [systemd](http://www.freedesktop.org/wiki/Software/systemd/)
|
||||
documentation for more information. The [manual
|
||||
pages](http://www.freedesktop.org/software/systemd/man/) for `systemd.service`
|
||||
and `systemctl` may be of particular interest.
|
@ -1,130 +0,0 @@
|
||||
# Building and installing Moonfire NVR manually
|
||||
|
||||
This guide will walk you through building and installing Moonfire NVR manually.
|
||||
You should have already downloaded the source code as mentioned in
|
||||
[install.md](install.md), and after completing these instructions you should go
|
||||
back to that page to complete configuration.
|
||||
|
||||
## Building from source
|
||||
|
||||
There are no binary packages of Moonfire NVR available yet, so it must be built
|
||||
from source.
|
||||
|
||||
Moonfire NVR is written in the [Rust Programming
|
||||
Language](https://www.rust-lang.org/en-US/). In the long term, I expect this
|
||||
will result in a more secure, full-featured, easy-to-install software.
|
||||
|
||||
You will need the following C libraries installed:
|
||||
|
||||
* [ffmpeg](http://ffmpeg.org/) version 2.x or 3.x, including `libavutil`,
|
||||
`libavcodec` (to inspect H.264 frames), and `libavformat` (to connect to RTSP
|
||||
servers and write `.mp4` files).
|
||||
|
||||
Note ffmpeg library versions older than 55.1.101, along with all versions of
|
||||
the competing project [libav](http://libav.org), don't support socket
|
||||
timeouts for RTSP. For reliable reconnections on error, it's strongly
|
||||
recommended to use ffmpeg library versions >= 55.1.101.
|
||||
|
||||
* [SQLite3](https://www.sqlite.org/).
|
||||
|
||||
* [`ncursesw`](https://www.gnu.org/software/ncurses/), the UTF-8 version of
|
||||
the `ncurses` library.
|
||||
|
||||
On recent Ubuntu or Raspbian, the following command will install
|
||||
all non-Rust dependencies:
|
||||
|
||||
```
|
||||
$ sudo apt-get install \
|
||||
build-essential \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libncurses5-dev \
|
||||
libncursesw5-dev \
|
||||
libsqlite3-dev \
|
||||
pkgconf \
|
||||
sqlite3 \
|
||||
tzdata
|
||||
```
|
||||
|
||||
Next, you need Rust 1.45+ and Cargo. The easiest way to install them is by
|
||||
following the instructions at [rustup.rs](https://www.rustup.rs/).
|
||||
|
||||
Finally, building the UI requires [yarn](https://yarnpkg.com/en/).
|
||||
|
||||
Once prerequisites are installed, Moonfire NVR can be built as follows:
|
||||
|
||||
```
|
||||
$ yarn
|
||||
$ yarn build
|
||||
$ cargo test
|
||||
$ cargo build --release
|
||||
$ sudo install -m 755 target/release/moonfire-nvr /usr/local/bin
|
||||
$ sudo mkdir /usr/local/lib/moonfire-nvr
|
||||
$ sudo cp -R ui-dist /usr/local/lib/moonfire-nvr/ui
|
||||
```
|
||||
|
||||
## Creating the user and database
|
||||
|
||||
You can create Moonfire NVR's dedicated user and SQLite database with the
|
||||
following commands:
|
||||
|
||||
```
|
||||
$ sudo useradd --system --user-group --create-home --home /var/lib/moonfire-nvr moonfire-nvr
|
||||
$ sudo -u moonfire-nvr -H sh -c 'cd && mkdir --mode=700 db'
|
||||
$ sudo -u moonfire-nvr moonfire-nvr init
|
||||
```
|
||||
|
||||
## System Service
|
||||
|
||||
Moonfire NVR can be run as a systemd service. Create
|
||||
`/etc/systemd/system/moonfire-nvr.service`:
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=Moonfire NVR
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/moonfire-nvr run \
|
||||
--db-dir=/var/lib/moonfire-nvr/db \
|
||||
--http-addr=0.0.0.0:8080 \
|
||||
--allow-unauthenticated-permissions='view_video: true'
|
||||
Environment=TZ=:/etc/localtime
|
||||
Environment=MOONFIRE_FORMAT=google-systemd
|
||||
Environment=MOONFIRE_LOG=info
|
||||
Environment=RUST_BACKTRACE=1
|
||||
Type=simple
|
||||
User=moonfire-nvr
|
||||
Nice=-20
|
||||
Restart=on-failure
|
||||
CPUAccounting=true
|
||||
MemoryAccounting=true
|
||||
BlockIOAccounting=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Note that the HTTP port currently has no authentication, encryption, or
|
||||
logging; it should not be directly exposed to the Internet.
|
||||
|
||||
Tell `systemd` to look for the new file:
|
||||
|
||||
```
|
||||
$ sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
See the [systemd](http://www.freedesktop.org/wiki/Software/systemd/)
|
||||
documentation for more information. The [manual
|
||||
pages](http://www.freedesktop.org/software/systemd/man/) for `systemd.service`
|
||||
and `systemctl` may be of particular interest.
|
||||
|
||||
Don't enable or start the service just yet; you'll need to do some more
|
||||
configuration first.
|
||||
|
||||
## Completing installation
|
||||
|
||||
After the steps on this page, go back to [Downloading, installing, and
|
||||
configuring Moonfire NVR](install.md) to set up the sample file directory and
|
||||
configure the system.
|
@ -1,104 +0,0 @@
|
||||
# Building and installing Moonfire NVR using provided scripts
|
||||
|
||||
This guide will walk you through building and installing Moonfire NVR with the
|
||||
provided scripts. You should have already downloaded the source code as
|
||||
mentioned in [install.md](install.md), and after completing these instructions
|
||||
you should go back to that page to complete configuration.
|
||||
|
||||
There are no binary packages of Moonfire NVR available yet, so it must be built
|
||||
from source. This is made easy using a few scripts that will do the job for you
|
||||
unless you have very a different operating system. The scripts are written and
|
||||
tested under ubuntu and raspbian but should not be hard to modify if necessary.
|
||||
|
||||
## Setting everything up
|
||||
|
||||
Start by executing the setup script:
|
||||
|
||||
$ cd moonfire-nvr
|
||||
$ scripts/setup-ubuntu.sh
|
||||
|
||||
If this is the very first time you run this script, a file named `prep.config`
|
||||
will be created and the script will stop. This file is where you will set
|
||||
or change variables that describe the Moonfire installation you want. The
|
||||
initial execution will put default values in this value, but only for the
|
||||
most commonly changed variables. For a full list of variables, see below.
|
||||
|
||||
Once you modify this file (if desired), you run the setup script again. This
|
||||
time it will use the values in the file and proceed with the setup.
|
||||
The script will download and install any pre-requisites. Watch carefully for
|
||||
error messages. It may be you have conflicting installations. If that is the
|
||||
case you must either resolve those first, or go the manual route.
|
||||
|
||||
The script may be given the `-f` option. If you do, you are telling the script
|
||||
that you do not want any existing installation of ffmpeg to be overwritten with
|
||||
a newer one. This could be important to you. If you do use it, and the version
|
||||
you have installed is not compatible with Moonfire, you will be told through
|
||||
a message. If you have no ffmpeg installed, the option is effectively ignored
|
||||
and the necessary version of ffmpeg will be installed.
|
||||
|
||||
The setup script should only need to be run once (after `prep.config` has been
|
||||
created), although if you do a re-install of Moonfire, in particular a much
|
||||
newer version, it is a good idea to run it again as requirements and pre-requisites
|
||||
may have changed. Running the script multiple times should not have any negative effects.
|
||||
|
||||
*Note:* It is quite possible that during the running of the setup script,
|
||||
in particular during the building of libavutil you will see several compiler
|
||||
warnings. This, while undesirable, is a direct result of the original
|
||||
developers not cleaning up the cause(s) of these warnings. They are, however,
|
||||
just warnings and will not affect correct functioning of Moonfire.
|
||||
|
||||
Once the setup is complete, two steps remain: building and then installing.
|
||||
There is a script for each of these scenarios, but since generally you would
|
||||
want to install after a succesul build, the build script automatically invokes
|
||||
the install script, unless specifically told not to.
|
||||
|
||||
## Building
|
||||
|
||||
The build script is involved like this:
|
||||
|
||||
$ scripts/build.sh
|
||||
|
||||
This script will perform all steps necessary to build a complete Moonfire
|
||||
setup. If there are no build errors, this script will then automatically
|
||||
invoke the install script (see below).
|
||||
|
||||
There are two options you may pass to this script. The first is `-B` which
|
||||
means "build only". In other words, this will stop the automatic invocation
|
||||
of the install script. The other option available is `-t` and causes the
|
||||
script to ignore the results of any tests. In other words, even if tests
|
||||
fail, the build phase will be considered successful. This can occasionally
|
||||
be useful if you are doing development, and have temporarily broken one
|
||||
or more test, but want to proceed anyway.
|
||||
|
||||
## Installing
|
||||
|
||||
The install step is performed by the script that can be manually invoked
|
||||
like this:
|
||||
|
||||
$ scripts/install.sh
|
||||
|
||||
This script will copy various files resulting from the build to the correct
|
||||
locations. It will also create a "service configuration" for systemctl that
|
||||
can be used to control Moonfire. This service configuration can be prevented
|
||||
by using the `-s` option to this script. It will also prevent the automatic
|
||||
start of this configuration.
|
||||
|
||||
## Configuration variables
|
||||
|
||||
Although not all listed in the default `prep.config` file, these are the
|
||||
available configuration variable and their defaults.
|
||||
|
||||
NVR_USER=moonfire-nvr
|
||||
NVR_PORT=8080
|
||||
NVR_HOME_BASE=/var/lib
|
||||
DB_NAME=db
|
||||
DB_DIR=$NVR_HOME/$DB_NAME
|
||||
SERVICE_NAME=moonfire-nvr
|
||||
SERVICE_DESC="Moonfire NVR"
|
||||
SERVICE_BIN=/usr/local/bin/$SERVICE_NAME
|
||||
|
||||
## Completing installation
|
||||
|
||||
After the steps on this page, go back to [Downloading, installing, and
|
||||
configuring Moonfire NVR](install.md) to set up the sample file directory and
|
||||
configure the system.
|
160
guide/install.md
160
guide/install.md
@ -1,47 +1,109 @@
|
||||
# Downloading, installing, and configuring Moonfire NVR
|
||||
# Downloading, installing, and configuring Moonfire NVR with Docker
|
||||
|
||||
This document describes how to download, install, and configure Moonfire NVR
|
||||
on a Debian-based Linux system (such as Ubuntu or Raspbian).
|
||||
via the prebuilt Docker images available for x86-64, arm64, and arm. If you
|
||||
instead want to build Moonfire NVR yourself, see the [Build
|
||||
instructions](build.md).
|
||||
|
||||
(In principle, Moonfire NVR supports any POSIX-compliant system, and the main
|
||||
author uses macOS for development, but the documentation and scripts are
|
||||
intended for Linux.)
|
||||
|
||||
## Downloading
|
||||
|
||||
See the [github page](https://github.com/scottlamb/moonfire-nvr) (in case
|
||||
you're not reading this text there already). You can download the
|
||||
bleeding-edge version from the commandline via git:
|
||||
First, install [Docker](https://www.docker.com/) if you haven't already,
|
||||
and verify you can run the container.
|
||||
|
||||
```
|
||||
$ git clone https://github.com/scottlamb/moonfire-nvr.git
|
||||
$ docker run --rm -it scottlamb/moonfire-nvr:latest
|
||||
moonfire-nvr 0.6.0
|
||||
security camera network video recorder
|
||||
|
||||
USAGE:
|
||||
moonfire-nvr <SUBCOMMAND>
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
## Building and installing from source
|
||||
|
||||
There are no binary packages of Moonfire NVR available yet, so it must be built
|
||||
from source. To do so, you can follow either of two paths:
|
||||
|
||||
* Scripted: You will run some shell scripts (after preparing one or two files,
|
||||
and will be completely done. This is by far the easiest option, in
|
||||
particular for first time builders/installers. Read more in [Scripted
|
||||
Installation](install-scripted.md).
|
||||
* Manual: see [instructions](install-manual.md).
|
||||
Next, you'll need to set up your filesystem and the Monfire NVR user.
|
||||
|
||||
Moonfire NVR keeps two kinds of state:
|
||||
|
||||
* a SQLite database, typically <1 GiB. It should be stored on flash if
|
||||
available.
|
||||
* the "sample file directories", which hold the actual samples/frames of
|
||||
H.264 video. These should be quite large and are typically stored on hard
|
||||
drives.
|
||||
* a SQLite database, typically <1 GiB. It should be stored on flash if
|
||||
available. In most cases your root filesystem is on flash, so the
|
||||
default location of `/var/lib/moonfire-nvr/db` will be fine.
|
||||
* the "sample file directories", which hold the actual samples/frames of
|
||||
H.264 video. These should be quite large and are typically stored on hard
|
||||
drives. More below.
|
||||
|
||||
(See [schema.md](schema.md) for more information.)
|
||||
|
||||
By now Moonfire NVR's dedicated user and database should have been created for
|
||||
you. Next you need to create a sample file directory.
|
||||
On most Linux systems, you can create the user as follows:
|
||||
|
||||
## Dedicated hard drive seutp
|
||||
```
|
||||
$ sudo useradd --user-group --create-home --home /var/lib/moonfire-nvr moonfire-nvr
|
||||
```
|
||||
|
||||
and create a script called `nvr` to run Moonfire NVR as the intended host user.
|
||||
This script supports running Moonfire NVR's various administrative commands interactively
|
||||
and managing a long-lived Docker container for its web interface.
|
||||
|
||||
As you set up this script, adjust the `tz` variable as appropriate for your
|
||||
time zone.
|
||||
|
||||
```
|
||||
sudo sh -c 'cat > /usr/local/bin/nvr' <<EOF
|
||||
#!/bin/bash -e
|
||||
|
||||
tz=America/Los_Angeles
|
||||
container_name=moonfire-nvr
|
||||
image_name=scottlamb/moonfire-nvr:latest
|
||||
common_docker_run_args=(
|
||||
--mount=type=bind,source=/etc/localtime,destination=/etc/localtime
|
||||
--mount=type=bind,source=/var/lib/moonfire-nvr,destination=/var/lib/moonfire-nvr
|
||||
--user="$(id -u moonfire-nvr):$(id -g moonfire-nvr)"
|
||||
--env=RUST_BACKTRACE=1
|
||||
--env=TZ=:/etc/localtime
|
||||
)
|
||||
|
||||
case "$1" in
|
||||
run)
|
||||
shift
|
||||
exec docker run \
|
||||
--detach=true \
|
||||
--restart=on-failure \
|
||||
"${common_docker_run_args[@]}" \
|
||||
--publish=8080:8080 \
|
||||
--name="${container_name}" \
|
||||
"${image_name}" \
|
||||
run \
|
||||
--allow-unauthenticated-permissions='view_video: true' \
|
||||
"$@"
|
||||
;;
|
||||
start|stop|logs|rm)
|
||||
exec docker "$@" "${container_name}"
|
||||
;;
|
||||
pull)
|
||||
exec docker pull "${image_name}"
|
||||
;;
|
||||
*)
|
||||
exec docker run \
|
||||
--interactive=true \
|
||||
--tty \
|
||||
--rm \
|
||||
"${common_docker_run_args[@]}" \
|
||||
"${image_name}" \
|
||||
"$@"
|
||||
;;
|
||||
esac
|
||||
EOF
|
||||
sudo chmod a+rx /usr/local/bin/nvr
|
||||
```
|
||||
|
||||
then try it out by initializing the database:
|
||||
|
||||
```
|
||||
$ nvr init
|
||||
```
|
||||
|
||||
This will create a directory `/var/lib/moonfire-nvr/db` with a SQLite3 database
|
||||
within it.
|
||||
|
||||
## Dedicated hard drive setup
|
||||
|
||||
If a dedicated hard drive is available, set up the mount point:
|
||||
|
||||
@ -67,38 +129,32 @@ $ ls -l /dev/disk/by-uuid
|
||||
|
||||
If you use the `nofail` attribute in `/etc/fstab` as described above, your
|
||||
system will boot successfully even when the hard drive is unavailable (such as
|
||||
when your external USB storage is unmounted). This is convenient, but you
|
||||
likely want to ensure the `moonfire-nvr` service only starts when the mounting
|
||||
is successful. Edit the systemd configuration to do so:
|
||||
when your external USB storage is unmounted). This can be helpful when
|
||||
recovering from problems.
|
||||
|
||||
Add a new `--mount` line to your Docker wrapper script `/usr/local/bin/nvr`
|
||||
to expose this new volume to the Docker container, directly below the other
|
||||
mount lines. It will look similar to this:
|
||||
|
||||
```
|
||||
$ sudo vim /etc/systemd/system/moonfire-nvr.service
|
||||
$ sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
You'll want to add a line similar to the following to the `[Unit]` section of
|
||||
the file:
|
||||
|
||||
```
|
||||
RequiresMountsFor=/media/nvr
|
||||
--mount=type=bind,source=/media/nvr/sample,destination=/media/nvr/sample
|
||||
```
|
||||
|
||||
## Completing configuration through the UI
|
||||
|
||||
Once your system is set up, it's time to initialize an empty database,
|
||||
and add the cameras and sample directories to moonfire. You can do this
|
||||
Once your system is set up, it's time to initialize an empty database
|
||||
and add the cameras and sample directories. You can do this
|
||||
by using the `moonfire-nvr` binary's text-based configuration tool.
|
||||
|
||||
```
|
||||
$ sudo -u moonfire-nvr moonfire-nvr init # Initialize empty db
|
||||
$ sudo -u moonfire-nvr moonfire-nvr config 2>debug-log # Configure cameras and storage
|
||||
$ nvr config 2>debug-log
|
||||
```
|
||||
|
||||
In the user interface,
|
||||
|
||||
1. add your sample file dir(s) under "Directories and retention".
|
||||
If you used a dedicated hard drive, use the directory you precreated
|
||||
(`/media/surveillance/sample`). Otherwise, try
|
||||
(eg `/media/nvr/sample`). Otherwise, try
|
||||
`/var/lib/moonfire-nvr/sample`. Moonfire NVR will create the directory as
|
||||
long as it has the required permissions on the parent directory.
|
||||
|
||||
@ -154,14 +210,16 @@ out, particularly if the machine it's running on is behind a home router's
|
||||
firewall. You might not; in that case read through [secure the
|
||||
system](secure.md) first.
|
||||
|
||||
The following commands will start Moonfire NVR and enable it for following
|
||||
boots, respectively:
|
||||
This command will start a detached Docker container for the web interface.
|
||||
It will automatically restart when your system does.
|
||||
|
||||
```
|
||||
$ sudo systemctl start moonfire-nvr
|
||||
$ sudo systemctl enable moonfire-nvr
|
||||
$ nvr run
|
||||
```
|
||||
|
||||
You can temporarily disable the service via `nvr stop` and restart it later via
|
||||
`nvr start`.
|
||||
|
||||
The HTTP interface is accessible on port 8080; if your web browser is running
|
||||
on the same machine, you can access it at
|
||||
[http://localhost:8080/](http://localhost:8080/).
|
||||
|
@ -53,16 +53,10 @@ SQLite database:
|
||||
no longer in the dangerous mode.
|
||||
|
||||
Next ensure Moonfire NVR is not running and does not automatically restart if
|
||||
the system is rebooted during the upgrade. If you are using systemd with the
|
||||
service name `moonfire-nvr`, you can do this as follows:
|
||||
the system is rebooted during the upgrade. If you followed the Docker
|
||||
instructions, you can do this as follows:
|
||||
|
||||
$ sudo systemctl stop moonfire-nvr
|
||||
$ sudo systemctl disable moonfire-nvr
|
||||
|
||||
The service takes a moment to shut down; wait until the following command
|
||||
reports that it is not running:
|
||||
|
||||
$ sudo systemctl status moonfire-nvr
|
||||
$ nvr stop
|
||||
|
||||
Then back up your SQLite database. If you are using the default path, you can
|
||||
do so as follows:
|
||||
@ -83,27 +77,34 @@ manual for write-ahead logging](https://www.sqlite.org/wal.html):
|
||||
> 3.11.0 (2016-02-15), WAL mode works as efficiently with large transactions
|
||||
> as does rollback mode.
|
||||
|
||||
Run the upgrade procedure using the new software binary (here referred to as
|
||||
`new-moonfire-nvr`; if you are installing from source, you may find it as
|
||||
`target/release/moonfire-nvr`).
|
||||
Run the upgrade procedure using the new software binary.
|
||||
|
||||
$ sudo -u moonfire-nvr new-moonfire-nvr upgrade
|
||||
```
|
||||
$ nvr pull # updates the docker image to the latest binary
|
||||
$ nvr upgrade # runs the upgrade
|
||||
```
|
||||
|
||||
Then run the system in read-only mode to verify correct operation:
|
||||
You can run the system in read-only mode, although you'll find this only
|
||||
works in the "insecure" setup. (Authorization requires writing the database.)
|
||||
|
||||
$ sudo -u moonfire-nvr new-moonfire-nvr run --read-only
|
||||
```
|
||||
$ nvr rm
|
||||
$ nvr run --read-only
|
||||
```
|
||||
|
||||
Go to the web interface and ensure the system is operating correctly. If
|
||||
you detect a problem now, you can copy the old database back over the new one.
|
||||
If you detect a problem after enabling read-write operation, a restore will be
|
||||
you detect a problem now, you can copy the old database back over the new one
|
||||
and edit your `nvr` script to use the corresponding older Docker image. If
|
||||
you detect a problem after enabling read-write operation, a restore will be
|
||||
more complicated.
|
||||
|
||||
Then install the new software to the path expected by your systemd
|
||||
configuration and start it up:
|
||||
Once you're satisfied, restart the system in read-write mode:
|
||||
|
||||
$ sudo install -m 755 new-moonfire-nvr /usr/local/bin/moonfire-nvr
|
||||
$ sudo systemctl enable moonfire-nvr
|
||||
$ sudo systemctl start moonfire-nvr
|
||||
```
|
||||
$ nvr stop
|
||||
$ nvr rm
|
||||
$ nvr run
|
||||
```
|
||||
|
||||
Hopefully your system is functioning correctly. If not, there are two options
|
||||
for restore; neither are easy:
|
||||
@ -120,9 +121,7 @@ for restore; neither are easy:
|
||||
* undo the changes by hand. There's no documentation on this; you'll need
|
||||
to read the code and come up with a reverse transformation.
|
||||
|
||||
Once you're confident of correct operation, delete the unneeded backup:
|
||||
|
||||
$ sudo systemctl rm /var/lib/moonfire-nvr/db/db.pre-upgrade
|
||||
The `nvr check` command will show you what problems exist on your system.
|
||||
|
||||
### Unversioned to version 0
|
||||
|
||||
|
@ -149,16 +149,20 @@ your browser. See [How to secure Nginx with Let's Encrypt on Ubuntu
|
||||
|
||||
## 6. Reconfigure Moonfire NVR
|
||||
|
||||
In your `/etc/systemd/system/moonfire-nvr.service` file, look for these lines:
|
||||
If you follow the recommended Docker setup, your `/usr/local/bin/nvr` script
|
||||
will contain this line:
|
||||
|
||||
```
|
||||
ExecStart=/usr/local/bin/moonfire-nvr run \
|
||||
--db-dir=/var/lib/moonfire-nvr/db \
|
||||
--http-addr=0.0.0.0:8080 \
|
||||
--allow-unauthenticated-permissions='view_video: true'
|
||||
--allow-unauthenticated-permissions='view_video: true'
|
||||
```
|
||||
|
||||
Replace the last line with `--trust-forward-hdrs`. This change has two effects:
|
||||
Replace it with the following:
|
||||
|
||||
```
|
||||
--trust-forward-hdrs
|
||||
```
|
||||
|
||||
This change has two effects:
|
||||
|
||||
* No `--allow-unauthenticated-permissions` means that web users must
|
||||
authenticate.
|
||||
@ -167,15 +171,17 @@ Replace the last line with `--trust-forward-hdrs`. This change has two effects:
|
||||
in the next section.
|
||||
|
||||
If the webserver is running on the same machine as Moonfire NVR, you might
|
||||
also change `0.0.0.0:8080` to `127.0.0.1:8080`, which prevents other machines
|
||||
on the network from impersonating the proxy, effectively allowing them to lie
|
||||
about the client's IP and protocol.
|
||||
also change `--publish=8080:8080` to `--publish=127.0.0.1:8080:8080`, which
|
||||
prevents other machines on the network from impersonating the proxy,
|
||||
effectively allowing them to lie about the client's IP and protocol.
|
||||
|
||||
Run these commands to make the configuration take effect:
|
||||
To make this take effect, you'll need to stop the running Docker container,
|
||||
delete it, and create/run a new one:
|
||||
|
||||
```
|
||||
$ sudo systemctl daemon-reload
|
||||
$ sudo systemctl restart moonfire-nvr
|
||||
$ nvr stop
|
||||
$ nvr rm
|
||||
$ nvr run
|
||||
```
|
||||
|
||||
## 7. Configure the webserver
|
||||
|
@ -4,9 +4,12 @@
|
||||
|
||||
While Moonfire NVR is running, logs will be written to stderr.
|
||||
|
||||
* When running `moonfire-nvr config`, you typically should redirect stderr
|
||||
* When running the configuration UI, you typically should redirect stderr
|
||||
to a text file to avoid poor interaction between the interactive stdout
|
||||
output and the logging.
|
||||
output and the logging. If you use the recommended
|
||||
`nvr config 2>debug-log` command, output will be in the `debug-log` file.
|
||||
* When running detached through Docker, Docker saves the logs for you.
|
||||
Try `nvr logs` or `docker logs moonfire-nvr`.
|
||||
* When running through systemd, stderr will be redirected to the journal.
|
||||
Try `sudo journalctl --unit moonfire-nvr` to view the logs. You also
|
||||
likely want to set `MOONFIRE_FORMAT=google-systemd` to format logs as
|
||||
@ -25,6 +28,8 @@ Logging options are controlled by environmental variables:
|
||||
[glog](https://github.com/google/glog) package) and `google-systemd` (a
|
||||
variation for better systemd compatibility).
|
||||
|
||||
If you use Docker, set these via Docker's `--env` argument.
|
||||
|
||||
## Problems
|
||||
|
||||
### `Error: pts not monotonically increasing; got 26615520 then 26539470`
|
||||
@ -39,11 +44,5 @@ to disable B frames in the meantime.
|
||||
### `moonfire-nvr config` displays garbage
|
||||
|
||||
This happens if your machine is configured to a non-UTF-8 locale, due to
|
||||
gyscos/Cursive#13. As a workaround, type `export LC_ALL=en_US.UTF-8` prior to
|
||||
running `moonfire-nvr config`.
|
||||
|
||||
### Logging in is very very slow
|
||||
|
||||
Ensure you're using a build compiled with the `--release` flag. See
|
||||
[libpasta/libpasta#9](https://github.com/libpasta/libpasta/issues/9) for more
|
||||
background.
|
||||
gyscos/Cursive#13. As a workaround, try setting the environment variable
|
||||
`LC_ALL=C.UTF-8`. This should automatically be set with the Docker container.
|
||||
|
111
scripts/build.sh
111
scripts/build.sh
@ -1,111 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016-17 The Moonfire NVR Authors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the
|
||||
# OpenSSL library under certain conditions as described in each
|
||||
# individual source file, and distribute linked combinations including
|
||||
# the two.
|
||||
#
|
||||
# You must obey the GNU General Public License in all respects for all
|
||||
# of the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the
|
||||
# file(s), but you are not obligated to do so. If you do not wish to do
|
||||
# so, delete this exception statement from your version. If you delete
|
||||
# this exception statement from all source files in the program, then
|
||||
# also delete it here.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
. `dirname ${BASH_SOURCE[0]}`/script-functions.sh
|
||||
|
||||
initEnvironmentVars
|
||||
|
||||
# Process command line options
|
||||
#
|
||||
while getopts ":Bt" opt; do
|
||||
case $opt in
|
||||
B) BUILD_ONLY=1
|
||||
;;
|
||||
t) IGNORE_TESTS=1
|
||||
;;
|
||||
:)
|
||||
echo_fatal -x "Option -$OPTARG requires an argument."
|
||||
;;
|
||||
\?)
|
||||
echo_fatal "Invalid option: -$OPTARG"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Setup cargo if files are present
|
||||
#
|
||||
initCargo
|
||||
|
||||
# Check environment
|
||||
#
|
||||
|
||||
rv=$(getVersion rustc 0.0)
|
||||
if ! versionAtLeast "$rv" "$RUSTC_MIN_VERSION"; then
|
||||
echo_fatal -x "rustc not present or version less than $RUSTC_MIN_VERSION"
|
||||
fi
|
||||
|
||||
cv=$(getVersion cargo 0.0)
|
||||
if ! versionAtLeast "$cv" "$CARGO_MIN_VERSION"; then
|
||||
echo_fatal -x "cargo not present or version less than $CARGO_MIN_VERSION"
|
||||
fi
|
||||
|
||||
yv=$(getVersion yarn 0.0)
|
||||
if ! versionAtLeast "$yv" "$YARN_MIN_VERSION"; then
|
||||
echo_fatal -x "yarn not present or version less than $YARN_MIN_VERSION"
|
||||
fi
|
||||
|
||||
# Building main server component
|
||||
#
|
||||
if [ "${FORCE_CLEAN:-0}" -eq 1 ]; then
|
||||
echo_info -x "Forcing clean server build..."
|
||||
cargo clean
|
||||
fi
|
||||
|
||||
echo_info -x "Building test version..."
|
||||
if ! cargo test; then
|
||||
echo_error -x "test failed." "Try to run the following manually for more info" \
|
||||
"RUST_TEST_THREADS=1 cargo test --verbose" ''
|
||||
if [ "${IGNORE_TESTS:-0}" -ne 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if ! cargo build --release; then
|
||||
echo_error -x "Server/release build failed." "Try to run the following manually for more info" \
|
||||
"cargo build --release --verbose" ''
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Building UI components
|
||||
#
|
||||
echo_info -x "Building UI components..."
|
||||
if ! yarn build; then
|
||||
echo_fatal -x "UI build failed." "yarn build"
|
||||
fi
|
||||
|
||||
# Stop if build only is desired
|
||||
#
|
||||
if [ "${BUILD_ONLY:-0}" != 0 ]; then
|
||||
echo_info -x "Build (only) complete, exiting"
|
||||
exit 0
|
||||
fi
|
||||
. `dirname ${BASH_SOURCE[0]}`/install.sh
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
rm -fr node_modules
|
@ -1,126 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016-17 The Moonfire NVR Authors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the
|
||||
# OpenSSL library under certain conditions as described in each
|
||||
# individual source file, and distribute linked combinations including
|
||||
# the two.
|
||||
#
|
||||
# You must obey the GNU General Public License in all respects for all
|
||||
# of the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the
|
||||
# file(s), but you are not obligated to do so. If you do not wish to do
|
||||
# so, delete this exception statement from your version. If you delete
|
||||
# this exception statement from all source files in the program, then
|
||||
# also delete it here.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
. `dirname ${BASH_SOURCE[0]}`/script-functions.sh
|
||||
|
||||
# Determine directory path of this script
|
||||
#
|
||||
initEnvironmentVars
|
||||
|
||||
# Process command line options
|
||||
#
|
||||
while getopts ":s" opt; do
|
||||
case $opt in
|
||||
s) NO_SERVICE=1
|
||||
;;
|
||||
:)
|
||||
echo_fatal "Option -$OPTARG requires an argument."
|
||||
;;
|
||||
\?)
|
||||
echo_fatal "Invalid option: -$OPTARG"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
sudo_warn
|
||||
|
||||
sudo install -m 755 target/release/moonfire-nvr ${SERVICE_BIN}
|
||||
if [ -x "${SERVICE_BIN}" ]; then
|
||||
echo_info -x "Server Binary installed..."
|
||||
else
|
||||
echo_info -x "Server build failed to install..."
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "${LIB_DIR}" ]; then
|
||||
sudo mkdir "${LIB_DIR}"
|
||||
fi
|
||||
if [ -d "ui-dist" ]; then
|
||||
sudo mkdir -p "${LIB_DIR}/ui"
|
||||
sudo cp -R ui-dist/. "${LIB_DIR}/ui/"
|
||||
echo_info -x "Server UI installed..."
|
||||
else
|
||||
echo_fatal -x "Server UI failed to build or install..."
|
||||
fi
|
||||
|
||||
if [ "${NO_SERVICE:-0}" != 0 ]; then
|
||||
echo_info -x "Not configuring systemctl service. Done"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Make sure user was created
|
||||
#
|
||||
if ! userExists "${NVR_USER}"; then
|
||||
echo_fatal -x "NVR_USER=${NVR_USER} was not created. Do so manually or run the setup script."
|
||||
fi
|
||||
|
||||
pre_install_prep
|
||||
|
||||
|
||||
# Prepare service files for socket when using priviliged port
|
||||
#
|
||||
SOCKET_SERVICE_PATH="/etc/systemd/system/${SERVICE_NAME}.socket"
|
||||
if [ $NVR_PORT -lt 1024 ]; then
|
||||
echo_fatal -x "NVR_PORT ($NVR_PORT) < 1024: priviliged ports not supported"
|
||||
fi
|
||||
|
||||
# Prepare service files for moonfire
|
||||
#
|
||||
SERVICE_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
|
||||
sudo sh -c "cat > ${SERVICE_PATH}" <<NVR_EOF
|
||||
[Unit]
|
||||
Description=${SERVICE_DESC}
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=${SERVICE_BIN} run \\
|
||||
--db-dir=${DB_DIR} \\
|
||||
--ui-dir=${LIB_DIR}/ui \\
|
||||
--http-addr=0.0.0.0:${NVR_PORT} \\
|
||||
--allow-unauthenticated-permissions='view_video: true'
|
||||
Environment=TZ=:/etc/localtime
|
||||
Environment=MOONFIRE_FORMAT=google-systemd
|
||||
Environment=MOONFIRE_LOG=info
|
||||
Environment=RUST_BACKTRACE=1
|
||||
Type=simple
|
||||
User=${NVR_USER}
|
||||
Nice=-20
|
||||
Restart=on-failure
|
||||
CPUAccounting=true
|
||||
MemoryAccounting=true
|
||||
BlockIOAccounting=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
NVR_EOF
|
||||
|
||||
sudo systemctl daemon-reload
|
@ -1,263 +0,0 @@
|
||||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016-2017 The Moonfire NVR Authors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the
|
||||
# OpenSSL library under certain conditions as described in each
|
||||
# individual source file, and distribute linked combinations including
|
||||
# the two.
|
||||
#
|
||||
# You must obey the GNU General Public License in all respects for all
|
||||
# of the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the
|
||||
# file(s), but you are not obligated to do so. If you do not wish to do
|
||||
# so, delete this exception statement from your version. If you delete
|
||||
# this exception statement from all source files in the program, then
|
||||
# also delete it here.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
if [ -z "$BASH_VERSION" ]; then
|
||||
echo "Script must run using bash (/bin/bash), not dash (/bin/sh)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Useful constants
|
||||
#
|
||||
NODE_MIN_VERSION="10"
|
||||
YARN_MIN_VERSION="1.0"
|
||||
CARGO_MIN_VERSION="0.2"
|
||||
RUSTC_MIN_VERSION="1.45"
|
||||
|
||||
normalizeDirPath()
|
||||
{
|
||||
echo "$( cd -P "$1" && pwd )"
|
||||
}
|
||||
|
||||
resolvePath()
|
||||
{
|
||||
local d="$1"
|
||||
while [ -h "$d" ]; do # resolve $d until file no longer a symlink
|
||||
DIR="$( cd -P "$( dirname "$d" )" && pwd )"
|
||||
d="$(readlink "$d")"
|
||||
# if $d was rel symlink, resolve relative to path of symlink
|
||||
[[ "$d" != /* ]] && ="$DIR/$d"
|
||||
done
|
||||
echo "$d"
|
||||
}
|
||||
|
||||
functionsInit()
|
||||
{
|
||||
local p="$(resolvePath "${BASH_SOURCE[0]}")"
|
||||
MOONFIRE_DIR="$(normalizeDirPath "`dirname "${p}"`/..")"
|
||||
}
|
||||
|
||||
read_lines()
|
||||
{
|
||||
LINES_READ=()
|
||||
while read -r line; do
|
||||
LINES_READ+=("$line")
|
||||
done
|
||||
}
|
||||
|
||||
catPrefix()
|
||||
{
|
||||
sed -e "s/^/$2/" < "$1"
|
||||
}
|
||||
|
||||
echo_multi()
|
||||
{
|
||||
local prefix=''
|
||||
local plus=''
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
# Define a prefix for each line
|
||||
-p) shift; prefix="$1"; shift ;;
|
||||
# Provide extra empty line at end
|
||||
-x) shift; plus=1 ;;
|
||||
# Insert contents of LINES_READ here
|
||||
# Only works as leading option
|
||||
-L) shift; set -- "${LINES_READ[@]}" "$@" ;;
|
||||
# Stop processing options
|
||||
-) shift; break ;;
|
||||
# Non option break out
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
local A=("$@")
|
||||
for l in "${A[@]/#/$prefix}"; do
|
||||
echo "$l"
|
||||
done
|
||||
[ -n "$plus" ] && echo
|
||||
}
|
||||
|
||||
echo_stderr()
|
||||
{
|
||||
echo_multi "$@" 1>&2
|
||||
}
|
||||
|
||||
echo_info()
|
||||
{
|
||||
echo_multi -x -p '>>> ' "$@"
|
||||
}
|
||||
|
||||
|
||||
echo_warn()
|
||||
{
|
||||
echo_multi -p 'WARNING: ' "$@" 1>&2
|
||||
}
|
||||
|
||||
echo_error()
|
||||
{
|
||||
echo_multi -p 'ERROR: ' "$@" 1>&2
|
||||
}
|
||||
|
||||
echo_fatal()
|
||||
{
|
||||
echo_error "$@"
|
||||
exit 1;
|
||||
}
|
||||
|
||||
|
||||
# Read possible user config and then compute all derived environment
|
||||
# variables used by the script(s).
|
||||
#
|
||||
initEnvironmentVars()
|
||||
{
|
||||
test -z "${MOONFIRE_DIR}" && functionsInit
|
||||
if [ -r "${MOONFIRE_DIR}/prep.config" ]; then
|
||||
. "${MOONFIRE_DIR}/prep.config"
|
||||
fi
|
||||
NVR_USER="${NVR_USER:-moonfire-nvr}"
|
||||
NVR_PORT="${NVR_PORT:-8080}"
|
||||
NVR_HOME_BASE="${NVR_HOME_BASE:-/var/lib}"
|
||||
NVR_HOME="${NVR_HOME_BASE}/${NVR_USER}"
|
||||
DB_NAME="${DB_NAME:-db}"
|
||||
DB_DIR="${DB_DIR:-$NVR_HOME/${DB_NAME}}"
|
||||
SERVICE_NAME="${SERVICE_NAME:-moonfire-nvr}"
|
||||
SERVICE_DESC="${SERVICE_DESC:-Moonfire NVR}"
|
||||
SERVICE_BIN="${SERVICE_BIN:-/usr/local/bin/moonfire-nvr}"
|
||||
LIB_DIR="${UI_DIR:-/usr/local/lib/moonfire-nvr}"
|
||||
}
|
||||
|
||||
# Create file with confguration variables that are user changeable.
|
||||
# Not all variables are included here, only the likely ones to be
|
||||
# modified.
|
||||
# If the file already exists, it will not be modified
|
||||
#
|
||||
makePrepConfig()
|
||||
{
|
||||
test -z "${MOONFIRE_DIR}" && functionsInit
|
||||
if [ ! -f "${MOONFIRE_DIR}/prep.config" ]; then
|
||||
cat >"${MOONFIRE_DIR}/prep.config" <<-EOF_CONFIG
|
||||
NVR_USER=$NVR_USER
|
||||
NVR_PORT=$NVR_PORT
|
||||
SERVICE_NAME=$SERVICE_NAME
|
||||
SERVICE_DESC="$SERVICE_DESC"
|
||||
EOF_CONFIG
|
||||
echo_info -x "File prep.config newly created. Inspect and change as necessary." \
|
||||
"When done, re-run this setup script. Currently it contains:"
|
||||
catPrefix "${MOONFIRE_DIR}/prep.config" " "
|
||||
echo_info -x
|
||||
exit 0
|
||||
else
|
||||
echo_info -x "Setting up with variables:"
|
||||
catPrefix "${MOONFIRE_DIR}/prep.config" " "
|
||||
echo_info -x
|
||||
fi
|
||||
}
|
||||
|
||||
# Extract version data from stdin, possibly grepping first against
|
||||
# single argument.
|
||||
#
|
||||
extractVersion()
|
||||
{
|
||||
local pattern="$1"
|
||||
|
||||
if [ -n "${pattern}" ]; then
|
||||
grep "$pattern" | sed -e 's/[^0-9.]*\([0-9. ]*\).*/\1/' | tr -d ' '
|
||||
else
|
||||
sed -e 's/[^0-9.]*\([0-9. ]*\).*/\1/' | tr -d ' '
|
||||
fi
|
||||
}
|
||||
|
||||
getAVersion()
|
||||
{
|
||||
local v=`$1 $2 2>/dev/null | extractVersion`
|
||||
if [ "X${v}" = "X" ]; then echo "$3"; else echo "${v}"; fi
|
||||
}
|
||||
|
||||
getVersion()
|
||||
{
|
||||
getAVersion $1 --version $2
|
||||
}
|
||||
|
||||
getClassicVersion()
|
||||
{
|
||||
getAVersion $1 -version $2
|
||||
}
|
||||
|
||||
versionAtLeast()
|
||||
{
|
||||
v1=(${1//./ } 0 0 0); v1=("${v1[@]:0:3}")
|
||||
v2=(${2//./ } 0 0 0); v2=("${v2[@]:0:3}")
|
||||
|
||||
for i in 0 1 2; do
|
||||
if [ "${v1[$i]}" -gt "${v2[$i]}" ]; then return 0; fi
|
||||
if [ "${v1[$i]}" -lt "${v2[$i]}" ]; then return 1; fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
initCargo()
|
||||
{
|
||||
if [ -r ~/.cargo/env ]; then
|
||||
source ~/.cargo/env
|
||||
fi
|
||||
}
|
||||
|
||||
userExists()
|
||||
{
|
||||
return $(id -u "$1" >/dev/null 2>&1)
|
||||
}
|
||||
|
||||
sudo_warn()
|
||||
{
|
||||
echo_warn -x -p '!!!!! ' \
|
||||
'------------------------------------------------------------------------------' \
|
||||
'During this script you may be asked to input your root password' \
|
||||
'This is for the purpose of using the sudo command and is necessary to complete' \
|
||||
'the script successfully.' \
|
||||
'------------------------------------------------------------------------------'
|
||||
}
|
||||
|
||||
# Create user, group, and database directory if not there
|
||||
#
|
||||
prep_moonfire_user()
|
||||
{
|
||||
echo_info -x "Create user/group and directories we need..."
|
||||
if ! userExists "${NVR_USER}"; then
|
||||
sudo useradd --system ${NVR_USER} --user-group --create-home --home-dir "${NVR_HOME}"
|
||||
fi
|
||||
sudo -u ${NVR_USER} -H sh -c 'cd && test -d db || mkdir --mode=700 db'
|
||||
}
|
||||
|
||||
pre_install_prep()
|
||||
{
|
||||
prep_moonfire_user
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016-2017 The Moonfire NVR Authors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the
|
||||
# OpenSSL library under certain conditions as described in each
|
||||
# individual source file, and distribute linked combinations including
|
||||
# the two.
|
||||
#
|
||||
# You must obey the GNU General Public License in all respects for all
|
||||
# of the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the
|
||||
# file(s), but you are not obligated to do so. If you do not wish to do
|
||||
# so, delete this exception statement from your version. If you delete
|
||||
# this exception statement from all source files in the program, then
|
||||
# also delete it here.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
. `dirname ${BASH_SOURCE[0]}`/script-functions.sh
|
||||
|
||||
initEnvironmentVars
|
||||
makePrepConfig
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
|
||||
sudo_warn
|
||||
|
||||
# Setup all apt packages we need
|
||||
#
|
||||
echo_info -x 'Preparing and downloading packages we need...'
|
||||
PKGS="build-essential \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libncurses-dev \
|
||||
libncursesw-dev \
|
||||
libsqlite3-dev \
|
||||
pkgconf \
|
||||
sqlite3 \
|
||||
tzdata"
|
||||
|
||||
# Add yarn before NodeSource so it can all go in one update
|
||||
#
|
||||
yv=$(getVersion yarn "NA")
|
||||
if [ ${yv} = "NA" ]; then
|
||||
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg |\
|
||||
sudo apt-key add -
|
||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" |\
|
||||
sudo tee /etc/apt/sources.list.d/yarn.list
|
||||
PKGS="$PKGS yarn"
|
||||
fi
|
||||
|
||||
# Check for minimum node version
|
||||
#
|
||||
nv=$(getVersion node 0)
|
||||
if ! versionAtLeast "$nv" "$NODE_MIN_VERSION"; then
|
||||
# Nodesource will also make sure we have apt-transport-https
|
||||
# and will run apt-get-update when done
|
||||
#
|
||||
curl -sL https://deb.nodesource.com/setup_${NODE_MIN_VERSION}.x |
|
||||
sudo -E bash -
|
||||
PKGS="$PKGS nodejs"
|
||||
DO_UPDATE=0
|
||||
else
|
||||
PKGS="$PKGS apt-transport-https"
|
||||
fi
|
||||
|
||||
# Run apt-get update if still necessary
|
||||
#
|
||||
if [ ${DO_UPDATE:-1} ]; then sudo apt-get update -y; fi
|
||||
|
||||
# Install necessary packages
|
||||
#
|
||||
sudo apt-get install -y $PKGS
|
||||
sudo apt-get autoremove -y
|
||||
echo_info -x
|
||||
|
||||
# If cargo appears installed, initialize for using it so rustc can be found
|
||||
#
|
||||
initCargo
|
||||
|
||||
# Make sure we have rust and cargo
|
||||
rv=$(getVersion rustc 0.0)
|
||||
if ! versionAtLeast "$rv" "$RUSTC_MIN_VERSION"; then
|
||||
echo_info -x "Installing latest rust and cargo..."
|
||||
curl https://sh.rustup.rs -sSf | sh -s - -y
|
||||
initCargo
|
||||
fi
|
||||
|
||||
cv=$(getVersion cargo "NA")
|
||||
if [ ${cv} = "NA" ]; then
|
||||
echo_fatal -x "Cargo is not (properly) installed, but rust is." \
|
||||
"Suggest you install the latest rustup, or manually install cargo."
|
||||
"Install using: curl https://sh.rustup.rs -sSf | sh -s -y"
|
||||
fi
|
||||
|
||||
# Now make sure we have dev environment and tools for the UI portion
|
||||
#
|
||||
echo_info -x "Installing all dependencies with yarn..."
|
||||
yarn install
|
||||
echo_info -x
|
||||
|
||||
finish()
|
||||
{
|
||||
if [ -z "${OLDDIR}" ]; then
|
||||
cd "${OLDDIR}"
|
||||
fi
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
# Rest of prep
|
||||
#
|
||||
pre_install_prep
|
||||
|
||||
|
||||
read_lines <<-'INSTRUCTIONS'
|
||||
Unless there are errors above, everything you need should have been installed
|
||||
and you are now ready to build, install, and then use moonfire.
|
||||
|
||||
Build by executing the script: scripts/build.sh
|
||||
Install by executing the script: scripts/install.sh (run automatically by build
|
||||
step).
|
||||
INSTRUCTIONS
|
||||
echo_info -x -p ' ' -L
|
||||
|
Loading…
Reference in New Issue
Block a user